Contact: fumanchu@aminus.org

Log in as guest/misc to create tickets

root/httprepl.html

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

httprepl: New calltips and attr tips, plus re-org to allow for use with other frameworks.

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