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