blob: d6fa9d9448f36a527071f416d76d35d47314a9b0 [file] [log] [blame]
Felix Meschberger97204d82012-01-31 12:47:45 +00001//
2// Licensed to the Apache Software Foundation (ASF) under one or more
3// contributor license agreements. See the NOTICE file distributed with
4// this work for additional information regarding copyright ownership.
5// The ASF licenses this file to You under the Apache License, Version 2.0
6// (the "License"); you may not use this file except in compliance with
7// the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16//
17
18//
19// Based on http://antony.lesuisse.org/software/ajaxterm/
20// Public Domain License
21//
22
23gogo = { };
24
25gogo.Terminal_ctor = function(div, width, height) {
26
27 var query0 = "w=" + width + "&h=" + height;
28 var query1 = query0 + "&k=";
29 var buf = "";
30 var timeout;
31 var error_timeout;
32 var keybuf = [];
33 var sending = 0;
34 var rmax = 1;
35 var force = 1;
36
37 var dstat = document.createElement('pre');
38 var sled = document.createElement('span');
Felix Meschberger96812952012-06-01 14:37:54 +000039 var sdebug = document.getElementById('statline');
Felix Meschberger97204d82012-01-31 12:47:45 +000040 var dterm = document.createElement('div');
41
42 function debug(s) {
43 sdebug.innerHTML = s;
44 }
45
46 function error() {
47 sled.className = 'off';
Felix Meschberger96812952012-06-01 14:37:54 +000048 debug("Gogo Shell Processor not available");
Felix Meschberger97204d82012-01-31 12:47:45 +000049 }
50
51 function update() {
Felix Meschberger96812952012-06-01 14:37:54 +000052 if (sending == 0 /* && keybuf.length > 0 */ ) {
Felix Meschberger97204d82012-01-31 12:47:45 +000053 sending = 1;
54 sled.className = 'on';
55 var r = new XMLHttpRequest();
56 var send = "";
57 while (keybuf.length > 0) {
58 send += keybuf.pop();
59 }
60 var query = query1 + send;
61 if (force) {
62 query = query + "&f=1";
63 force = 0;
64 }
65 r.open("POST", "gogo", true);
66 r.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
67 r.onreadystatechange = function () {
68 if (r.readyState == 4) {
69 if (r.status == 200) {
70 window.clearTimeout(error_timeout);
71 if (r.responseText.length > 0) {
72 dterm.innerHTML = r.responseText;
73 rmax = 100;
74 } else {
75 rmax *= 2;
76 if (rmax > 2000)
77 rmax = 2000;
78 }
79 sending=0;
80 sled.className = 'off';
81 timeout = window.setTimeout(update, rmax);
Felix Meschberger96812952012-06-01 14:37:54 +000082 } else if (r.status == 500) {
83 debug("Gogo Shell Processor not available")
Felix Meschberger97204d82012-01-31 12:47:45 +000084 } else {
Felix Meschberger96812952012-06-01 14:37:54 +000085 debug("General failure with Gogo Shell: " + r.status);
Felix Meschberger97204d82012-01-31 12:47:45 +000086 }
87 }
88 }
89 error_timeout = window.setTimeout(error, 5000);
90 r.send(query);
91 }
92 }
93
94 function queue(s) {
95 keybuf.unshift(s);
96 if (sending == 0) {
97 window.clearTimeout(timeout);
98 timeout = window.setTimeout(update, 1);
99 }
100 }
101
Felix Meschberger23756c82013-01-21 21:05:03 +0000102 function keypress(ev) {
Felix Meschberger97204d82012-01-31 12:47:45 +0000103 // Translate to standard keycodes
104 if (!ev)
105 ev = window.event;
106 var kc;
107 if (ev.keyCode)
108 kc = ev.keyCode;
Felix Meschberger23756c82013-01-21 21:05:03 +0000109 if (ev.which)
Felix Meschberger97204d82012-01-31 12:47:45 +0000110 kc = ev.which;
111 if (ev.ctrlKey) {
112 if (kc >= 0 && kc <= 32)
113 kc = kc;
114 else if (kc >= 65 && kc <= 90)
115 kc -= 64;
116 else if (kc >= 97 && kc <= 122)
117 kc -= 96;
118 else {
119 switch (kc) {
120 case 54: kc=30; break; // Ctrl-^
121 case 109: kc=31; break; // Ctrl-_
122 case 219: kc=27; break; // Ctrl-[
123 case 220: kc=28; break; // Ctrl-\
124 case 221: kc=29; break; // Ctrl-]
125 default: return true;
126 }
127 }
Felix Meschberger23756c82013-01-21 21:05:03 +0000128 }
Felix Meschberger97204d82012-01-31 12:47:45 +0000129
130 var k = "";
131 // Build character
132 switch (kc) {
133 case 126: k = "~~"; break;
134 case 63232: k = "~A"; break; // Up
135 case 63233: k = "~B"; break; // Down
136 case 63234: k = "~D"; break; // Left
137 case 63235: k = "~C"; break; // Right
138 case 63276: k = "~1"; break; // PgUp
139 case 63277: k = "~2"; break; // PgDn
140 case 63273: k = "~H"; break; // Home
141 case 63275: k = "~F"; break; // End
142 case 63302: k = "~3"; break; // Ins
143 case 63272: k = "~4"; break; // Del
144 case 63236: k = "~a"; break; // F1
145 case 63237: k = "~b"; break; // F2
146 case 63238: k = "~c"; break; // F3
147 case 63239: k = "~d"; break; // F4
148 case 63240: k = "~e"; break; // F5
149 case 63241: k = "~f"; break; // F6
150 case 63242: k = "~g"; break; // F7
151 case 63243: k = "~h"; break; // F8
152 case 63244: k = "~i"; break; // F9
153 case 63245: k = "~j"; break; // F10
154 case 63246: k = "~k"; break; // F11
155 case 63247: k = "~l"; break; // F12
156 default: k = String.fromCharCode(kc); break;
157 }
158
Felix Meschberger96812952012-06-01 14:37:54 +0000159 var s = encodeURIComponent(k);
160
Felix Meschberger23756c82013-01-21 21:05:03 +0000161// debug("ev.keyCode=" + ev.keyCode + ", " +
Felix Meschberger97204d82012-01-31 12:47:45 +0000162// "ev.which=" + ev.which + ", ev.ctrlKey=" + ev.ctrlKey + ", " +
Felix Meschberger96812952012-06-01 14:37:54 +0000163// "kc=" + kc + ", k=" + k + ", s=" + s);
Felix Meschberger97204d82012-01-31 12:47:45 +0000164
Felix Meschberger96812952012-06-01 14:37:54 +0000165 queue(s);
Felix Meschberger97204d82012-01-31 12:47:45 +0000166
167 ev.cancelBubble = true;
168 if (ev.stopPropagation) ev.stopPropagation();
169 if (ev.preventDefault) ev.preventDefault();
170
171 return true;
172 }
173
Felix Meschberger96812952012-06-01 14:37:54 +0000174 function ignoreKey(ev) {
175 if (!ev) {
176 ev = window.event;
177 }
178
179 ev.cancelBubble = true;
180 if (ev.stopPropagation) ev.stopPropagation();
181 if (ev.preventDefault) ev.preventDefault();
182 }
Felix Meschberger97204d82012-01-31 12:47:45 +0000183
184 function init() {
185 if (typeof(XMLHttpRequest) == "undefined") {
186 XMLHttpRequest = function() {
187 try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
188 catch(e) {}
189 try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
190 catch(e) {}
191 try { return new ActiveXObject("Msxml2.XMLHTTP"); }
192 catch(e) {}
193 try { return new ActiveXObject("Microsoft.XMLHTTP"); }
194 catch(e) {}
195 throw new Error("This browser does not support XMLHttpRequest.");
196 };
197 }
Felix Meschberger96812952012-06-01 14:37:54 +0000198
Felix Meschberger97204d82012-01-31 12:47:45 +0000199 sled.appendChild(document.createTextNode('\xb7'));
200 sled.className = 'off';
201 dstat.appendChild(sled);
202 dstat.appendChild(document.createTextNode(' '));
Felix Meschberger96812952012-06-01 14:37:54 +0000203// dstat.appendChild(sdebug);
Felix Meschberger97204d82012-01-31 12:47:45 +0000204 dstat.className = 'stat';
Felix Meschberger96812952012-06-01 14:37:54 +0000205
Felix Meschberger97204d82012-01-31 12:47:45 +0000206 div.appendChild(dstat);
207 var d = document.createElement('div');
208 d.appendChild(dterm);
209 div.appendChild(d);
Felix Meschberger96812952012-06-01 14:37:54 +0000210
Felix Meschberger97204d82012-01-31 12:47:45 +0000211 document.onkeypress = keypress;
Felix Meschberger96812952012-06-01 14:37:54 +0000212 document.onkeyup = ignoreKey;
Felix Meschberger97204d82012-01-31 12:47:45 +0000213 timeout = window.setTimeout(update, 100);
214 }
215
216 init();
217
218}
219
220gogo.Terminal = function(div, width, height) {
221 return new this.Terminal_ctor(div, width, height);
222}
223