Contact: fumanchu@aminus.org

Log in as guest/misc to create tickets

root/okapi.html

Revision 175 (checked in by fumanchu, 2 years ago)

Okapi: Fixed some input color issues

  • Property svn:eol-style set to native
Line 
1 <!DOCTYPE html>
2 <html>
3 <head>
4     <title>Okapi API Browser</title>
5     <meta name="DC.Rights" content="http://svn.aminus.net/misc/license_bsd.txt">
6 <style>
7
8 * {
9     /* This is to work around W3C craziness with "standard" widths */
10     -moz-box-sizing: border-box;
11     -ms-box-sizing: border-box;
12 }
13
14 html, body {
15     margin: 0 !important;
16     padding: 0 !important;
17     font-family: Verdana, sans-serif;
18     height: 100%;
19     width: 100%;
20     text-align: left;
21 }
22
23 body { background: url('okapibg.png'); }
24
25 #lightbox {
26     display: none;
27     background-color: #332222;
28     height: 100%;
29     width: 100%;
30     opacity: 0.75;
31     position: absolute;
32     z-index: 5;
33 }
34
35 #grid {
36     border-collapse: collapse;
37     height: 100%;
38     border: 0;
39     margin: 0 !important;
40     padding: 0 !important;
41     width: 100%;
42 }
43
44 tr#addressbarrow, td#addressbarcell {
45     height: 1.5em;
46     border: 0;
47     margin: 0 !important;
48     padding: 0 !important;
49     width: 100%;
50     vertical-align: top;
51     background-color: transparent;
52 }
53
54 tr#messagebarrow, td#messagebarcell {
55     height: 1.5em;
56     border: 0;
57     margin: 0 !important;
58     padding: 0 !important;
59     width: 100%;
60     vertical-align: top;
61 }
62
63 tr#messagesrow, td#messagescell {
64     height: 100%;
65     border: 0;
66     margin: 0 !important;
67     padding: 0 !important;
68     width: 100%;
69     vertical-align: top;
70 }
71
72 /* ADDRESS BAR */
73
74 #addressbar {
75     color: black;
76     border: 0;
77     border-collapse: collapse;
78     width: 100%;
79     height: 1.5em;
80 }
81
82 #addressbar, #addressbar tr, #addressbar td {
83     margin: 0;
84     padding: 0;
85 }
86
87 #urilabel {
88     width: 3em;
89     white-space: nowrap;
90     margin: 0;
91     padding: 0;
92     background-color: white;
93 }
94
95 #urilabel a {
96     text-decoration: none;
97     color: black;
98 }
99
100 #urilabel a.disabled {
101     color: #999999;
102 }
103
104 #uribox {
105     border: 0;
106     background-color: white;
107 }
108
109 #uri {
110     width: 98%;
111     height: 90%;
112     border: 0;
113     margin-left: 0.5em;
114     color: black;
115     background-color: white;
116 }
117
118 #methodbox {
119     text-align: right;
120     height: 100%;
121     width: 14em;
122     padding: 0;
123     margin: 0;
124     white-space: nowrap;
125 }
126
127 input.button {
128     margin: 0;
129     padding: 0 0.1em 0 0.1em;
130     border: 0;
131     height: 100%;
132     cursor: pointer;
133 }
134
135 #methodbox input.button {
136     background-color: transparent;
137     color: white;
138 }
139
140 #methodbox input.selected {
141     background-color: transparent;
142 }
143
144 /* MESSAGE BAR */
145
146 #messagebar {
147     background-color: transparent;
148     border-collapse: collapse;
149     color: white;
150     margin: 0;
151     padding: 0;
152     height: 1.5em;
153     width: 100%;
154 }
155
156 #messagebar input.button {
157     background-color: white;
158     margin-right: 1px;
159     color: #280000;
160 }
161
162 #messagebar tr, #messagebar td {
163     margin: 0;
164     padding: 0;
165     height: 1.5em;
166     border: 0;
167 }
168
169 #requestlabel {
170     width: 6em;
171 }
172
173 #other_actions {
174     text-align: center;
175 }
176
177 #response_actions {
178     text-align: right;
179 }
180
181 #responselabel {
182     width: 6em;
183     text-align: right;
184 }
185
186
187 /* MESSAGES */
188
189 #messages {
190     border-collapse: collapse;
191     margin: 0;
192     padding: 0;
193     border: 0;
194     /* Somehow this fixes extraneous viewport scrollbars in FF */
195     overflow: hidden;
196 }
197
198 #messages tbody, #messages tr, #messages td {
199     margin: 0;
200     padding: 0;
201     border: 0;
202 }
203
204 #messages, #messages tbody, #messages tr {
205     height: 100%;
206     width: 100%;
207 }
208
209 #messages td {
210     height: 100%;
211     width: 50%;
212 }
213
214 #messages td#responsebox {
215     background-color: transparent;
216     color: white;
217     border-left: 2px dotted #331111 !important;
218 }
219
220 /* HEADER MENUS */
221
222 .header_table_envelope {
223     /* display: none; */
224     border-bottom: 2px dotted #331111;
225     width: 100%;
226     height: 25%;
227     margin-top: 0.25em;
228     vertical-align: top;
229     overflow-y: auto;
230 }
231
232 .header_table {
233     border: 0;
234     border-collapse: collapse;
235     width: 100%;
236     vertical-align: top;
237     margin: 0;
238 }
239
240 .header_table tr, .header_table td, .header_table th {
241     padding: 0 0.25em 0 0.25em !important;
242     margin: 0;
243     vertical-align: top;
244 }
245
246 .header_table input.text {
247     width: 100%;
248     font: normal 10pt "Lucida Console", Courier, monospace;
249     border: 0;
250     margin: 0;
251     color: black;
252     background-color: white;
253 }
254
255 #requestbox {
256     background-color: white;
257 }
258
259 #request_headers input.button {
260     background-color: white;
261     height: 1em;
262 }
263
264 #response_headers input.text {
265     background-color: transparent;
266     color: white;
267 }
268
269 #responsebox > div.header_table_envelope {
270     border-bottom: 2px dotted white;
271 }
272
273
274 /* MESSAGE BODIES */
275
276 #request, #response {
277     height: 74%;
278     width: 100%;
279     padding: 0 0 0 0.5em;
280     display: block;
281     border: 0;
282     font: normal 10pt "Lucida Console", Courier, monospace;
283 }
284
285 #request {
286     color: black;
287     background-color: white;
288 }
289
290 #response {
291     background-color: transparent;
292     color: white;
293 }
294
295 #render_overlay {
296     display: none;
297     position: absolute;
298     height: 80%;
299     width: 80%;
300     top: 3em;
301     right: 10%;
302     background-color: #442222;
303     color: white;
304     border: 4px solid #996666;
305     z-index: 7;
306 }
307
308 #render_close {
309     float: right;
310     margin: 1em;
311     cursor: pointer;
312 }
313
314 #render_overlay p {
315     padding: 0.5em;
316     height: 1.5em;
317 }
318
319 #render_iframe {
320     height: 80%;
321     width: 100%;
322     background-color: white;
323     border-color: #442222;
324 }
325
326 </style>
327
328 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
329 <script type="text/javascript">
330
331 function set(a) {
332     // Convert the given array into a set.
333     var o = {};
334     for (var i=0; i < a.length; i++) o[a[i]] = '';
335     return o;
336 }
337
338 function sanitize (s) {
339     // Sanitize HTML values in the given string.
340     return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
341 }
342
343 function stripws(s) {
344     return s.replace(/(^\s+)|(\s+$)/g, "");
345 }
346
347 function make_header_row(cls, k, v) {
348     return ("<tr class='" + cls + "_header_row'>" +
349             "<td><input type='text' class='text' value='" + k + "'></td>" +
350             "<td><input type='text' class='text' value='" + stripws(v) + "'></td></tr>");
351 }
352
353 function highlight_method(method) {
354     $("#methodbox input").removeClass("selected");
355     var target = $("#methodbox input#do" + method)
356     if (target.length) {
357         target.addClass("selected");
358     } else {
359         target = $("#methodbox input#doCustom");
360         target.addClass("selected");
361         target.title = method;
362     }
363 }
364
365 var okapi_history = [];
366 var okapi_history_pointer = -1;
367
368 var HistoryItem = function (uri, method, request_headers, request_body,
369                             response_headers, response_body) {
370     this.uri = uri;
371     this.method = method;
372     this.request_headers = request_headers;
373     this.request_body = request_body;
374     this.response_headers = response_headers;
375     this.response_body = response_body;
376 };
377
378 function make_request(uri, method, body) {
379     if (method == null) method = 'GET';
380     highlight_method(method);
381    
382     var request_headers = [];
383    
384     function ajax_before_send (XMLHttpRequest) {
385         $("#request_headers tr.request_header_row").each(
386             function (i) {
387                 var row = $(this);
388                 var key = row.find("td:first > input").val();
389                 var value = row.find("td:last > input").val();
390                 if (key != null && key != '' && value != null && value != '') {
391                     request_headers.push([key, value]);
392                     XMLHttpRequest.setRequestHeader(key, value);
393                 } else {
394                     row.remove();
395                 }
396             }
397         );
398     }
399    
400     function ajax_error (XMLHttpRequest, textStatus, errorThrown) {
401         ajax_success(XMLHttpRequest.responseText, textStatus);
402     }
403    
404     function ajax_success(data, textStatus) {
405         var response_headers = [];
406        
407         // Response body
408         $("#response").val(data);
409        
410         // Headers
411         var headers = $("#response_headers > tbody");
412         headers.empty();
413        
414         // Status "header"
415         var k = 'Status "header"';
416         var v = sanitize(xhr.status.toString() + ' ' + xhr.statusText);
417         headers.append(make_header_row('response', k, v));
418         response_headers.push([k, v]);
419        
420         // Real headers
421         var lines = xhr.getAllResponseHeaders().split("\n");
422         for (var i=0; i < lines.length; i++) {
423             var line = lines[i].replace('\r', '');
424             if (line.length != 0) {
425                 // TODO: sanitize quote marks
426                 var atoms = sanitize(line).match(/^([^\:]+)\: ?(.+)$/);
427                 if (atoms != null) {
428                     var k = atoms[1], v = atoms[2];
429                     headers.append(make_header_row('response', k, v));
430                     response_headers.push([atoms[1], atoms[2]]);
431                 }
432             }
433         }
434        
435         // History
436         // First, slice off any 'Forward' entries
437         okapi_history = okapi_history.slice(0, okapi_history_pointer + 1);
438         // Then, add our new entry
439         okapi_history.push(new HistoryItem(uri, method, request_headers, body, response_headers, data));
440         okapi_history_pointer = okapi_history_pointer + 1;
441         sync_history_buttons();
442     }
443    
444     // It is STRONGLY recommended you change your server to issue 307
445     // when redirecting PUT/POST/DELETE; otherwise (with 301/302/303),
446     // Firefox, and maybe others, will automatically redirect PUT to GET.
447     var xhr = jQuery.ajax({type: method, url: uri,
448                            data: body,
449                            processData: false,
450                            dataType: 'text',
451                            beforeSend: ajax_before_send,
452                            error: ajax_error, success: ajax_success});
453 }
454
455 function render_response() {
456     if (window.frames['render_iframe']) {
457         // IE
458         var fd = window.frames['render_iframe'].document;
459     } else {
460         var fd = document.getElementById('render_iframe').contentWindow.document;
461     }
462    
463     var ct = get_response_header('Content-Type');
464     var data = $("#response").val();
465    
466     var render_mode = $("input[@name=render_mode]:checked").val();
467     if (render_mode == 'document_write') {
468         fd.open();
469         fd.write(data);
470         fd.close();
471     } else if (render_mode == 'inner_html') {
472         fd.body.innerHTML = data;
473     } else if (render_mode == 'data_url') {
474         fd.location = 'data:' + ct + ',' + encodeURIComponent(data);
475     }
476 }
477
478 function toggle_render_response() {
479     var bg = $('#lightbox');
480     var f = $('#render_overlay');
481     if (f.css('display') == 'none') {
482         render_response();
483         f.fadeIn(500);
484         bg.fadeIn(500);
485     } else {
486         f.fadeOut(500);
487         bg.fadeOut(500);
488     }
489 }
490
491 known_methods = {
492     "GET": {safe: true, body: false},
493     "HEAD": {safe: true, body: false},
494     "PUT": {safe: false, body: true},
495     "POST": {safe: false, body: true},
496     "DELETE": {safe: false, body: false}
497 }
498
499 function do_method(method) {
500     if (method in known_methods) {
501         var body = (known_methods[method].body) ? $('#request').val() : null;
502         make_request($('#uri').val(), method, body);
503     }
504     return false;
505 }
506
507 function custom_method() {
508     var method = prompt("HTTP method");
509     var body = prompt("Include a request body?");
510     var body = (body.toLowerCase().charAt(0) == 'y') ? $('#request').val() : null;
511     make_request($('#uri').val(), method, body);
512     return false;
513 }
514
515 function get_response_header(name) {
516     name = name.toLowerCase();
517     var result = null;
518     $("#response_headers tr.response_header_row").each(
519         function (i) {
520             var row = $(this);
521             var key = row.find("td:first > input").val();
522             if (key != null && key.toLowerCase() == name) {
523                 var value = row.find("td:last > input").val();
524                 if (value != null) {
525                     result = value;
526                     // Stop the callback loop.
527                     return false;
528                 }
529             }
530         }
531     );
532     return result;
533 }
534
535 function set_request_header(name, value) {
536     var found = false;
537     var lowname = name.toLowerCase();
538     $("#request_headers tr.request_header_row").each(
539         function (i) {
540             var row = $(this);
541             var key = row.find("td:first > input").val();
542             if (key != null && key.toLowerCase() == lowname) {
543                 row.find("td:last > input").val(value);
544                 found = true;
545                 // Stop the callback loop.
546                 return false;
547             }
548         }
549     );
550     if (!found) add_request_header(name, value);
551 }
552
553 function Copy_click() {
554     $('#request').val($('#response').val());
555     var ct = get_response_header('Content-Type');
556     if (ct != null) set_request_header('Content-Type', ct);
557     return false;
558 }
559
560 function URI_keypress(e) {
561     if (!e) var e = window.event;
562     if (e.keyCode) { code = e.keyCode; }
563     else { if (e.which) code = e.which; }
564     if (code == 13) return do_method('GET');
565 }
566
567 function toggle_header_menu(pane) {
568     var headers = jQuery('#' + pane + '_headers').parent('div');
569     var body = jQuery('#' + pane);
570     if (headers.css('display') == 'none') {
571         body.css('height', '75%');
572         headers.fadeIn(250);
573     } else {
574         headers.fadeOut(250);
575         body.css('height', '100%');
576     }
577 }
578
579 function add_request_header(name, value) {
580     // TODO: sanitize quote marks
581     if (name == null) name = 'Content-Type';
582     if (value == null) value = 'application/json';
583     var headers = $("#request_headers > tbody");
584     headers.append(make_header_row('request', name, value));
585 }
586
587 function sync_history_buttons() {
588     if (okapi_history_pointer > 0) {
589         $('#back').removeClass('disabled');
590     } else {
591         $('#back').addClass('disabled');
592     }
593     if (okapi_history_pointer < (okapi_history.length - 1)) {
594         $('#forward').removeClass('disabled');
595     } else {
596         $('#forward').addClass('disabled');
597     }
598 }
599
600 function restore_history(hist) {
601     $('#uri').val(hist.uri);
602    
603     highlight_method(hist.method);
604    
605     var headers = $("#request_headers > tbody");
606     headers.empty();
607     for (var i in hist.request_headers) {
608         var h = hist.request_headers[i];
609         headers.append(make_header_row('request', h[0], h[1]));
610     }
611     $('#request').val(hist.request_body);
612    
613     var headers = $("#response_headers > tbody");
614     headers.empty();
615     for (var i in hist.response_headers) {
616         var h = hist.response_headers[i];
617         headers.append(make_header_row('response', h[0], h[1]));
618     }
619     $('#response').val(hist.response_body);
620 }
621
622 function go_back() {
623     if (okapi_history_pointer > 0) {
624         okapi_history_pointer = okapi_history_pointer - 1;
625         var hist = okapi_history[okapi_history_pointer];
626         restore_history(hist);
627         sync_history_buttons();
628     }
629 }
630
631 function go_forward() {
632     if (okapi_history_pointer < (okapi_history.length - 1)) {
633         okapi_history_pointer = okapi_history_pointer + 1;
634         var hist = okapi_history[okapi_history_pointer];
635         restore_history(hist);
636         sync_history_buttons();
637     }
638 }
639
640 </script>
641 </head>
642
643 <body>
644 <div id='lightbox'></div>
645 <table id='grid'>
646 <tr id='addressbarrow'><td id='addressbarcell'>
647     <table id='addressbar'>
648     <tr>
649         <th id='urilabel'><a
650             id='back' class='disabled' href='#' onClick='go_back();'>&#x25C0;</a><a
651             id='forward' class='disabled' href='#' onClick='go_forward();'>&#x25B6;</a>URI</th>
652         <td id='uribox'><input id='uri' name='uri' type='text' class='text' size='0'
653             onKeyPress='URI_keypress(event)'></td>
654         <td id='methodbox'><input
655             id='doGET' type='button' class='button' value='GET' onClick='do_method("GET");'><input
656             id='doHEAD' type='button' class='button' value='HEAD' onClick='do_method("HEAD");'><input
657             id='doPUT' type='button' class='button' value='PUT' onClick='do_method("PUT");'><input
658             id='doPOST' type='button' class='button' value='POST' onClick='do_method("POST");'><input
659             id='doDELETE' type='button' class='button' value='DELETE' onClick='do_method("DELETE");'><input
660             id='doCustom' type='button' class='button' value='Custom' onClick='custom_method();'>
661         </td>
662     </tr>
663     </table>
664 </td></tr>
665 <tr id='messagebarrow'><td id='messagebarcell'>
666     <table id='messagebar'>
667     <tr>
668         <th id='requestlabel'>Request</th>
669         <td id='request_actions'><input
670             id='request_header_toggle' type='button' class='button' value='&#x25BC; Headers &#x25BC;'
671             onClick='toggle_header_menu("request")'></td>
672         <td id='other_actions'><input
673             id='copy' type='button' class='button' value='&#x25C0; Copy &#x25C0;'
674             onClick='Copy_click();'></td>
675         <td id='response_actions'><input
676             id='render_response_toggle' type='button' class='button' value='Render'
677             onClick='toggle_render_response()'><input
678             id='response_header_toggle' type='button' class='button' value='&#x25BC; Headers &#x25BC;'
679             onClick='toggle_header_menu("response")'></td>
680         <th id='responselabel'>Response</th>
681     </tr>
682     </table>
683 </td></tr>
684 <tr id='messagesrow'><td id='messagescell'>
685     <table id='messages'>
686     <tr>
687         <div id='render_overlay'><div
688             id='render_close' onClick='toggle_render_response()'>X</div><p
689             id='render_options'>Render mode: <input checked='checked'
690                 id='render_document_write' type='radio' name='render_mode'
691                 value='document_write' onClick='render_response()'><label
692                 for='render_document_write'>document.write</label><input
693                 id='render_data_url' type='radio' name='render_mode'
694                 value='data_url' onClick='render_response()'><label
695                 for='render_data_url'>data:</label><input
696                 id='render_inner_html' type='radio' name='render_mode'
697                 value='inner_html' onClick='render_response()'><label
698                 for='render_inner_html'>innerHTML</label></p><iframe
699             id='render_iframe' src=''></iframe></div>
700         <td id='requestbox'><div class='header_table_envelope'><table
701             id='request_headers' class='header_table'>
702             <thead>
703                 <tr><th>Header Name <input type='button' class='button'
704                     id='add_request_header_button' value='+'
705                     onClick='add_request_header();'></th><th>Value</th></tr>
706             </thead>
707             <tbody>
708             <tr class='request_header_row'><td><input type='text' class='text' value='Content-Type'></td>
709                 <td><input type='text' class='text' value='application/json'></td></tr>
710             </tbody></table></div><textarea id='request' name='request'></textarea></td>
711         <td id='responsebox'><div class='header_table_envelope'><table
712             id='response_headers' class='header_table'>
713             <thead><tr><th>Header Name</th><th>Value</th></tr></thead>
714             <tbody></tbody></table></div><textarea id='response' name='response'></textarea></td>
715     </tr>
716     </table>
717 </td></tr>
718 </table>
719 </body>
720 </html>
Note: See TracBrowser for help on using the browser.