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