Contact: fumanchu@aminus.org

Log in as guest/misc to create tickets

root/httprepl.html

Revision 121 (checked in by fumanchu, 6 years ago)

HTTPREPL: Improved overflow in tipbar, plus a CP 3 fix.

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