      1 ﻿
      2 /**
      3  * @name	CeL function for native objects
      4  * @fileoverview
      5  * 本檔案包含了 native objects 的 functions。
      6  * @since
      7  */
      8
      9
     10 if (typeof CeL === 'function'){
     11
     12 /**
     13  * 本 module 之 name(id)，<span style="text-decoration:line-through;">不設定時會從呼叫時之 path 取得</span>。
     14  * @type	String
     15  * @constant
     16  * @inner
     17  * @ignore
     18  */
     19 var module_name = 'native';
     20
     21 //===================================================
     22 /**
     23  * 若欲 include 整個 module 時，需囊括之 code。
     24  * @type	Function
     25  * @param	{Function} library_namespace	namespace of library
     26  * @param	load_arguments	呼叫時之 argument(s)
     27  * @return
     28  * @name	CeL.native
     29  * @constant
     30  * @inner
     31  * @ignore
     32  */
     33 var code_for_including = function(library_namespace, load_arguments) {
     34
     35 //	requires 必須放在 '_' 後！
     36 	if (eval(library_namespace.use_function(
     37 			'data.split_String_to_Object')))
     38 		return;
     39
     40
     41 /**
     42  * null module constructor
     43  * @class	native objects 的 functions
     44  */
     45 CeL.native
     46 = function() {
     47 	//	null module constructor
     48 };
     49
     50
     51 /**
     52  * for JSDT: 有 prototype 才會將之當作 Class
     53  */
     54 CeL.native
     55 .prototype = {
     56 };
     57
     58
     59
     60
     61
     62
     63 /*	opposite of toUTCString()
     64 	尚不成熟！假如是type=='date'，不如用new Date()!
     65 	string大部分可用new Date(Date.parse(str))代替!
     66 	http://www.comsharp.com/GetKnowledge/zh-CN/TeamBlogTimothyPage_K742.aspx
     67
     68 var UTCDay,UTCMonth;
     69 setObjValue('UTCDay','Sun,Mon,Tue,Wed,Thu,Fri,Sat',1);
     70 setObjValue('UTCMonth','Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec',1);
     71 var fromUTCStringFormat=[[0,3,2,1,4],[0,5,1,2,3],[0,4,1,2,3]];	//	0:[Mon, 9 Aug 2004 12:05:00 GMT],1:[Thu Sep 30 18:12:08 UTC+0800 2004],2:[Sat Jun 26 18:19:46 2004]
     72 function fromUTCString(str,format){
     73  var s=''+str,f;
     74  if(!s)return;
     75  if(typeof format=='undefined')if(f=Date.parse(s))return new Date(f);else return 'Unknown format!';//format=0;
     76  if(!isNaN(format)&&format<fromUTCStringFormat.length)f=fromUTCStringFormat[format];
     77  else return 'Yet support this kind of format['+format+']!\nWe support to '+fromUTCStringFormat.length+'.';
     78  if(!f[0])f[0]=' ';
     79  s=s.replace(new RegExp(f[0]+'+','g'),f[0]).split(f[0]);
     80  if(s.length<f.length)return 'The item length of data: '+s.length+' is less then format['+format+']: '+f.length+'!\n'+s.join(',');// new Date
     81  if(f.length==5)s[f[4]]=s[f[4]].split(':');
     82  else if(f.length==7)s[f[4]]=[s[f[4]],s[f[5]],s[f[6]]];
     83  else return 'Illegal date format!';
     84  if(format==1&&s[4].match(/([+-]\d{2})/))s[f[4]][0]=parseInt(s[f[3]][0])+parseInt(RegExp.$1);
     85  alert(str+'\n'+s[f[1]]+','+s[f[2]]+'('+UTCMonth[s[f[2]]]+'),'+s[f[3]]+','+s[f[4]][0]+','+s[f[4]][1]+','+s[f[4]][2]);
     86  //	check,可以包括星期
     87  if( !(s[f[2]]=UTCMonth[s[f[2]]]) || !(s=new Date(s[f[1]],s[f[2]],s[f[3]],s[f[4]][0],s[f[4]][1],s[f[4]][2])) )	//	Date.UTC()
     88   s='Input data error!';
     89  return s;
     90 }
     91 */
     92
     93 /*	string <-> date object, Date.parse()
     94 	http://msdn2.microsoft.com/zh-tw/library/t5580e8h(VS.80).aspx
     95
     96
     97 /((\d{1,4})[\/.-])?([01]?\d)([\/.-]([0-3]?\d))?/
     98 /([0-2]?\d):([0-5]?\d)(:([0-5]?\d))?\s*(([PA])M)?/
     99
    100
    101 (
    102
    103
    104 (
    105
    106
    107 (
    108 ([12]\d{3}|1?\d{2})
    109
    110 [\/.-]
    111 )?
    112
    113 ([01]?\d)
    114
    115 ([\/.-]([0-3]?\d)(\.\d+)?)?
    116
    117
    118 |
    119
    120
    121 ([0-2]?\d)
    122 :
    123 ([0-5]?\d)
    124
    125 (:([0-5]?\d))?
    126
    127 \s*
    128 (([PA])M)?
    129
    130
    131 )
    132
    133
    134
    135 \s*
    136 ){1,2}
    137
    138
    139 try:
    140 '2003/1/4  12:53:5'.toDate();
    141 String_to_Date.m.join('<br/>');
    142 	$2:year
    143 	$3:month
    144 	$5:mday
    145
    146
    147 */
    148 String_to_Date.pd=/(([12]\d{3}|1\d{2}|[2-9]\d)[\/.\-–年])?([01]?\d)([\/.\-–月]([0-3]?\d)日?)?/;	//	pattern of date
    149 String_to_Date.pt=/([0-2]?\d)[:時]([0-5]?\d)([:分]([0-5]?\d)(\.\d+)?)?\s*(([PA])M)?/i;	//	pattern of time
    150 String_to_Date.r1=new RegExp(String_to_Date.pd.source+'(\\s+'+String_to_Date.pt.source+')?','i');	//	date [time]
    151 String_to_Date.r2=new RegExp(String_to_Date.pt.source+'(\\s+'+String_to_Date.pd.source+')?','i');	//	time [date]
    152 //String_to_Date.m;	//	matched string
    153 function String_to_Date(s,f,diff){	//	date string, force parse(no Date.parse() try), 時差 in hour(例如 TW: UTC+8 → 8, 可使用.5)
    154  if(!s)s=this.valueOf();//.toString();
    155  var m,a,b,c;
    156  if(!f&&!diff&&(m=Date.parse(s)))return new Date(m);	//	有diff時不使用 Date.parse
    157
    158  if(m=s.match(/(^|[^\d])([12]\d{3})([^\/.\-–年]|$)/))s=m[2]+'/1';	//	僅有年時的bug
    159
    160  f=1911;	//	小於此年份會加上此年份。for 民國
    161  if(diff)diff=(new Date).getTimezoneOffset()+parseInt(60*diff);
    162  if(!diff)diff=0;
    163  if(m=s.match(String_to_Date.r1))
    164   //	日期先
    165   //for(var i=1;i<11;i++)m[i]=m[i]?Math.floor(m[i]):0;	//	needless
    166   a=new Date((b=m[2]-0)&&b<200?b+f:b,m[3]?m[3]-1:0,m[5]||1,	m[12]=='P'||m[13]=='p'?m[7]-0+12:m[7],m[8]-diff,m[10],m[11]*1e3);
    167
    168  if((!m||!isNaN(m[0]))&&(c=s.match(String_to_Date.r2)))	//	不match或僅有一數字
    169   //	時間先
    170   m=c,a=new Date((b=m[10]-0)&&b<200?b+f:b,m[11]?m[11]-1:0,m[13]||1,	m[7]=='P'||m[7]=='p'?m[1]-0+12:m[1],m[2]-diff,m[4],m[5]*1e3);
    171
    172  //var t="match:\n"+s+"\n\n";for(var i=0;i<m.length;i++){t+=(i>9?i:' '+i)+': '+m[i]+'\n';}if(!m[1]||!m[2]||!m[4])alert(t);
    173
    174  if (String_to_Date.m = m) {
    175   //	判別未輸入時預設年份設對了沒：以最接近 now 的為基準
    176   if (!b && a - new Date(0, 0, 2) > 0) {
    177 					m = new Date(a);
    178 					a.setFullYear(s = (b = new Date).getFullYear());
    179 					m.setFullYear(a - b > 0 ? s - 1 : s + 1);
    180 					if (a - b > 0 && a - b > b - m || a - b < 0
    181 							&& a - b < b - m)
    182 						a = m;
    183 				}
    184   return a;
    185  }
    186 }
    187
    188 //	Turn to RFC 822 date-time
    189 //DateToRFC822[generateCode.dLK]='setTool,String_to_Date';
    190 function DateToRFC822(d) {
    191 	if (!(d instanceof Date))
    192 		d = ('' + d).toDate();
    193 	if (!d)
    194 		d = new Date;
    195 	return d.toGMTString().replace(/UTC/gi, 'GMT');
    196 };
    197
    198 //	要用更多樣化的，請使用format_date()
    199 function Date_to_String(sp) {
    200 	if (!sp)
    201 		sp = '/';
    202 	with (this)
    203 		return '' + getYear() + sp + (getMonth() + 1) + sp + getDate() + ' '
    204 				+ getHours() + ':' + getMinutes()
    205 		// +':'+.getSeconds()+'.'+getMilliseconds();
    206 		;
    207 };
    208 //var tt='2001/8/7 03:35PM';alert(tt+'\n'+tt.toDate().toStr());
    209
    210
    211 /*
    212 mode:
    213 	+4:不顯示時間,
    214 	+3:顯示時間至時,
    215 	+2:顯示時間至分,
    216 	+1:顯示時間至秒,
    217 	+0:顯示時間至毫秒(ms)
    218
    219 	+32(4<<3):不顯示日期,
    220 	+24(3<<3):顯示日期mm/dd,
    221 	+16(2<<3):顯示日期yyyy/mm,
    222 	+8(1<<3):顯示日期yyyy/mm/dd(星期),
    223 	+0:顯示日期yyyy/mm/dd
    224
    225 	+64(1<<6):input UTC
    226 	+128(2<<6):output UTC
    227
    228 NOTE:
    229 在現有時制下要轉換其他時區之時間成正確time:
    230 d=_其他時區之時間_;
    231 diff=其他時區之時差(例如 TW: UTC+8)
    232 d.setTime(d.getTime()-60000*((new Date).getTimezoneOffset()+diff*60))
    233
    234 */
    235
    236 CeL.native
    237 .
    238 /**
    239  * 顯示格式化日期 string
    240  * @param date_value	要轉換的 date, 值過小時當作時間, <0 轉成當下時間
    241  * @param {Number} mode	要轉換的 mode
    242  * @param {Boolean} zero_fill	對 0-9 是否補零
    243  * @param {String} date_separator	date separator
    244  * @param {String} time_separator	time separator
    245  * @return	{String}	格式化後的日期
    246  * @example
    247  * alert(format_date());
    248  * @since	2003/10/18 1:04 修正
    249  * @since	2010/4/16 10:37:30	重構(refactoring)
    250  * @requires setTool,to_fixed
    251  * @see
    252  * http://www.merlyn.demon.co.uk/js-dates.htm,
    253  * http://aa.usno.navy.mil/data/docs/JulianDate.html
    254  * @memberOf	CeL.native
    255  */
    256 format_date = function format_date(date_value, mode, zero_fill, date_separator, time_separator) {
    257 	//library_namespace.debug('[' + (typeof date_value) + '] ' + date_value + ', mode: ' + mode);
    258
    259 	// initiate
    260 	if (!mode)
    261 		mode = 0;
    262
    263 	var output_UTC, a, b = mode, time_mode, return_string = '',
    264 	show_number = zero_fill ? function(n) {
    265 		return n > 9 ? n : '0' + n;
    266 	} : function(n) {
    267 		return n;
    268 	};
    269
    270 	//	date & time mode
    271 	mode %= 64;
    272 	//	UTC mode
    273 	b = (b - mode) / 64;
    274 	//	input UTC
    275 	a = b % 2 == 1 ? 1 : 0;
    276 	output_UTC = b - a === 1;
    277
    278 	time_mode = mode % 8;
    279 	//	date mode
    280 	mode = (mode - time_mode) / 8;
    281 	// time_mode > 4 && mode > 3: error mode: 沒啥好顯示的了
    282
    283 	//	處理各種不同的 date
    284 	b = typeof date_value;
    285 	if (b === 'number' && date_value >= 0){
    286 		// 全球標準時間(UCT)與本地時間之差距
    287 		// UTC time = local time + format_date.UTC_offset(ms)
    288 		if (!a && isNaN(a = format_date.UTC_offset))
    289 			//	input UTC 時之差距(ms)
    290 			//	.getTimezoneOffset() is in minute. 60*1000(ms)=6e4(ms)
    291 			a = format_date.UTC_offset = 6e4 * (new Date).getTimezoneOffset();
    292
    293 		// 值過小時當作時間: d<90000000~24*60*60*1000，判別為當天，只顯示時間。不允許 d<0！
    294 		date_value = new Date(Math.abs(a += date_value) < 9e7 ? a : date_value);
    295 		mode = 32;
    296 	}else if (b === 'string' && (a = date_value.toDate()))
    297 		date_value = a;
    298 	else if (b === 'date')
    299 		// 應對在 Excel 等外部程式會出現的東西
    300 		date_value = new Date(date_value);
    301 	else if (
    302 			//	http://www.interq.or.jp/student/exeal/dss/ejs/1/1.html
    303 			//	引数がオブジェクトを要求してくる場合は instanceof 演算子を使用します
    304 			//	typeof date_value!=='object'||date_value.constructor!=Date
    305 			!(date_value instanceof Date))
    306 		//	new Date === new Date()
    307 		date_value = new Date;
    308
    309
    310 	// 處理 date
    311 	if (mode < 4) {
    312 		return_string = show_number((output_UTC ? date_value.getUTCMonth()
    313 				: date_value.getMonth()) + 1);
    314 		if (!date_separator)
    315 			date_separator = '/';
    316 		if (mode < 3)
    317 			return_string = (output_UTC ? date_value.getUTCFullYear() : date_value
    318 					.getFullYear())
    319 					+ date_separator + return_string;
    320 		if (mode !== 2) {
    321 			return_string += date_separator
    322 			+ show_number(output_UTC ? date_value.getUTCDate() : date_value
    323 					.getDate());
    324 			if (mode === 1)
    325 				return_string += '(' + (output_UTC ? date_value.getUTCDay()
    326 						: date_value.getDay()) + ')';
    327 		}
    328 	}
    329
    330 	// 處理 time
    331 	if (time_mode < 4) {
    332 		if (mode < 4)
    333 			// 日期 & 時間中間分隔
    334 			return_string += ' ';
    335 		if (!time_separator)
    336 			time_separator = ':';
    337 		return_string += show_number(output_UTC ? date_value.getUTCHours()
    338 				: date_value.getHours());
    339 		if (time_mode < 3) {
    340 			return_string += time_separator
    341 			+ show_number(output_UTC ? date_value.getUTCMinutes()
    342 					: date_value.getMinutes());
    343 			if (time_mode < 2)
    344 				return_string += time_separator
    345 				+ (time_mode ? show_number(output_UTC ? date_value
    346 						.getUTCSeconds() : date_value.getSeconds())
    347 						: (output_UTC ? date_value.getUTCSeconds()
    348 								+ date_value.getUTCMilliseconds() / 1e3
    349 								: date_value.getSeconds() + date_value.getMilliseconds() / 1e3
    350 							).to_fixed(3));
    351 		}
    352 	}
    353
    354 	return return_string;
    355 };
    356
    357
    358
    359 /*
    360 	function經ScriptEngine會轉成/取用'function'開始到'}'為止的字串
    361
    362 	用[var thisFuncName=parse_function().funcName]可得本身之函數名
    363 	if(_detect_)alert('double run '+parse_function().funcName+'() by '+parse_function(arguments.callee.caller).funcName+'()!');
    364
    365 You may use this.constructor
    366
    367
    368 TODO:
    369 to call: parse_function(this,arguments)
    370 e.g., parent_func.child_func=function(){var name=parse_function(this,arguments);}
    371
    372 bug:
    373 函數定義 .toString() 時無法使用。
    374 */
    375 CeL.native
    376 .
    377 /**
    378  * 函數的文字解譯/取得函數的語法
    379  * @param {Function|String} function_name	function name or function structure
    380  * @param flag	=1: reduce
    381  * @return
    382  * @example
    383  * parsed_data = new parse_function(function_name);
    384  * @see
    385  * http://www.interq.or.jp/student/exeal/dss/ref/jscript/object/function.html,
    386  * Syntax error: http://msdn.microsoft.com/library/en-us/script56/html/js56jserrsyntaxerror.asp
    387  * @memberOf	CeL.native
    388  * @since	2010/5/16 23:04:54
    389  */
    390 parse_function = function parse_function(function_name, flag) {
    391 	if (!function_name
    392 			&& typeof (function_name = parse_function.caller) !== 'function')
    393 		return;
    394 	if (typeof function_name === 'string'
    395 			&& !(function_name = library_namespace.get_various(function_name)))
    396 		return;
    397
    398 	var fs = '' + function_name, m = fs.match(/^function[\s\n]+(\w*)[\s\n]*\(([\w,\s\n]*)\)[\s\n]*\{[\s\n]*((.|\n)*)[\s\n]*\}[\s\n]*$/);
    399 	//library_namespace.debug(typeof function_name + '\n' + fs + '\n' + m);
    400
    401 	// detect error, 包含引數
    402 	// 原先：functionRegExp=/^\s*function\s+(\w+) ..
    403 	// 因為有function(~){~}這種的，所以改變。
    404 	if (!m)
    405 		// JScript5 不能用throw!
    406 		// http://www.oldversion.com/Internet-Explorer.html
    407 		throw new Error(1002, 'Syntax error (語法錯誤)');
    408
    409 	if (function_name != m[1])
    410 		library_namespace.warn('Function name unmatch (函數名稱不相符，可能是用了reference？)');
    411
    412 	//library_namespace.debug('function ' + m[1] + '(' + m[2] + '){\n' + m[3] + '\n}');
    413
    414 	return {
    415 		string : fs,
    416 		name : m[1],
    417 		// 去除前後空白
    418 		arguments : m[2].replace(/[\s\n]+/g, '').split(','),
    419 		code : m[3]
    420 	};
    421 };
    422
    423
    424
    425
    426 //	補強String.fromCharCode()
    427 function fromCharCode(c) {
    428 	if (!isNaN(c))
    429 		return String.fromCharCode(c);
    430 	try {
    431 		// 直接最快
    432 		return eval('String.fromCharCode(' + c + ');');
    433 	} catch (e) {
    434 	}
    435
    436 /*
    437 if (typeof c == 'string')
    438 	return eval('String.fromCharCode(' + n + ')');// c=c.split(','); 後者可以通過審查
    439 if (typeof c == 'object') {
    440 	var t = '', d, i, a, n = [];
    441 	if (c.length)
    442 		a = c;
    443 	else {
    444 		a = [];
    445 		for (i in c)
    446 			a.push(c[i]);
    447 	}
    448 	for (i = 0; i < a.length; i++)
    449 		if (!isNaN(c = a[i]) || !isNaN(c = ('' + a[i]).charCodeAt(0)))
    450 			n.push(c); // 跳過無法判讀的值
    451 	return eval('String.fromCharCode(' + n + ')');//n.join(',')	這樣較快
    452 }
    453 */
    454 };
    455
    456
    457
    458
    459
    460 CeL.native
    461 .
    462 /**
    463  * 對付有時 charCodeAt 會傳回 >256 的數值。
    464  * 若確定編碼是 ASCII (char code 是 0~255) 即可使用此函數替代 charCodeAt。
    465  * @param text	string
    466  * @param position	at what position
    467  * @return
    468  * @since	2008/8/2 10:10:49
    469  * @see
    470  * http://www.alanwood.net/demos/charsetdiffs.html
    471  * @memberOf	CeL.native
    472  */
    473 toASCIIcode=function (text, position) {
    474 	var _f = arguments.callee, c;
    475
    476 	if (!_f.t) {
    477 		// initial
    478 		var i = 129, t = _f.t = [], l = {
    479 			8364 : 128,
    480 			8218 : 130,
    481 			402 : 131,
    482 			8222 : 132,
    483 			8230 : 133,
    484 			8224 : 134,
    485 			8225 : 135,
    486 			710 : 136,
    487 			8240 : 137,
    488 			352 : 138,
    489 			8249 : 139,
    490 			338 : 140,
    491 			381 : 142,
    492 			8216 : 145,
    493 			8217 : 146,
    494 			8220 : 147,
    495 			8221 : 148,
    496 			8226 : 149,
    497 			8211 : 150,
    498 			8212 : 151,
    499 			732 : 152,
    500 			8482 : 153,
    501 			353 : 154,
    502 			8250 : 155,
    503 			339 : 156,
    504 			382 : 158,
    505 			376 : 159
    506 		};
    507 		for (; i < 256; i += 2)
    508 			t[i] = i;
    509 		for (i in l)
    510 			// sl(i+' = '+l[i]),
    511 			t[Math.floor(i)] = l[i];
    512 	}
    513
    514 	if (position < 0 && !isNaN(text))
    515 		c = text;
    516 	else
    517 		c = text.charCodeAt(position || 0);
    518
    519 	return c < 128 ? c : _f.t[c] || c;
    520 };
    521
    522
    523 /*	2008/8/2 9:9:16
    524 	encodeURI, encodeURIComponent 僅能編成 utf-8，對於其他 local 編碼可使用本函數。
    525
    526 e.g.,
    527 f.src='http://www.map.com.tw/search_engine/searchBar.asp?search_class=address&SearchWord='+encodeUC(q[0],'big5')
    528
    529
    530
    531
    532 perl
    533 #use Encode qw(from_to);
    534 use Encode;
    535
    536 my $tEnc='utf-8';
    537
    538 $t="金";
    539
    540 $t=Encode::decode($t,'big5');
    541
    542 Encode::from_to($t,$lEnc,$outEnc);
    543
    544 Encode::from_to
    545
    546 @b=split(//,$a);
    547
    548 for($i=0;$i<scalar(@b);$i++){
    549  $r.=sprintf('%%%X',ord($b[$i]));
    550 };
    551
    552
    553 */
    554 //encodeUC[generateCode.dLK]='toASCIIcode';
    555 function encodeUC(u,enc){
    556  if(!enc||enc=='utf8')return encodeURI(u);
    557
    558  with(new ActiveXObject("ADODB.Stream"))
    559   Type=2,//adTypeText;
    560   Charset=enc,
    561   Open(),
    562   WriteText(u),
    563   Position=0,
    564   Charset='iso-8859-1',
    565   u=ReadText(),
    566   Close();
    567
    568  var i=0,c,r=[];
    569  for(;i<u.length;i++)
    570   r.push((c=u.charCodeAt(i))<128?u.charAt(i):'%'+toASCIIcode(c,-1).toString(16).toUpperCase());
    571
    572  return r.join('').replace(/ /g,'+');
    573 }
    574
    575
    576
    577
    578 CeL.native
    579 .
    580 /**
    581  * String pattern (e.g., "/a+/g") to RegExp pattern.
    582  * qq// in perl.
    583  * String.prototype.toRegExp = function(f) { return to_RegExp_pattern(this.valueOf(), f); };
    584  * @param {String} pattern	pattern text
    585  * @param {Boolean|String} [RegExp_flag]	flags when need to return RegExp object
    586  * @param {RegExp} [escape_pattern]	char pattern need to escape
    587  * @return	{RegExp} RegExp object
    588  */
    589 to_RegExp_pattern = function(pattern, RegExp_flag, escape_pattern) {
    590 	var r = pattern
    591 		// 不能用 $0
    592 		.replace(escape_pattern || /([.+*?|()\[\]\\{}])/g, '\\$1')
    593 		// 這種方法不完全，例如 /\s+$|^\s+/g
    594 		.replace(/^([\^])/, '\\^').replace(/([$])$/, '\\$');
    595 	return RegExp_flag ? new RegExp(r, /^[igms]+$/i.test(RegExp_flag) ? RegExp_flag : '') : r;
    596 };
    597
    598
    599
    600 CeL.native
    601 .
    602 /**
    603  * 重新設定 RegExp object 之 flag
    604  * @param {RegExp} regexp	RegExp object to set
    605  * @param {String} flag	flag of RegExp
    606  * @return	{RegExp}
    607  * @example
    608  * 附帶 'g' flag 的 RegExp 對相同字串作 .test() 時，第二次並不會重設。因此像下面的 expression 兩次並不會得到相同結果。
    609  * var r=/,/g,t='a,b';
    610  * WScript.Echo(r.test(t)+','+r.test(t));
    611  *
    612  * //	改成這樣就可以了：
    613  * var r=/,/g,t='a,b',s=renew_RegExp_flag(r,'-g');
    614  * WScript.Echo(s.test(t)+','+s.test(t));
    615  *
    616  * //	這倒沒問題：
    617  * r=/,/g,a='a,b';
    618  * if(r.test(a))alert(a.replace(r,'_'));
    619  *
    620  * //	delete r.lastIndex; 無效，得用 r.lastIndex=0; 因此下面的亦可：
    621  * if(r.global)r.lastIndex=0;
    622  * if(r.test(a)){~}
    623  *
    624  * @see
    625  * http://msdn.microsoft.com/zh-tw/library/x9h97e00(VS.80).aspx,
    626  * 如果規則運算式已經設定了全域旗標，test 將會從 lastIndex 值表示的位置開始搜尋字串。如果未設定全域旗標，則 test 會略過 lastIndex 值，並從字串之首開始搜尋。
    627  * http://www.aptana.com/reference/html/api/RegExp.html
    628  * @memberOf	CeL.native
    629  */
    630 renew_RegExp_flag = function(regexp, flag) {
    631 	var i, flag_set = {
    632 		global : 'g',
    633 		ignoreCase : 'i',
    634 		multiline : 'm'
    635 	};
    636
    637 	// 未指定 flag: get flag
    638 	if (!flag) {
    639 		flag = '';
    640 		for (i in flag_set)
    641 			if (regexp[i])
    642 				flag += flag_set[i];
    643 		return flag;
    644 	}
    645
    646 	var a = flag.charAt(0), F = '', m;
    647 	a = a === '+' ? 1 : a === '-' ? 0 : (F = 1);
    648
    649 	if (F)
    650 		// 無 [+-]
    651 		F = flag;
    652 	else
    653 		// f: [+-]~ 的情況，parse flag
    654 		for (i in flag_set)
    655 			if ((m = flag.indexOf(flag_set[i], 1) != -1) && a || !m
    656 					&& regexp[i])
    657 				F += flag_set[i];
    658
    659 	// for JScript<=5
    660 	try{
    661 		return new RegExp(regexp.source, F);
    662 	}catch (e) {
    663 		// TODO: handle exception
    664 	}
    665 };
    666
    667
    668 /*	2004/5/27 16:08
    669 	將 MS-DOS 萬用字元(wildcard characters)轉成 RegExp, 回傳 pattern
    670 	for search
    671
    672 usage:
    673 	p=new RegExp(turnWildcardToRegExp('*.*'))
    674
    675
    676 flag&1	有變化的時候才 return RegExp
    677 flag&2	add ^$
    678
    679
    680 萬用字元經常用在檔名的置換。
    681 * 代表任意檔案名稱
    682 如：ls * 表示列出所有檔案名稱。
    683 ? 則代表一個字元
    684 如: ls index.??? 表示列出所有 index.三個字元 的檔案名稱
    685 [ ] 代表選擇其中一個字元
    686 [Ab] 則代表 A 或 b 二者之中的一個字元
    687 如: ls [Ab]same 為 Asame 或 bsame
    688 [! ] 代表除外的一個字元
    689 [!Ab] 則代表 不是 A 且 不是 b 的一個字元
    690 如: [!0-9] 表不是數字字元
    691 如: *[!E] 表末尾不是 E 的檔名
    692
    693 memo:
    694 檔案名稱不可包含字元	** 不包含目錄分隔字元 [\\/]:
    695 /:*?"<>|/
    696
    697 */
    698
    699 //	萬用字元 RegExp source, ReadOnly
    700 turnWildcardToRegExp.w_chars = '*?\\[\\]';
    701
    702 function turnWildcardToRegExp(p, f) { // pattern, flag
    703
    704 	if (p instanceof RegExp)
    705 		return p;
    706 	if (!p || typeof p != 'string')
    707 		return;
    708
    709 	var ic = arguments.callee.w_chars, r;
    710 	if ((f & 1) && !new RegExp('[' + ic + ']').test(p))
    711 		return p;
    712
    713 	ic = '[^' + ic + ']';
    714 	r = p
    715 		//	old: 考慮 \
    716 		//.replace(/(\\*)(\*+|\?+|\.)/g,function($0,$1,$2){var c=$2.charAt(0);return $1.length%2?$0:$1+(c=='*'?ic+'*':c=='?'?ic+'{'+$2.length+'}':'\\'+$2);})
    717
    718 		//	處理目錄分隔字元：多轉一，'/' → '\\' 或相反
    719 		.replace(/[\\\/]+/g, typeof dirSp === 'string' ? dirSp : '\\')
    720
    721 		//	在 RegExp 中有作用，但非萬用字元，在檔名中無特殊作用的
    722 		.replace(/([().^$\-])/g, '\\$1')
    723
    724 		//	* 代表任意檔案字元
    725 		.replace(/\*+/g, '\0*')
    726
    727 		//	? 代表一個檔案字元
    728 		.replace(/\?+/g, function($0) {
    729 			return '\0{' + $0.length + '}';
    730 		})
    731
    732 		//	translate wildcard characters
    733 		.replace(/\0+/g, ic)
    734
    735 		//	[ ] 代表選擇其中一個字元
    736 		//pass
    737
    738 		//	[! ] 代表除外的一個字元
    739 		.replace(/\[!([^\]]*)\]/g, '[^$1]')
    740 		;
    741
    742
    743 	// 有變化的時候才 return RegExp
    744 	if (!(f & 1) || p !== r)
    745 		try {
    746 			p = new RegExp(f & 2 ? '^' + r + '$' : r, 'i');
    747 		} catch (e) {
    748 			//	輸入了不正確的 RegExp：未預期的次數符號等
    749 		}
    750
    751 	return p;
    752 }
    753
    754
    755
    756
    757 //	string & Number處理	-----------------------------------------------
    758
    759 //	set prototype's function of 內建物件 for 相容性(not good way..)
    760 //setTool[generateCode.dLK]='*setTool();';//,product,countS,to_fixed,getText,turnUnicode,trimStr,String_to_Date,Date_to_String,JSalert
    761 function setTool(){
    762  if(!String.prototype.x&&typeof product==='function')String.prototype.x=product;
    763  if(!String.prototype.count&&typeof countS==='function')String.prototype.count=countS;
    764  if(!Number.prototype.to_fixed&&typeof to_fixed==='function')Number.prototype.to_fixed=to_fixed;
    765  if(!String.prototype.gText&&typeof getText==='function')String.prototype.gText=getText;
    766  if(!String.prototype.turnU&&typeof turnUnicode==='function')String.prototype.turnU=turnUnicode;
    767  if(!String.prototype.trim&&typeof trimStr==='function')String.prototype.trim=trimStr;
    768  //if(!Array.prototype.unique&&typeof Aunique==='function')Array.prototype.unique=Aunique;	//	建議不用，因為在for(in Array)時會..
    769
    770  if(!String.prototype.toDate&&typeof String_to_Date==='function')String.prototype.toDate=String_to_Date;
    771  if(!Date.prototype.toStr&&typeof Date_to_String==='function')Date.prototype.toStr=Date_to_String;
    772  if(typeof alert=='undefined'&&typeof JSalert==='function')alert=JSalert;	//	在HTML中typeof alert=='object'
    773 }
    774
    775 function Aunique(){return uniqueArray(this);}
    776 function uniqueArray(a,f){	//	array,sortFunction
    777  if(f)a.sort(f);else a.sort();
    778  var i=1,j=-1;
    779  for(;i<a.length;i++)
    780   if(a[i]==a[i-1]){if(j<0)j=i;}
    781   else if(j>=0)a.splice(j,i-j),i=j,j=-1;
    782  if(j>=0)a.splice(j,i-j);
    783  return a;
    784 }
    785
    786 function product(c) {
    787 	if (isNaN(c) || (c = Math.floor(c)) < 1)
    788 		return '';
    789 	var i, r = '', s = [];
    790 	s[i = 1] = this;
    791 	while (i + i <= c)
    792 		s[i + i] = s[i] + s[i], i += i;
    793 	while (c) {
    794 		if (i <= c)
    795 			r += s[i], c -= i;
    796 		i /= 2;
    797 	}
    798 	return r;//in VB:String(c,this)
    799 }
    800 //	計算string中出現k之次數	用s///亦可@perl
    801 function countS(k) { // k亦可用RegExp
    802 	//var c=0,s=this,i=0,l;if(k&&typeof k=='string'){l=k.length;while((i=this.indexOf(k,i))!=-1)c++,i+=l;}return c;
    803 	return (this.length - this.replace(k, '').length) / k.length;
    804 }
    805
    806
    807 CeL.native
    808 .
    809 /**
    810  * 取至小數 d 位，
    811  * 肇因： JScript即使在做加減運算時，有時還是會出現 1.4000000000000001、0.0999999999999998 等數值。此函數可取至 1.4 與 0.1。
    812  * c.f., round()
    813  * @param {Number} digits	1,2,..: number of decimal places shown
    814  * @param {Number} [max]	max digits	max===0:round() else floor()
    815  * @return
    816  * @see
    817  * https://bugzilla.mozilla.org/show_bug.cgi?id=5856
    818  * IEEE754の丸め演算は最も報告されるES3「バグ」である。
    819  * http://www.jibbering.com/faq/#FAQ4_6
    820  * http://en.wikipedia.org/wiki/Rounding
    821  * @example
    822  * {var d=new Date,v=0.09999998,i=0,a;for(;i<100000;i++)a=v.to_fixed(2);alert(v+'\n→'+a+'\ntime:'+format_date(new Date-d));}
    823  * @memberOf	CeL.native
    824  */
    825 to_fixed = function(digits, max) {
    826 	var v = this.valueOf(),
    827 	i, n;
    828
    829 	if (isNaN(v))
    830 		return v;
    831
    832 	if (isNaN(digits) || digits < 0)
    833 		// 內定：8位
    834 		digits = 8;
    835 	else if (digits > 20)
    836 		digits = 20;
    837
    838 	if (!max && Number.prototype.toFixed)
    839 		return parseFloat(v.toFixed(digits));
    840
    841 	if (v < 0)
    842 		// 負數
    843 		n = 1, v = -v;
    844 	if ((i = (v = v.toString(10)).indexOf('e')) !== -1)
    845 		return v.charAt(i + 1) == '-' ? 0 : v;
    846
    847 	//library_namespace.debug(v);
    848 	//	TODO: using +.5 的方法
    849 	//	http://clip.artchiu.org/2009/06/26/%E4%BB%A5%E6%95%B8%E5%AD%B8%E7%9A%84%E5%8E%9F%E7%90%86%E8%99%95%E7%90%86%E3%80%8C%E5%9B%9B%E6%8D%A8%E4%BA%94%E5%85%A5%E3%80%8D/
    850 	if ((i = v.indexOf('.')) !== -1) {
    851 		if (i + 1 + digits < v.length)
    852 			if (max)
    853 				v = v.slice(0, i + 1 + digits);
    854 			else {
    855 				v = '00000000000000000000' + Math.round(
    856 						v.slice(0, i++) + v.substr(i, digits) + '.'
    857 						+ v.charAt(i + digits)).toString(10);
    858 				// (v!=0?alert(v+','+v.length+','+digits+','+v.substr(0,v.length-digits)+','+v.substr(max)):0);
    859 				v = v.slice(0, max = v.length - digits) + '.' + v.substr(max);
    860 			}
    861 	}
    862
    863 	return v ? parseFloat((n ? '-' : '') + v) : 0;
    864 };
    865 /*	old:very slow
    866 function to_fixed(d,m){
    867  var v=this.valueOf(),i;if(isNaN(v))return v;
    868  if(isNaN(d)||d<0)d=8;	//	內定：8位
    869  if(!m){
    870   v=Math.round(Math.pow(10,d)*v);v=v<0?'-'+'0'.x(d)+(-v):'0'.x(d)+v;
    871   v=v.slice(0,i=v.length-d)+'.'+v.substr(i);
    872  }else if(i=(v=''+v).indexOf('.')+1)v=v.slice(0,i+(d?d:d-1));
    873  return parseFloat(v||0);
    874 }
    875 */
    876
    877 /*
    878 //	增添單位
    879 var addDenominationSet={};
    880 addDenominationSet.a=',,,,'.split(',');
    881 function addDenomination(a,b){
    882
    883 }
    884 */
    885
    886
    887
    888
    889 //var sourceF=WScript.ScriptName,targetF='test.js';simpleWrite('tmp.js',alert+'\n'+simpleRead+'\n'+simpleWrite+'\nvar t="",ForReading=1,ForWriting=2,ForAppending=8\n,TristateUseDefault=-2,TristateTrue=-1,TristateFalse=0\n,WshShell=WScript.CreateObject("WScript.Shell"),fso=WScript.CreateObject("Scripting.FileSystemObject");\nt='+dQuote(simpleRead(sourceF),80)+';\nsimpleWrite("'+targetF+'",t);//eval(t);\nalert(simpleRead("'+sourceF+'")==simpleRead("'+targetF+'")?"The same (test dQuote OK!)":"Different!");');//WshShell.Run('"'+getFolder(WScript.ScriptFullName)+targetF+'"');
    890 //	determine quotation mark:輸入字串，傳回已加'或"之字串。
    891 /*
    892 dQuote.qc=function(c,C){
    893 	return c<32?'\\'+c:C;
    894 };
    895 */
    896 function dQuote(s,len,sp){	//	string,分割長度(會採用'~'+"~"的方式),separator(去除末尾用)
    897  var q;s=''+s;if(sp)s=s.replace(new RegExp('['+sp+']+$'),'');	//	去除末尾之sp
    898  if(isNaN(len)||len<0)len=0;
    899  if(len){
    900   var t='';
    901   for(;s;)t+='+'+dQuote(s.slice(0,len))+'\n',s=s.substr(len);	//	'\n':NewLine
    902   return t.substr(1);
    903  }
    904  //if(len){var t='';for(;s;)t+='t+='+dQuote(s.slice(0,len))+'\n',s=s.substr(len);return t.substr(3);}	//	test用
    905  s=s.replace(/\\/g,'\\\\')
    906 	.replace(/\r/g,'\\r').replace(/\n/g,'\\n')	//	\b,\t,\f
    907 	//	轉換控制字符
    908 	.replace(/([\0-\37\x7f\xff])/g,function($0,$1){var c=$1.charCodeAt(0);return c<64?'\\'+c.toString(8):'\\x'+(c<16?'0':'')+c.toString(16);})
    909 	//.replace(/([\u00000100-\uffffffff])/g,function($0,$1){})
    910 	;
    911  //q=s.length;while(s.charAt(--q)==sp);s=s.slice(0,q+1);
    912  if(s.indexOf(q="'")!=-1)q='"';
    913  if(s.indexOf(q)!=-1)s=s.replace(new RegExp(q="'",'g'),"\\'");	//	,alert("Can't determine quotation mark, the resource may cause error.\n"+s);
    914  return q+s+q;
    915 }
    916
    917
    918 CeL.native
    919 .
    920 /**
    921  * check input string send to SQL server
    922  * @param {String} string	input string
    923  * @return	{String}	轉換過的 string
    924  * @since	2006/10/27 16:36
    925  * @see
    926  * from lib/perl/BaseF.pm (or program/database/BaseF.pm)
    927  * @memberOf	CeL.native
    928  */
    929 checkSQLInput=function (string) {
    930 	if (!string)
    931 		return '';
    932
    933 	// 限制長度
    934 	if (maxInput && string.length > maxInput)
    935 		string = string.slice(0, maxInput);
    936
    937 	return string
    938 		// for \uxxxx
    939 		.replace(/\\u([\da-f]{4})/g, function($0, $1) {
    940 			return String.fromCharCode($1);
    941 		}).replace(/\\/g, '\\\\')
    942
    943 		// .replace(/[\x00-\x31]/g,'')
    944 		.replace(/\x00/g, '\\0')
    945
    946 		// .replace(/\x09/g,'\\t')
    947 		// .replace(/\x1a/g,'\\Z')
    948
    949 		// .replace(/\r\n/g,' ')
    950 		.replace(/\r/g, '\\r').replace(/\n/g, '\\n')
    951
    952 		// .replace(/"/g,'\\"')
    953 		.replace(/'/g, "''");
    954 };
    955
    956 /**
    957  * check input string send to SQL server 並去掉前後 space
    958  * @param {String} string	input string
    959  * @return	{String}	轉換過的 string
    960  * @since	2006/10/27 16:36
    961  * @see
    962  * from lib/perl/BaseF.pm (or program/database/BaseF.pm)
    963  * function strip() @ Prototype JavaScript framework
    964  * @memberOf	CeL.native
    965  */
    966 function checkSQLInput_noSpace(string) {
    967 	return string ? checkSQLInput(string
    968 			// .replace(/[\s\n]+$|^[\s\n]+/g,'')
    969 			.replace(/^\s+|\s+$/g, ''))
    970 		: '';
    971 }
    972 ;
    973 /*
    974
    975 2010/6/1
    976 test time:
    977
    978 '   fhdgjk   lh gjkl ;sfdf d  hf gj '
    979
    980 .replace(/^\s+|\s+$/g, '')
    981 ~<
    982 .replace(/\s+$|^\s+/g, '')
    983 <
    984 .replace(/^\s+/, '').replace(/\s+$/, '')
    985 ~<
    986 .replace(/\s+$/, '').replace(/^\s+/, '')
    987
    988 */
    989
    990
    991
    992 CeL.native
    993 .
    994 /**
    995  * 轉換字串成數值，包括分數等。分數亦將轉為分數。
    996  * @param {String} number	欲轉換之值
    997  * @return
    998  * @memberOf	CeL.native
    999  */
    1000 parse_number = function(number) {
    1001 	var m = typeof number;
    1002 	if (m === 'number')
    1003 		return number;
    1004 	if (!number || m !== 'string')
    1005 		return NaN;
    1006
    1007 	number = number.replace(/(\d),(\d)/g, '$1$2');
    1008 	if (m = number.match(/(-?[\d.]+)\s+([\d.]+)\/([\d.]+)/)) {
    1009 		var p = parseFloat(m[1]), q = parseFloat(m[2]) / parseFloat(m[3]);
    1010 		return p + (m[1].charAt(0) === '-' ? -q : q);
    1011 	}
    1012 	if (m = number.match(/(-?[\d.]+)\/([\d.]+)/))
    1013 		// new quotient(m[1],m[2])
    1014 		return parseFloat(m[1]) / parseFloat(m[2]);
    1015
    1016 /*
    1017 	try {
    1018 		return isNaN(m = parseFloat(number)) ?
    1019 				//	TODO: security hole
    1020 				eval(number) : m;
    1021 	} catch (e) {
    1022 		return m;
    1023 	}
    1024 */
    1025 };
    1026
    1027
    1028
    1029
    1030
    1031
    1032 return (
    1033 	CeL.native
    1034 );
    1035 };
    1036
    1037 //===================================================
    1038
    1039 CeL.setup_module(module_name, code_for_including);
    1040
    1041 };
    1042