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