source: package_branches/invirt-web/cherrypy/code/static/ajaxterm/ajaxterm.js @ 2439

Last change on this file since 2439 was 2435, checked in by quentin, 15 years ago

Allow reconnecting to the same terminal session

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