1 2 /** 3 * @name CeL function for HTA 4 * @fileoverview 5 * 本檔案包含了 web HTA 的 functions。 6 * @since 7 */ 8 9 if (typeof CeL === 'function'){ 10 11 /** 12 * 本 module 之 name(id),<span style="text-decoration:line-through;">不設定時會從呼叫時之 path 取得</span>。 13 * @type String 14 * @constant 15 * @inner 16 * @ignore 17 */ 18 var module_name = 'net.HTA'; 19 20 //=================================================== 21 /** 22 * 若欲 include 整個 module 時,需囊括之 code。 23 * @type Function 24 * @param {Function} library_namespace namespace of library 25 * @param load_arguments 呼叫時之 argument(s) 26 * @return 27 * @name CeL.net.HTA 28 * @constant 29 * @inner 30 * @ignore 31 */ 32 var code_for_including = function(library_namespace, load_arguments) { 33 34 // requires 35 if (eval(library_namespace.use_function( 36 'code.compatibility.is_DOM'))) 37 return; 38 39 40 /** 41 * null module constructor 42 * @class web HTA 的 functions 43 */ 44 CeL.net.HTA 45 = function() { 46 // null module constructor 47 }; 48 49 /** 50 * for JSDT: 有 prototype 才會將之當作 Class 51 */ 52 CeL.net.HTA 53 .prototype = { 54 }; 55 56 57 58 /* 59 TODO: 60 JavaScript closure and IE 4-6 memory leak 61 Mozilla ActiveX Project http://www.iol.ie/%7Elocka/mozilla/mozilla.htm 62 IE臨時文件的位置可以從註冊表鍵值 HKLM\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Cache\paths\Directory 中讀取。 63 */ 64 65 CeL.net.HTA 66 . 67 /** 68 * Internet Explorer Automation tool 69 * @param {String} [URL] initial URL 70 * @returns {IEA} 71 * @memberOf CeL.net.HTA 72 */ 73 IEA = function (URL) { 74 75 try { 76 /* COM objects 77 WScript.CreateObject("InternetExplorer.Application","Event_"); 78 new ActiveXObject(class[, servername]); 79 80 http://www.cnblogs.com/xdotnet/archive/2007/04/09/javascript_object_activexobject.html 81 var obj=new ActiveXObject(servername,typename[,location]); 82 servername提供該對象的應用程序名稱; 83 typename要創建的對象地類型或類; 84 location創建該對象得網絡服務器名稱。 85 */ 86 this.app = new ActiveXObject("InternetExplorer.Application"); 87 } catch (e) { 88 // TODO 89 //return; 90 } 91 if (!this.app) 92 return; 93 94 // 要先瀏覽了網頁,才能實行IEApp.Document其他功能。 95 this.go(URL || ''); 96 97 return this; 98 99 /* other functions 100 http://msdn2.microsoft.com/en-us/library/aa752085.aspx 101 http://msdn2.microsoft.com/en-us/library/Aa752084.aspx 102 IEApp.Visible=true; 103 IEApp.Offline=true; 104 IEApp.Document.frames.prompt(); 105 */ 106 }; 107 108 /** 109 * get <frame> 110 * @param document_object document object 111 * @param name frame name 112 * @returns 113 */ 114 _.IEA.frame = function(document_object, name) { 115 try { 116 document_object = document_object.getElementsByTagName('frame'); 117 return name ? document_object[name].contentWindow.document : document_object; 118 } catch (e) { 119 // TODO 120 } 121 }; 122 123 _.IEA.prototype = { 124 /** 125 * 本 IEA 之 status 是否 OK. 126 * 以有無視窗,否則以有無內容判別OK 關掉視窗時, typeof this.app.Visible=='unknown' 127 * @param w window object 128 * @returns 129 */ 130 OK : function(w) { 131 try { 132 if (w ? typeof this.app.Visible == 'boolean' 133 : this.doc().body.innerHTML) 134 return this.app; 135 } catch (e) { 136 } 137 }, 138 autoSetBase : true, 139 baseD : '', 140 baseP : '', 141 //initP : 'about:blank', 142 timeout : 3e4, // ms>0 143 setBase : function(URL) { 144 var m = (URL || '').match(/^([\w\d\-]+:\/\/[^\/]+)(.*?)$/); 145 if (m) 146 this.baseD = m[1], this.baseP = m[2].slice(0, 147 m[2].lastIndexOf('/') + 1); 148 //WScript.Echo('IEA.setBase:\ndomin: '+this.baseD+'\npath: '+this.baseP); 149 return this.baseD; 150 }, 151 /** 152 * go to URL 153 * @param URL URL or history num 154 * @returns 155 */ 156 go : function(URL) { 157 var _t = this; 158 try { 159 if (URL === '' || isNaN(URL)) { 160 if (URL === '') 161 URL = 'about:blank';// _t.initP; 162 if (URL) { 163 if (URL.indexOf(':') == -1)// if(URL.indexOf('://')==-1&&URL.indexOf('about:')==-1) 164 URL = _t.baseD + (URL.charAt(0) == '/' ? '' : _t.baseP) 165 + URL; 166 167 // IEApp.Document.frames.open(URL); ** 請注意:這裡偶爾會造成script停滯,並跳出警告視窗! 168 _t.app.Navigate(URL); 169 170 if (_t.autoSetBase) 171 _t.setBase(URL); 172 _t.wait(); 173 174 // 防止自動關閉 175 //_t.win().onclose=function(){return false;};//_t.win().close=null; 176 } 177 } else 178 _t.win().history.go(URL), _t.wait(); 179 180 } catch (e) { 181 } 182 eName = 0; 183 return _t; 184 }, 185 /* 完全載入 186 TODO: 187 http://javascript.nwbox.com/IEContentLoaded/ 188 try{document.documentElement.doScroll('left');} 189 catch(e){setTimeout(arguments.callee, 50);return;} 190 instead of onload 191 */ 192 waitStamp : 0, 193 waitInterval : 200, // ms 194 waitState : 3, // 1-4: READYSTATE_COMPLETE=4 usual set to interactive=3 195 wait : function(w) { 196 if (!w && !(w = this.waitState) || this.waitStamp) 197 return; // !!this.waitStamp: wait中 198 this.waitStamp = new Date; 199 try { 200 // 可能中途被關掉 201 while (new Date - this.waitStamp < this.timeout 202 && (!this.OK(1) || this.app.busy || this.app.readyState < w)) 203 try { 204 // Win98的JScript沒有WScript.Sleep 205 WScript.Sleep(this.waitInterval); 206 } catch (e) { 207 } 208 } catch (e) { 209 } 210 w = new Date - this.waitStamp, this.waitStamp = 0; 211 return w; 212 }, 213 quit : function() { 214 try { 215 this.app.Quit(); 216 } catch (e) { 217 } 218 this.app = null; 219 if (typeof CollectGarbage == 'function') 220 // CollectGarbage(): undocumented IE javascript method: 先置為 null 再 CollectGarbage(); 設置為null,它會斷開對象的引用,但是IE為了節省資源(經常釋放內存也會佔系統資源),因此採用的是延遲釋放策略,你調用CollectGarbage函數,就會強制立即釋放。 221 // http://www.cnblogs.com/stupidliao/articles/797659.html 222 setTimeout(function() { 223 CollectGarbage(); 224 }, 0); 225 return; 226 }, 227 // 用IE.doc().title or IE.app.LocationName 可反映狀況 228 doc : function() { 229 try { 230 return this.app.document; 231 } catch (e) { 232 } 233 }, 234 href : function() { 235 try { 236 return this.app.LocationURL; 237 } catch (e) { 238 } 239 }, 240 win : function() { 241 try { 242 return this.doc().parentWindow; 243 } catch (e) { 244 } 245 }, 246 /* 247 reload:function(){ 248 try{IE.win().history.go(0);IE.wait();}catch(e){} 249 }, 250 */ 251 /** 252 * get element 253 * @param e 254 * @param o 255 * @returns 256 */ 257 getE : function(e, o) { 258 try { 259 return (o || this.doc()).getElementById(e); 260 } catch (e) { 261 } 262 }, 263 /** 264 * get tag 265 * @param e 266 * @param o 267 * @returns 268 */ 269 getT : function(e, o) { 270 try { 271 return (o || this.doc()).getElementsByTagName(e); 272 } catch (e) { 273 } 274 }, 275 // name/id, HTML object to get frame, return document object or not 276 // .getElementsByName() 277 // http://www.w3school.com.cn/htmldom/met_doc_getelementsbyname.asp 278 frame : function(n, f, d) { 279 try { 280 f = f ? f.getElementsByTagName('frame') : this.getT('frame'); 281 if (isNaN(n)) 282 if (!n) 283 return f; 284 else 285 for ( var i = 0; i < f.length; i++) 286 if (f[i].name == n) { 287 n = i; 288 break; 289 } 290 if (!isNaN(n)) 291 return d ? f[n].contentWindow.document : f[n]; 292 } catch (e) { 293 } 294 }, 295 // IE.frames()['*'] IEApp.document.frames 296 // Cross Site AJAX http://blog.joycode.com/saucer/archive/2006/10/03/84572.aspx 297 // Cross-Site XMLHttpRequest http://ejohn.org/blog/cross-site-xmlhttprequest/ 298 frames : function() { 299 try { 300 var i = 0, f = this.getT('frame'), r = []; 301 for (r['*'] = []; i < f.length; i++) 302 r['*'].push(f(i).name), r[f(i).name] = r[i] = f(i); 303 // use frame.window, frame.document 304 return r; 305 } catch (e) { 306 } 307 }, 308 // form name array 309 // formNA : 0, 310 // return name&id object. 設置這個還可以強制 do submit 使用 name 為主,不用 id。 311 fillForm_rtE : 0, 312 /** 313 * 填充 form 314 * @param parameter parameter={id/name:value} 315 * @param submit_id do submit(num) 或 button id 316 * @param form_index submit 之 form index 或 id 317 * @returns 318 */ 319 fillForm : function(parameter, submit_id, form_index) { 320 try { 321 var i, j, n = {}, h = 0, f = this.doc().forms[form_index || 0] || {}, t, 322 // g=f.getElementById, 323 s = function( 324 o, v) { 325 t = o.tagName.toLowerCase(); 326 if (t == 'select') 327 if (isNaN(v) || v < 0 || v >= o.options.length) 328 o.value = v; 329 else 330 // .options[i].value==v 331 // .selectedIndex= 的設定有些情況下會失效 332 o.selectedIndex = v; 333 // 參考 cookieForm 334 else if (t == 'input') { 335 t = o.type.toLowerCase(); // .getAttribute('type') 336 if (t == 'checkbox') 337 o.checked = v; 338 else if (t != 'radio') 339 o.value = v; 340 else if (o.value == v) 341 o.checked = true; 342 else 343 return true; // return true: 需要再處理 344 } else if (t == 'textarea') 345 o.value = v; 346 }; 347 /* needless 348 if(!f){ 349 f=this.getT('form'); 350 for(i in f)if(f[i].name==fi){f=a[i];break;} 351 } 352 if(!f)f={}; 353 */ 354 for (j in parameter) 355 if (!(i = /* f.getElementById?f.getElementById(j): */this 356 .getE(j)) 357 || s(i, parameter[j])) 358 n[j] = 1, h = 1; 359 if ((h || this.fillForm_rtE) 360 && (i = f.getElementsByTagName ? f 361 .getElementsByTagName('input') : this.getT('input'))) 362 for (j = 0; j < i.length; j++) 363 if (i[j].name in n) 364 s(i[j], parameter[i[j].name]); 365 else if (submit_id && typeof submit_id != 'object' && submit_id == i[j].name) 366 submit_id = i[j]; 367 // if(i[j].name in pm)s(i[j],pm[i[j].name]); 368 if (submit_id) { 369 if (i = typeof submit_id == 'object' ? submit_id 370 : /* f.getElementById&&f.getElementById(l)|| */ 371 this.getE(submit_id)) 372 i.click(); 373 else 374 f.submit(); 375 this.wait(); 376 } else if (this.fillForm_rtE) { 377 h = { 378 '' : i 379 }; 380 for (j = 0; j < i.length; j++) 381 if (i[j].name) 382 h[i[j].name] = i[j]; 383 return h; 384 } 385 } catch (e) { 386 } 387 return this; 388 }, 389 setLoc : function(w, h, l, t) { 390 try { 391 var s = this.win().screen; 392 with (this.app) { 393 if (w) { 394 Width = w; 395 if (typeof l == 'undefined') 396 l = (s.availWidth - w) / 2; 397 } 398 if (h) { 399 Height = h; 400 if (typeof t == 'undefined') 401 t = (s.availHeight - h) / 2; 402 } 403 if (l) 404 Left = l; 405 if (t) 406 Top = t; 407 } 408 } catch (e) { 409 } 410 return this; 411 }, 412 write : function(h) { 413 try { 414 if (!this.doc()) 415 this.go(''); 416 with (this.doc()) 417 open(), write(h || ''), close(); 418 } catch (e) { 419 } 420 return this; 421 }, 422 // 使之成為 dialog 形式的視窗 423 // http://members.cox.net/tglbatch/wsh/ 424 setDialog : function(w, h, l, t, H) { 425 try { 426 with (this.app) 427 FullScreen = true, ToolBar = false, StatusBar = false; 428 } catch (e) { 429 } 430 this.setLoc(w, h, l, t); 431 if (H) 432 this.write(H).focus(); 433 try { 434 // 太早設定 scroll 沒用。 435 with (this.doc().body) 436 scroll = 'no', style.borderStyle = 'outset', 437 style.borderWidth = '3px'; 438 } catch (e) { 439 } 440 return this; 441 }, 442 show : function(s) { 443 try { 444 this.app.Visible = s || typeof s == 'undefined'; 445 } catch (e) { 446 } 447 return this; 448 }, 449 focus : function(s) { 450 try { 451 if (s || typeof s === 'undefined') 452 this.win().focus(); 453 else 454 this.win().blur(); 455 } catch (e) { 456 } 457 return this; 458 }, 459 get_page : function() { 460 return this.getT('html')[0].outerHTML; 461 }, 462 save_page : function(path, encoding) { 463 var text = this.get_page(); 464 if (path && text) { 465 href = this.href(), l = href.length; 466 l = (l > 9 ? l > 99 ? l > 999 ? '' : '0' : '00' : '000') 467 + l; 468 simpleWrite(path, '<!-- saved from url=(' + l + ')' + href 469 + ' -->' + NewLine + text, encoding || TristateTrue); 470 } 471 return this; 472 }, 473 getC : function(class_name) { 474 return find_class(class_name, this.doc()); 475 } 476 }; 477 // IEA.prototype={ 478 479 480 481 482 483 484 // WSH環境中設定剪貼簿的資料:多此一舉 http://yuriken.hp.infoseek.co.jp/index3.html http://code.google.com/p/zeroclipboard/ 485 //setClipboardText[generateCode.dLK]='IEA';//,clipboardFunction 486 function setClipboardText(cData,cType){ 487 if(typeof clipboardFunction=='function')return clipboardFunction(); 488 var IE=new IEA; 489 if(!IE.OK(1))return ''; 490 if(!cType)cType='text'; 491 492 with(IE.win()) 493 if(cData)window.clipboardData.setData(cType,cData); 494 else cData=window.clipboardData.getData(cType); 495 496 IE.quit();//try{IEApp.Quit();}catch(e){} 497 return cData||''; 498 }; 499 500 CeL.net.HTA 501 . 502 /** 503 * WSH 環境中取得剪貼簿的資料 504 * @memberOf CeL.net.HTA 505 */ 506 getClipboardText = setClipboardText; 507 508 509 510 511 512 return ( 513 CeL.net.HTA 514 ); 515 }; 516 517 //=================================================== 518 519 CeL.setup_module(module_name, code_for_including); 520 521 }; 522