[2747] | 1 | ajaxterm={}; |
---|
[2752] | 2 | ajaxterm.Terminal_ctor=function(id,machine_id) { |
---|
[2747] | 3 | var ie=0; |
---|
| 4 | if(window.ActiveXObject) |
---|
| 5 | ie=1; |
---|
[2752] | 6 | var base_path="machine/"+machine_id+"/at"; |
---|
| 7 | var query0=""; |
---|
[2747] | 8 | var query1=query0+"&c=1&k="; |
---|
| 9 | var buf=""; |
---|
| 10 | var timeout; |
---|
| 11 | var error_timeout; |
---|
| 12 | var keybuf=[]; |
---|
| 13 | var sending=0; |
---|
| 14 | var rmax=1; |
---|
| 15 | |
---|
| 16 | var div=document.getElementById(id); |
---|
| 17 | var dstat=document.createElement('pre'); |
---|
| 18 | var sled=document.createElement('span'); |
---|
| 19 | var opt_color=document.createElement('a'); |
---|
| 20 | var opt_paste=document.createElement('a'); |
---|
| 21 | var sdebug=document.createElement('span'); |
---|
| 22 | var dterm=document.createElement('div'); |
---|
| 23 | |
---|
| 24 | function debug(s) { |
---|
| 25 | sdebug.innerHTML=s; |
---|
| 26 | } |
---|
| 27 | function error() { |
---|
| 28 | sled.className='off'; |
---|
| 29 | debug("Connection lost timeout ts:"+((new Date).getTime())); |
---|
| 30 | } |
---|
| 31 | function opt_add(opt,name) { |
---|
| 32 | opt.className='off'; |
---|
| 33 | opt.innerHTML=' '+name+' '; |
---|
| 34 | dstat.appendChild(opt); |
---|
| 35 | dstat.appendChild(document.createTextNode(' ')); |
---|
| 36 | } |
---|
| 37 | function do_color(event) { |
---|
| 38 | var o=opt_color.className=(opt_color.className=='off')?'on':'off'; |
---|
| 39 | if(o=='on') |
---|
| 40 | query1=query0+"&c=1&k="; |
---|
| 41 | else |
---|
| 42 | query1=query0+"&k="; |
---|
| 43 | debug('Color '+opt_color.className); |
---|
| 44 | } |
---|
| 45 | function mozilla_clipboard() { |
---|
| 46 | // mozilla sucks |
---|
| 47 | try { |
---|
| 48 | netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
---|
| 49 | } catch (err) { |
---|
| 50 | debug('Access denied, <a href="http://kb.mozillazine.org/Granting_JavaScript_access_to_the_clipboard" target="_blank">more info</a>'); |
---|
| 51 | return undefined; |
---|
| 52 | } |
---|
| 53 | var clip = Components.classes["@mozilla.org/widget/clipboard;1"].createInstance(Components.interfaces.nsIClipboard); |
---|
| 54 | var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable); |
---|
| 55 | if (!clip || !trans) { |
---|
| 56 | return undefined; |
---|
| 57 | } |
---|
| 58 | trans.addDataFlavor("text/unicode"); |
---|
| 59 | clip.getData(trans,clip.kGlobalClipboard); |
---|
| 60 | var str=new Object(); |
---|
| 61 | var strLength=new Object(); |
---|
| 62 | try { |
---|
| 63 | trans.getTransferData("text/unicode",str,strLength); |
---|
| 64 | } catch(err) { |
---|
| 65 | return ""; |
---|
| 66 | } |
---|
| 67 | if (str) { |
---|
| 68 | str=str.value.QueryInterface(Components.interfaces.nsISupportsString); |
---|
| 69 | } |
---|
| 70 | if (str) { |
---|
| 71 | return str.data.substring(0,strLength.value / 2); |
---|
| 72 | } else { |
---|
| 73 | return ""; |
---|
| 74 | } |
---|
| 75 | } |
---|
| 76 | function do_paste(event) { |
---|
| 77 | var p=undefined; |
---|
| 78 | if (window.clipboardData) { |
---|
| 79 | p=window.clipboardData.getData("Text"); |
---|
| 80 | } else if(window.netscape) { |
---|
| 81 | p=mozilla_clipboard(); |
---|
| 82 | } |
---|
| 83 | if (p) { |
---|
| 84 | debug('Pasted'); |
---|
| 85 | queue(encodeURIComponent(p)); |
---|
| 86 | } else { |
---|
| 87 | } |
---|
| 88 | } |
---|
| 89 | function update() { |
---|
| 90 | // debug("ts: "+((new Date).getTime())+" rmax:"+rmax); |
---|
| 91 | if(sending==0) { |
---|
| 92 | sending=1; |
---|
| 93 | sled.className='on'; |
---|
| 94 | var r=new XMLHttpRequest(); |
---|
| 95 | var send=""; |
---|
| 96 | while(keybuf.length>0) { |
---|
| 97 | send+=keybuf.pop(); |
---|
| 98 | } |
---|
| 99 | var query=query1+send; |
---|
[2761] | 100 | if (dterm.firstChild && dterm.firstChild.id) { |
---|
| 101 | query=query+"&h="+dterm.firstChild.id; |
---|
[2753] | 102 | } |
---|
[2759] | 103 | r.open("POST",base_path,true); |
---|
[2747] | 104 | r.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); |
---|
| 105 | r.onreadystatechange = function () { |
---|
| 106 | // debug("xhr:"+((new Date).getTime())+" state:"+r.readyState+" status:"+r.status+" statusText:"+r.statusText); |
---|
| 107 | if (r.readyState==4) { |
---|
| 108 | if(r.status==200) { |
---|
| 109 | window.clearTimeout(error_timeout); |
---|
| 110 | de=r.responseXML.documentElement; |
---|
| 111 | if(de.tagName=="pre") { |
---|
| 112 | if(ie) { |
---|
| 113 | Sarissa.updateContentFromNode(de, dterm); |
---|
| 114 | } else { |
---|
| 115 | Sarissa.updateContentFromNode(de, dterm); |
---|
| 116 | // old=div.firstChild; |
---|
| 117 | // div.replaceChild(de,old); |
---|
| 118 | } |
---|
| 119 | rmax=100; |
---|
| 120 | } else { |
---|
| 121 | rmax*=2; |
---|
| 122 | if(rmax>2000) |
---|
| 123 | rmax=2000; |
---|
| 124 | } |
---|
| 125 | sending=0; |
---|
| 126 | sled.className='off'; |
---|
| 127 | timeout=window.setTimeout(update,rmax); |
---|
| 128 | } else { |
---|
| 129 | debug("Connection error status:"+r.status); |
---|
| 130 | } |
---|
| 131 | } |
---|
| 132 | } |
---|
| 133 | error_timeout=window.setTimeout(error,5000); |
---|
[2759] | 134 | r.send(query); |
---|
[2747] | 135 | } |
---|
| 136 | } |
---|
| 137 | function queue(s) { |
---|
| 138 | keybuf.unshift(s); |
---|
| 139 | if(sending==0) { |
---|
| 140 | window.clearTimeout(timeout); |
---|
| 141 | timeout=window.setTimeout(update,1); |
---|
| 142 | } |
---|
| 143 | } |
---|
| 144 | function keypress(ev) { |
---|
| 145 | if (!ev) var ev=window.event; |
---|
| 146 | // s="kp keyCode="+ev.keyCode+" which="+ev.which+" shiftKey="+ev.shiftKey+" ctrlKey="+ev.ctrlKey+" altKey="+ev.altKey; |
---|
| 147 | // debug(s); |
---|
| 148 | // return false; |
---|
| 149 | // else { if (!ev.ctrlKey || ev.keyCode==17) { return; } |
---|
| 150 | var kc; |
---|
| 151 | var k=""; |
---|
| 152 | if (ev.keyCode) |
---|
| 153 | kc=ev.keyCode; |
---|
| 154 | if (ev.which) |
---|
| 155 | kc=ev.which; |
---|
| 156 | if (ev.altKey) { |
---|
| 157 | if (kc>=65 && kc<=90) |
---|
| 158 | kc+=32; |
---|
| 159 | if (kc>=97 && kc<=122) { |
---|
| 160 | k=String.fromCharCode(27)+String.fromCharCode(kc); |
---|
| 161 | } |
---|
| 162 | } else if (ev.ctrlKey) { |
---|
| 163 | if (kc>=65 && kc<=90) k=String.fromCharCode(kc-64); // Ctrl-A..Z |
---|
| 164 | else if (kc>=97 && kc<=122) k=String.fromCharCode(kc-96); // Ctrl-A..Z |
---|
| 165 | else if (kc==54) k=String.fromCharCode(30); // Ctrl-^ |
---|
| 166 | else if (kc==109) k=String.fromCharCode(31); // Ctrl-_ |
---|
| 167 | else if (kc==219) k=String.fromCharCode(27); // Ctrl-[ |
---|
| 168 | else if (kc==220) k=String.fromCharCode(28); // Ctrl-\ |
---|
| 169 | else if (kc==221) k=String.fromCharCode(29); // Ctrl-] |
---|
| 170 | else if (kc==219) k=String.fromCharCode(29); // Ctrl-] |
---|
| 171 | else if (kc==219) k=String.fromCharCode(0); // Ctrl-@ |
---|
[2763] | 172 | else k=String.fromCharCode(kc); |
---|
[2747] | 173 | } else if (ev.which==0) { |
---|
| 174 | if (kc==9) k=String.fromCharCode(9); // Tab |
---|
| 175 | else if (kc==8) k=String.fromCharCode(127); // Backspace |
---|
| 176 | else if (kc==27) k=String.fromCharCode(27); // Escape |
---|
| 177 | else { |
---|
| 178 | if (kc==33) k="[5~"; // PgUp |
---|
| 179 | else if (kc==34) k="[6~"; // PgDn |
---|
| 180 | else if (kc==35) k="[4~"; // End |
---|
| 181 | else if (kc==36) k="[1~"; // Home |
---|
| 182 | else if (kc==37) k="[D"; // Left |
---|
| 183 | else if (kc==38) k="[A"; // Up |
---|
| 184 | else if (kc==39) k="[C"; // Right |
---|
| 185 | else if (kc==40) k="[B"; // Down |
---|
| 186 | else if (kc==45) k="[2~"; // Ins |
---|
| 187 | else if (kc==46) k="[3~"; // Del |
---|
| 188 | else if (kc==112) k="[[A"; // F1 |
---|
| 189 | else if (kc==113) k="[[B"; // F2 |
---|
| 190 | else if (kc==114) k="[[C"; // F3 |
---|
| 191 | else if (kc==115) k="[[D"; // F4 |
---|
| 192 | else if (kc==116) k="[[E"; // F5 |
---|
| 193 | else if (kc==117) k="[17~"; // F6 |
---|
| 194 | else if (kc==118) k="[18~"; // F7 |
---|
| 195 | else if (kc==119) k="[19~"; // F8 |
---|
| 196 | else if (kc==120) k="[20~"; // F9 |
---|
| 197 | else if (kc==121) k="[21~"; // F10 |
---|
| 198 | else if (kc==122) k="[23~"; // F11 |
---|
| 199 | else if (kc==123) k="[24~"; // F12 |
---|
| 200 | if (k.length) { |
---|
| 201 | k=String.fromCharCode(27)+k; |
---|
| 202 | } |
---|
| 203 | } |
---|
| 204 | } else { |
---|
| 205 | if (kc==8) |
---|
| 206 | k=String.fromCharCode(127); // Backspace |
---|
| 207 | else |
---|
| 208 | k=String.fromCharCode(kc); |
---|
| 209 | } |
---|
| 210 | if(k.length) { |
---|
| 211 | // queue(encodeURIComponent(k)); |
---|
| 212 | if(k=="+") { |
---|
| 213 | queue("%2B"); |
---|
| 214 | } else { |
---|
| 215 | queue(escape(k)); |
---|
| 216 | } |
---|
| 217 | } |
---|
| 218 | ev.cancelBubble=true; |
---|
| 219 | if (ev.stopPropagation) ev.stopPropagation(); |
---|
| 220 | if (ev.preventDefault) ev.preventDefault(); |
---|
| 221 | return false; |
---|
| 222 | } |
---|
| 223 | function keydown(ev) { |
---|
| 224 | if (!ev) var ev=window.event; |
---|
| 225 | if (ie) { |
---|
| 226 | // s="kd keyCode="+ev.keyCode+" which="+ev.which+" shiftKey="+ev.shiftKey+" ctrlKey="+ev.ctrlKey+" altKey="+ev.altKey; |
---|
| 227 | // debug(s); |
---|
| 228 | o={9:1,8:1,27:1,33:1,34:1,35:1,36:1,37:1,38:1,39:1,40:1,45:1,46:1,112:1, |
---|
| 229 | 113:1,114:1,115:1,116:1,117:1,118:1,119:1,120:1,121:1,122:1,123:1}; |
---|
| 230 | if (o[ev.keyCode] || ev.ctrlKey || ev.altKey) { |
---|
| 231 | ev.which=0; |
---|
| 232 | return keypress(ev); |
---|
| 233 | } |
---|
| 234 | } |
---|
| 235 | } |
---|
| 236 | function init() { |
---|
| 237 | sled.appendChild(document.createTextNode('\xb7')); |
---|
| 238 | sled.className='off'; |
---|
| 239 | dstat.appendChild(sled); |
---|
| 240 | dstat.appendChild(document.createTextNode(' ')); |
---|
| 241 | opt_add(opt_color,'Colors'); |
---|
| 242 | opt_color.className='on'; |
---|
| 243 | opt_add(opt_paste,'Paste'); |
---|
| 244 | dstat.appendChild(sdebug); |
---|
| 245 | dstat.className='stat'; |
---|
| 246 | div.appendChild(dstat); |
---|
| 247 | div.appendChild(dterm); |
---|
| 248 | if(opt_color.addEventListener) { |
---|
| 249 | opt_color.addEventListener('click',do_color,true); |
---|
| 250 | opt_paste.addEventListener('click',do_paste,true); |
---|
| 251 | } else { |
---|
| 252 | opt_color.attachEvent("onclick", do_color); |
---|
| 253 | opt_paste.attachEvent("onclick", do_paste); |
---|
| 254 | } |
---|
[2760] | 255 | // If tabIndex works, only grab keyboard events when terminal is focused |
---|
| 256 | // Otherwise, grab from whole document (e.g. in Safari). |
---|
| 257 | var focus_element = document; |
---|
| 258 | if(typeof $('term').tabIndex != "undefined") { |
---|
| 259 | focus_element = $('term'); |
---|
| 260 | focus_element.focus(); |
---|
| 261 | } |
---|
| 262 | focus_element.onkeypress=keypress; |
---|
| 263 | focus_element.onkeydown=keydown; |
---|
[2747] | 264 | timeout=window.setTimeout(update,100); |
---|
| 265 | } |
---|
| 266 | init(); |
---|
| 267 | } |
---|
[2752] | 268 | ajaxterm.Terminal=function(id,machine_id) { |
---|
| 269 | return new this.Terminal_ctor(id,machine_id); |
---|
[2747] | 270 | } |
---|
| 271 | |
---|