Contact: fumanchu@aminus.org

Log in as guest/misc to create tickets

root/httprepl.html

Revision 63 (checked in by fumanchu, 7 years ago)

httprepl: improved styling.

Line 
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2     "http://www.w3.org/TR/xhtml1/DTD/strict.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4 <head>
5     <title>CherryPy Terminal</title>
6
7 <style type='text/css'>
8
9 body {
10     margin: 0;
11     padding: 6px;
12 }
13
14 h1 {
15     font: 700 24pt Verdana, sans-serif;
16     margin-top: -6px;
17     margin-right: -6px;
18     margin-bottom: 6px;
19     margin-left: -6px;
20     padding: 0.5em;
21     background-color: #993333;
22     color: white;
23     border-bottom: 1px solid #330000;
24 }
25
26 #output pre {
27     font: 10pt monospace;
28     margin: 0;
29     padding: 1px;
30     border: 1px solid #E0E0FF;
31     background-color: #F8F8FF;
32    
33     white-space: -moz-pre-wrap; /* Mozilla, supported since 1999 */
34     white-space: -pre-wrap; /* Opera 4 - 6 */
35     white-space: -o-pre-wrap; /* Opera 7 */
36     white-space: pre-wrap; /* CSS3 - Text module (Candidate Recommendation)
37                             http://www.w3.org/TR/css3-text/#white-space */
38     word-wrap: break-word; /* IE 5.5+ */
39 }
40
41 #output pre.stdin {
42     border: none;
43     background-color: transparent;
44 }
45
46 form {
47     font: 10pt monospace;
48     margin: 0;
49 }
50
51 #input {
52     font: 10pt monospace;
53     width: 95%;
54     border-top: none;
55     border-right: 1px dotted #E0E0FF;
56     border-bottom: none;
57     border-left: 1px dotted #E0E0FF;
58 }
59
60 #tipbar {
61     position: fixed;
62     top: 10px;
63     right: 10px;
64     width: 50%;
65    
66     border: 2px outset #DDCCBB;
67     background-color: #FFEEDD;
68     font: 9pt monospace;
69    
70     margin: 0;
71     padding: 4px;
72    
73     white-space: -moz-pre-wrap; /* Mozilla, supported since 1999 */
74     white-space: -pre-wrap; /* Opera 4 - 6 */
75     white-space: -o-pre-wrap; /* Opera 7 */
76     white-space: pre-wrap; /* CSS3 - Text module (Candidate Recommendation)
77                             http://www.w3.org/TR/css3-text/#white-space */
78     word-wrap: break-word; /* IE 5.5+ */
79    
80     display: none;
81 }
82
83 #tipbar a {
84     padding: 4px;
85     text-decoration: none;
86     color: #666666;
87 }
88
89 </style>
90
91 <script type='text/javascript'>
92
93 function http() {
94     var h;
95     if (typeof(XMLHttpRequest) != "undefined") {
96         h = new XMLHttpRequest();
97     } else {
98         try { h = new ActiveXObject("Msxml2.XMLHTTP"); }
99         catch (e) {
100             try { h = new ActiveXObject("Microsoft.XMLHTTP"); }
101             catch (E) { alert("Your browser is not supported."); }
102         }
103     }
104     return h
105 }
106
107
108 //                           HISTORY NAVIGATION                           //
109
110 function use_history(elem) {
111     var content = get_text(elem);
112     // Strip the leading prompt
113     if (elem.className == 'stdin') content = content.substr(4);
114     input.value = content;
115     input.focus();
116 }
117
118 function history_hook() {
119     use_history(this);
120 }
121
122 var current_history = undefined;
123
124 function prev_history() {
125     if (current_history == undefined) {
126         var prev = document.getElementById("output").lastChild;
127     } else {
128         var prev = current_history.previousSibling;
129     }
130     while (prev != null && prev.className != 'stdin') {
131         prev = prev.previousSibling;
132     }
133     if (prev != null) {
134         current_history = prev;
135         use_history(prev);
136     }
137 }
138
139 function next_history() {
140     if (current_history == undefined) return;
141    
142     var next = current_history.nextSibling;
143     while (next != null && next.className != 'stdin') {
144         next = next.nextSibling;
145     }
146     if (next != null) {
147         current_history = next;
148         use_history(next);
149     }
150 }
151
152
153 //                            CODE COMPLETION                            //
154
155 current_range = undefined;
156
157 function partial_line() {
158     if (document.selection) {
159         // Internet Explorer
160         current_range = document.selection.createRange();
161         var end = current_range.getBookmark().charCodeAt(2) - 2;
162     } else {
163         var end = input.selectionEnd;
164     }
165     return input.value.substring(0, end);
166 }
167
168 function insert_text(newtext) {
169     if (document.selection) {
170         // Internet Explorer
171         current_range.text = newtext;
172         current_range.select();
173     } else {
174         var start = input.selectionStart;
175         input.value = input.value.substring(0, start) + newtext + input.value.substr(input.selectionEnd);
176         var end = start + newtext.length;
177         input.setSelectionRange(end, end);
178     }
179 }
180
181 function clear_tips() {
182     tipbar.style.display = '';
183     while (tipbar.hasChildNodes()) {
184         tipbar.removeChild(tipbar.lastChild);
185     }
186 }
187
188 function show_tips() {
189     tipbar.style.display = 'block';
190 }
191
192 var intip = false;
193
194 function use_tip() {
195     insert_text(get_text(this));
196     clear_tips();
197     intip = true;
198     input.focus();
199 }
200
201 function dir() {
202     var data = partial_line();
203    
204     clear_tips();
205    
206     var h = http();
207     h.onreadystatechange = function() {
208         if (h.readyState == 4) {
209             try {
210                 var status = h.status;
211             } catch(e) {
212                 var status = "NO HTTP RESPONSE";
213             }
214             switch (status) {
215                 case 200:
216                     var tips = eval(h.responseText);
217                     for (var i=0; i < tips.length; i++) {
218                         var tiplink = document.createElement("a");
219                         tiplink.onclick = use_tip;
220                         tiplink.href = "javascript:void(0)";
221                         set_text(tiplink, tips[i]);
222                         tipbar.appendChild(tiplink);
223                         tipbar.appendChild(document.createTextNode(" "));
224                     }
225                     show_tips()
226                     input.focus();
227                     break;
228                 // Internet Explorer might return 1223 for 204
229                 case 1223:
230                 case 204:
231                     // No tips available
232                     break;
233                 case 12029:
234                     // Internet Explorer client could not connect to server
235                     status = "NO HTTP RESPONSE";
236                 default:
237                     stdout_write(status + "\n" + h.responseText, false);
238             }
239         }
240     }
241     h.open("GET", "dir?line=" + escape(data), true);
242     h.send(null);
243 }
244
245 function doc() {
246     var data = partial_line();
247    
248     clear_tips();
249    
250     var h = http();
251     h.onreadystatechange = function() {
252         if (h.readyState == 4) {
253             try {
254                 var status = h.status;
255             } catch(e) {
256                 var status = "NO HTTP RESPONSE";
257             }
258             switch (status) {
259                 case 200:
260                     tipbar.appendChild(document.createTextNode(h.responseText));
261                     show_tips();
262                     input.focus();
263                     break;
264                 // Internet Explorer might return 1223 for 204
265                 case 1223:
266                 case 204:
267                     // No tips available
268                     break;
269                 case 12029:
270                     // Internet Explorer client could not connect to server
271                     status = "NO HTTP RESPONSE";
272                 default:
273                     stdout_write(status + "\n" + h.responseText, false);
274             }
275         }
276     }
277     h.open("GET", "doc?line=" + escape(data), true);
278     h.send(null);
279 }
280
281 //                           COMMAND EXECUTION                           //
282
283 function get_text(elem) {
284     if (elem.innerText != undefined) {
285         // Internet Explorer
286         return elem.innerText;
287     } else {
288         // Mozilla
289         return elem.textContent;
290     }
291 }
292
293 function set_text(elem, newvalue) {
294     if (elem.innerText != undefined) {
295         // Internet Explorer
296         elem.innerText = newvalue;
297     } else {
298         // Mozilla
299         elem.textContent = newvalue;
300     }
301 }
302
303 function get_prompt() {
304     return get_text(document.getElementById("prompt"));
305 }
306
307 function set_prompt(newvalue) {
308     var p = document.getElementById("prompt");
309     set_text(p, newvalue);
310 }
311
312 function stdout_write(content, stdin) {
313     current_history = undefined;
314     if (content == "") return;
315    
316     var block = document.createElement("pre");
317     block.ondblclick = history_hook;
318     if (stdin) {
319         content = get_prompt() + content;
320         block.className = 'stdin';
321     }
322     if (block.innerText != undefined) {
323         // Internet Explorer quirkiness
324         block.innerText = content;
325     } else {
326         block.appendChild(document.createTextNode(content));
327     }
328     output.appendChild(block);
329 }
330
331 whitespace = /^\s+$/;
332
333 function push() {
334     var data = input.value;
335     // Uncomment to treat a line with only whitespace like a blank line
336     // if (whitespace.test(data)) data = "";
337    
338     input.value = "";
339    
340     var h = http();
341     h.onreadystatechange = function() {
342         if (h.readyState == 4) {
343             stdout_write(data, true);
344             try {
345                 var status = h.status;
346             } catch(e) {
347                 var status = "NO HTTP RESPONSE";
348             }
349             switch (status) {
350                 case 200:
351                     set_prompt(">>> ");
352                     stdout_write(h.responseText, false);
353                     break;
354                 // Internet Explorer might return 1223 for 204
355                 case 1223:
356                 case 204:
357                     set_prompt("... ");
358                     // input.value *should* be blank, but just in case...
359                     input.value = "    " + input.value;
360                     break;
361                 case 12029:
362                     // Internet Explorer client could not connect to server
363                     status = "NO HTTP RESPONSE";
364                 default:
365                     stdout_write(status + "\n" + h.responseText, false);
366             }
367             input.focus();
368         }
369     }
370     h.open("POST", "push", true);
371     h.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
372     h.send("line=" + escape(data));
373 }
374
375 function escape(data) {
376     data = data.replace(/%/gi, "%25");
377     data = data.replace(/&/gi, "%26");
378     data = data.replace(/[+]/gi, "%2B");
379     data = data.replace(/;/gi, "%3B");
380     return data;
381 }
382
383
384 //                                 SETUP                                 //
385
386 function mapKeys(key_code) {
387     if (intip) {
388         intip = false;
389         // Trap the bubbling keyup event from a tiplink. This means that,
390         // if you actually click a tiplink instead of tab and hit 'enter',
391         // you have to hit 'enter' twice to push the line. :(
392         if (key_code == 13) return;
393     }
394     switch(key_code) {
395         case 8:    // backspace
396             clear_tips();
397             break;
398         case 13:   // enter
399             clear_tips();
400             push();
401             break;
402         case 38:   // up arrow
403             prev_history();
404             break;
405         case 40:   // down arrow
406             next_history();
407             break;
408         case 48:  // close paren "("
409             clear_tips();
410             break;
411         case 57:  // open paren "("
412             doc();
413             break;
414         case 190:  // period "."
415             dir();
416             break;
417     }
418 }
419
420 function trapKeys(e) {
421     if (!e) var e = window.event;
422     mapKeys(e.keyCode);
423 }
424
425 input = undefined;
426 output = undefined;
427 tipbar = undefined;
428
429 function init() {
430     input = document.getElementById("input");
431     input.onkeyup = trapKeys;
432     output = document.getElementById("output");
433     tipbar = document.getElementById("tipbar");
434     input.focus();
435 }
436
437 </script>
438 </head>
439
440 <body onload="init();">
441 <h1>CherryPy Terminal</h1>
442
443 <div id="output">
444 </div>
445
446 <form action="" id="terminal" onsubmit="return false;">
447 <div id='tipbar'></div>
448 <nobr><span id='prompt'>&gt;&gt;&gt; </span><input type="text" id="input"
449     size="60" /></nobr>
450 </form>
451
452 </body>
453 </html>
Note: See TracBrowser for help on using the browser.