1 | ajaxterm={}; |
---|
2 | ajaxterm.Terminal_ctor=function(id,machine_id) { |
---|
3 | var ie=0; |
---|
4 | if(window.ActiveXObject) |
---|
5 | ie=1; |
---|
6 | var base_path="machine/"+machine_id+"/at"; |
---|
7 | var query0=""; |
---|
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; |
---|
100 | if (dterm.firstChild && dterm.firstChild.id) { |
---|
101 | query=query+"&h="+dterm.firstChild.id; |
---|
102 | } |
---|
103 | r.open("POST",base_path,true); |
---|
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); |
---|
134 | r.send(query); |
---|
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-@ |
---|
172 | } else if (ev.which==0) { |
---|
173 | if (kc==9) k=String.fromCharCode(9); // Tab |
---|
174 | else if (kc==8) k=String.fromCharCode(127); // Backspace |
---|
175 | else if (kc==27) k=String.fromCharCode(27); // Escape |
---|
176 | else { |
---|
177 | if (kc==33) k="[5~"; // PgUp |
---|
178 | else if (kc==34) k="[6~"; // PgDn |
---|
179 | else if (kc==35) k="[4~"; // End |
---|
180 | else if (kc==36) k="[1~"; // Home |
---|
181 | else if (kc==37) k="[D"; // Left |
---|
182 | else if (kc==38) k="[A"; // Up |
---|
183 | else if (kc==39) k="[C"; // Right |
---|
184 | else if (kc==40) k="[B"; // Down |
---|
185 | else if (kc==45) k="[2~"; // Ins |
---|
186 | else if (kc==46) k="[3~"; // Del |
---|
187 | else if (kc==112) k="[[A"; // F1 |
---|
188 | else if (kc==113) k="[[B"; // F2 |
---|
189 | else if (kc==114) k="[[C"; // F3 |
---|
190 | else if (kc==115) k="[[D"; // F4 |
---|
191 | else if (kc==116) k="[[E"; // F5 |
---|
192 | else if (kc==117) k="[17~"; // F6 |
---|
193 | else if (kc==118) k="[18~"; // F7 |
---|
194 | else if (kc==119) k="[19~"; // F8 |
---|
195 | else if (kc==120) k="[20~"; // F9 |
---|
196 | else if (kc==121) k="[21~"; // F10 |
---|
197 | else if (kc==122) k="[23~"; // F11 |
---|
198 | else if (kc==123) k="[24~"; // F12 |
---|
199 | if (k.length) { |
---|
200 | k=String.fromCharCode(27)+k; |
---|
201 | } |
---|
202 | } |
---|
203 | } else { |
---|
204 | if (kc==8) |
---|
205 | k=String.fromCharCode(127); // Backspace |
---|
206 | else |
---|
207 | k=String.fromCharCode(kc); |
---|
208 | } |
---|
209 | if(k.length) { |
---|
210 | // queue(encodeURIComponent(k)); |
---|
211 | if(k=="+") { |
---|
212 | queue("%2B"); |
---|
213 | } else { |
---|
214 | queue(escape(k)); |
---|
215 | } |
---|
216 | } |
---|
217 | ev.cancelBubble=true; |
---|
218 | if (ev.stopPropagation) ev.stopPropagation(); |
---|
219 | if (ev.preventDefault) ev.preventDefault(); |
---|
220 | return false; |
---|
221 | } |
---|
222 | function keydown(ev) { |
---|
223 | if (!ev) var ev=window.event; |
---|
224 | if (ie) { |
---|
225 | // s="kd keyCode="+ev.keyCode+" which="+ev.which+" shiftKey="+ev.shiftKey+" ctrlKey="+ev.ctrlKey+" altKey="+ev.altKey; |
---|
226 | // debug(s); |
---|
227 | 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, |
---|
228 | 113:1,114:1,115:1,116:1,117:1,118:1,119:1,120:1,121:1,122:1,123:1}; |
---|
229 | if (o[ev.keyCode] || ev.ctrlKey || ev.altKey) { |
---|
230 | ev.which=0; |
---|
231 | return keypress(ev); |
---|
232 | } |
---|
233 | } |
---|
234 | } |
---|
235 | function init() { |
---|
236 | sled.appendChild(document.createTextNode('\xb7')); |
---|
237 | sled.className='off'; |
---|
238 | dstat.appendChild(sled); |
---|
239 | dstat.appendChild(document.createTextNode(' ')); |
---|
240 | opt_add(opt_color,'Colors'); |
---|
241 | opt_color.className='on'; |
---|
242 | opt_add(opt_paste,'Paste'); |
---|
243 | dstat.appendChild(sdebug); |
---|
244 | dstat.className='stat'; |
---|
245 | div.appendChild(dstat); |
---|
246 | div.appendChild(dterm); |
---|
247 | if(opt_color.addEventListener) { |
---|
248 | opt_color.addEventListener('click',do_color,true); |
---|
249 | opt_paste.addEventListener('click',do_paste,true); |
---|
250 | } else { |
---|
251 | opt_color.attachEvent("onclick", do_color); |
---|
252 | opt_paste.attachEvent("onclick", do_paste); |
---|
253 | } |
---|
254 | // If tabIndex works, only grab keyboard events when terminal is focused |
---|
255 | // Otherwise, grab from whole document (e.g. in Safari). |
---|
256 | var focus_element = document; |
---|
257 | if(typeof $('term').tabIndex != "undefined") { |
---|
258 | focus_element = $('term'); |
---|
259 | focus_element.focus(); |
---|
260 | } |
---|
261 | focus_element.onkeypress=keypress; |
---|
262 | focus_element.onkeydown=keydown; |
---|
263 | timeout=window.setTimeout(update,100); |
---|
264 | } |
---|
265 | init(); |
---|
266 | } |
---|
267 | ajaxterm.Terminal=function(id,machine_id) { |
---|
268 | return new this.Terminal_ctor(id,machine_id); |
---|
269 | } |
---|
270 | |
---|