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