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