Contact: fumanchu@aminus.org

Log in as guest/misc to create tickets

root/httpdrop/httpdrop.html

Revision 123 (checked in by fumanchu, 5 years ago)

Added an anchor tag around the filename label. This allows users to right-click and "save as..." in most browsers instead of always having to open the resource.

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>HTTP Drop Box</title>
6     <script src='ajax.js' type='text/javascript'></script>
7
8 <style type='text/css'>
9
10 body {
11     margin: 0;
12     padding: 0;
13     font: normal 10pt Arial, sans-serif;
14 }
15
16 #header {
17     margin: 0;
18     padding: 0.5em;
19     background-color: #333399;
20     color: white;
21     border-bottom: 1px solid #330000;
22 }
23
24 #header h1 {
25     margin: 0;
26     padding: 0;
27     font: 700 24pt Verdana, sans-serif;
28 }
29
30 #header p {
31     margin: 0;
32     padding: 0;
33 }
34
35 .tools {
36     font: normal 10pt Arial, sans-serif;
37     float: right;
38     margin: 0.25em;
39     padding: 3px 1em;
40     border-left: 1px solid #9999CC;
41     text-align: right;
42 }
43
44 form#upload {
45     padding: 0;
46     margin: 0;
47     display: inline;
48 }
49
50
51 /* ----------------- Tree styles ----------------- */
52
53 #tree {
54     float: left;
55     width: 25%;
56     overflow: auto;
57     background-color: #F8F8FF;
58 }
59
60 table {
61     border-collapse: collapse;
62 }
63
64 td {
65     vertical-align: middle;
66 }
67
68 .expander {
69     vertical-align: top;
70 }
71
72 .expander span {
73     cursor: pointer;
74     cursor: hand;
75 }
76
77 .branch {
78     margin: 0;
79     padding: 0;
80     width: 100%;
81 }
82
83 #sel_branch {
84     border: 1px dotted #999999;
85 }
86
87 .branch p {
88     margin: 0;
89     padding: 1px;
90     cursor: pointer;
91     cursor: hand;
92     border: 1px solid #F8F8FF;
93 }
94
95
96 /* ----------------- Box styles ----------------- */
97
98 #box {
99     float: right;
100     width: 70%;
101     overflow: auto;
102     border-left: 3px double #999999;
103     padding: 0;
104     margin: 0;
105 }
106
107 #box h4 {
108     text-align: right;
109     margin: 0;
110     padding: 5px;
111     border-bottom: 1px solid #CCCCFF;
112 }
113
114 .fileitem {
115     float: left;
116     margin: 10px;
117     padding: 4px;
118     width: 100px;
119     height: 100px;
120     overflow: auto;
121     text-align: center;
122     vertical-align: bottom;
123     border: 1px solid white;
124 }
125
126 #sel_file {
127     border: 1px dotted #999999;
128 }
129
130 .fileitem img {
131     margin: 0;
132     padding: 0;
133 }
134
135 .fileitem p {
136     margin: 0;
137     padding: 0;
138 }
139
140 </style>
141
142 <!--[if IE]>
143 <style type='text/css'>
144 .fileitem p {
145     word-wrap: break-word;
146 }
147 </style>
148 <![endif]-->
149
150 <script type='text/javascript'>
151
152 function find_children(obj, tagname, classname) {
153     var matches = new Array();
154     var children = obj.getElementsByTagName(tagname);
155     for (var i=0; i < children.length; i++) {
156         var child = children[i];
157         if (typeof(classname) == 'undefined' || classname == child.className)
158             matches[matches.length] = child;
159     }
160     return matches;
161 }
162
163
164 //                              TREE EVENTS                              //
165
166
167 function get_folder(path, dirs) {
168     var topnode = document.createElement("table");
169     // Internet Explorer requires a tbody element
170     var tb = document.createElement("tbody");
171     for (i = 0; i < dirs.length; i++) {
172         var dir = dirs[i];
173         var row = document.createElement("tr");
174         row.className = "dir";
175        
176         // Make a cell with an expander button
177         var cell = document.createElement("td");
178         cell.className = "expander";
179         var expander = document.createElement("span");
180         expander.onclick = expander_on_click;
181         expander.appendChild(document.createTextNode("+"));
182         cell.appendChild(expander);
183         row.appendChild(cell);
184        
185         // Make a cell with an icon and the name of the dir
186         cell = document.createElement("td");
187         cell.className = "branch";
188         cell.name = path + dir + '/';
189        
190         var content = document.createElement("p");
191         content.className = "dirname";
192         content.onclick = dir_onclick_event;
193        
194         // Folder icon
195         var icon = document.createElement("img");
196         icon.src = "icons/folder.gif";
197         content.appendChild(icon);
198        
199         // Folder name
200         content.appendChild(document.createTextNode(dir));
201         cell.appendChild(content);
202         row.appendChild(cell);
203        
204         tb.appendChild(row);
205     }
206     topnode.appendChild(tb);
207     return topnode;
208 }
209
210 function expander_on_click(event) {
211     var cell = this.parentNode.nextSibling;
212    
213     // Firefox has an extra #text node in-between the two TD nodes
214     if (cell.tagName == undefined) cell = cell.nextSibling;
215    
216     toggle_branch(cell);
217 }
218
219 function toggle_branch(cell) {
220     var innertable = cell.getElementsByTagName("table");
221     if (innertable.length == 0) {
222         fetch_branch(cell);
223     } else {
224         if (innertable[0].style.display == 'none') {
225             innertable[0].style.display = 'block';
226         } else {
227             innertable[0].style.display = 'none';
228         }
229     }
230 }
231
232 function fetch_branch(cell) {
233     set_status("Fetching subfolders...");
234     function insert_branch(jsondoc) {
235         cell.appendChild(get_folder(cell.name, eval(jsondoc)));
236         set_status("&nbsp;");
237     }
238     var h = http_action(insert_branch);
239     h.open("GET", "dirs?path=" + cell.name, true);
240     h.setRequestHeader("Accept", "application/x-json");
241     h.send(null);
242 }
243
244 function dir_onclick_event(event) {
245     select_dir(this);
246     fill_box(this.parentNode.name);
247 }
248
249 function select_dir(target) {
250     var cells = find_children(document, "p", "dirname");
251     for (var i = 0; i < cells.length; i++) {
252         var s = cells[i];
253         if (s == target) {
254             s.id = 'sel_branch';
255         } else {
256             s.id = null;
257         }
258     }
259 }
260
261
262 //                              BOX EVENTS                              //
263
264
265 var known_filetypes = new Array("css", "gif", "jpeg", "jpg", "htm", "html", "pdf");
266
267 function filetype(filename) {
268     // If the given filename has a known file extension, return it (else "unknown")
269     var dotpos = filename.lastIndexOf(".");
270     if (dotpos != -1) {
271         var ext = filename.substr(dotpos + 1).toLowerCase();
272         for (var j = 0; j < known_filetypes.length; j++) {
273             if (known_filetypes[j] == ext) return ext;
274         }
275     }
276     return "unknown";
277 }
278
279 function fileitem_on_dblclick() {
280     window.open("root/" + this.name, "_blank");
281 }
282
283 function _fill_box(path, files) {
284     var box = document.getElementById("box");
285     box.innerHTML = "";
286     box.name = path;
287     document.getElementById("path").value = path;
288    
289     var boxhead = document.createElement("h4");
290     boxhead.id = "boxhead";
291     boxhead.appendChild(document.createTextNode(files.length + " files"));
292     box.appendChild(boxhead);
293    
294     for (var i = 0; i < files.length; i++) {
295         var filename = files[i];
296        
297         var item = document.createElement("div");
298         item.className = "fileitem";
299         item.onmousedown = select_file;
300         item.name = path + filename;
301         item.ondblclick = fileitem_on_dblclick;
302        
303         // Icon
304         var icon = document.createElement("img");
305         icon.src = "icons/" + filetype(filename) + ".gif";
306         icon.className = "icon";
307         item.appendChild(icon);
308        
309         // Label (filename with link)
310         var p = document.createElement("p");
311         item.appendChild(p);
312         var a = document.createElement("a");
313         a.appendChild(document.createTextNode(filename));
314         a.href= "root/" + item.name;
315         p.appendChild(a);
316        
317         box.appendChild(item);
318     }
319 }
320
321 function fill_box(path) {
322     set_status("Fetching folder contents...");
323     function show_folder(jsondoc) {
324         _fill_box(path, eval(jsondoc));
325         set_status("&nbsp;");
326     }
327     var h = http_action(show_folder);
328     h.open("GET", "files?path=" + path, true);
329     h.setRequestHeader("Accept", "application/x-json");
330     h.send(null);
331 }
332
333 //---------------------------- DRAG and DROP ----------------------------//
334
335 var draggedobj = null;
336 var placeholder = null;
337
338 // These offsets represent the distance between the top left corner
339 // of draggedobj and the mouse position "inside" draggedobj.
340 var cursor_offset_x = 0;
341 var cursor_offset_y = 0;
342
343 function abs_offset(obj) {
344     // Return the [x, y] offset of 'obj' and all its offsetParents.
345     // This should the [x, y] of the object relative to the document origin.
346     var x = obj.offsetLeft;
347     var y = obj.offsetTop;
348     var p = obj.offsetParent;
349     while (p != null) {
350         x += p.offsetLeft;
351         y += p.offsetTop;
352         p = p.offsetParent;
353     }
354     return [x, y];
355 }
356
357 function getScrollXY() {
358   var scrOfX = 0, scrOfY = 0;
359   if( typeof( window.pageYOffset ) == 'number' ) {
360     //Netscape compliant
361     scrOfY = window.pageYOffset;
362     scrOfX = window.pageXOffset;
363   } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
364     //DOM compliant
365     scrOfY = document.body.scrollTop;
366     scrOfX = document.body.scrollLeft;
367   } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
368     //IE6 standards compliant mode
369     scrOfY = document.documentElement.scrollTop;
370     scrOfX = document.documentElement.scrollLeft;
371   }
372   return [ scrOfX, scrOfY ];
373 }
374
375 function mouse_offset(event) {
376     var scrollxy = getScrollXY();
377     // Return the [x, y] offset of the mouse relative to the document origin.
378     var x = event.clientX + scrollxy[0];
379     var y = event.clientY + scrollxy[1];
380     return [x, y];
381 }
382
383 function select_file(event) {
384     if (!event) var event = window.event;
385    
386     // Clear the previous selection (if any)
387     var sf = document.getElementById("sel_file")
388     if (sf) sf.id = null;
389    
390     this.id = "sel_file";
391    
392     var xy = abs_offset(this);
393     var mousexy = mouse_offset(event);
394     cursor_offset_x = mousexy[0] - xy[0];
395     cursor_offset_y = mousexy[1] - xy[1];
396    
397     document.onmousemove = drag;
398     document.onmouseup = drop;
399    
400     return false;
401 }
402
403 function drag(event) {
404     if (!event) var event = window.event;
405     if (draggedobj == null) {
406         // This is where we actually start dragging
407         draggedobj = document.getElementById("sel_file");
408        
409         placeholder = draggedobj.cloneNode(true);
410         placeholder.id = "placeholder";
411         draggedobj.parentNode.insertBefore(placeholder, draggedobj);
412        
413         draggedobj.style.position = "absolute";
414         draggedobj.style.zIndex = 10;
415     }
416    
417     var mousexy = mouse_offset(event);
418     draggedobj.style.left = (mousexy[0] - cursor_offset_x) + "px";
419     draggedobj.style.top = (mousexy[1] - cursor_offset_y) + "px";
420    
421     // Scroll as needed
422     var scrollX = 0;
423     var scrollY = 0;
424     if (event.clientX < 20) scrollX = event.clientX - 20;
425     if (event.clientY < 20) scrollY = event.clientY - 20;
426     if (scrollX != 0 || scrollY != 0) window.scrollBy(scrollX, scrollY);
427    
428     highlight_dir(droptarget(event));
429     return false;
430 }
431
432 function move_sel_file(dirname) {
433     var sel_file = document.getElementById("sel_file");
434     var oldname = find_children(sel_file, "p")[0].innerHTML;
435    
436     set_status("Moving '" + oldname + "' to " + dirname + "...");
437    
438     function cleanup(xmldoc) {
439         remove_fileitem(sel_file);
440         highlight_dir(null);
441         draggedobj = null;
442         set_status("&nbsp;");
443     }
444     var h = http_action(cleanup);
445     h.open("POST", "move?oldname=" + sel_file.name + "&newname=" + dirname + oldname, true);
446     h.setRequestHeader("Content-Length", "0");
447     h.send("");
448 }
449
450 function drop(event) {
451     if (!event) var event = window.event;
452    
453     document.onmousemove = null;
454     document.onmouseup = null;
455    
456     if (draggedobj) {
457         var dt = droptarget(event);
458         if (dt == null) {
459             highlight_dir(null);
460             draggedobj.style.zIndex = 0;
461             draggedobj.style.position = "relative";
462             draggedobj.style.left = 0;
463             draggedobj.style.top = 0;
464             draggedobj = null;
465         } else {
466             move_sel_file(dt.parentNode.name);
467             // draggedobj will be set to null in move()
468         }
469         placeholder.parentNode.removeChild(placeholder);
470     }
471 }
472
473 function droptarget(event) {
474     var mousexy = mouse_offset(event);
475    
476     var cells = find_children(document, "p", "dirname");
477     for (var i = 0; i < cells.length; i++) {
478         var s = cells[i];
479         if (s != draggedobj) {
480             var xy = abs_offset(s);
481             if (mousexy[1] <= xy[1] + s.offsetHeight &&
482                 mousexy[0] <= xy[0] + s.offsetWidth) {
483                 return s;
484             }
485         }
486     }
487     return null;
488 }
489
490 function highlight_dir(target) {
491     var cells = find_children(document, "p", "dirname");
492     for (var i = 0; i < cells.length; i++) {
493         var s = cells[i];
494         if (s == target) {
495             s.style.backgroundColor = '#DDDDFF';
496         } else {
497             s.style.backgroundColor = 'transparent';
498         }
499     }
500 }
501
502 //                            SETUP AND TOOLS                            //
503
504 function init() {
505     set_status("Fetching folder list...");
506     var path = get_params()['path'] || "/";
507    
508     // Insert the first level of subfolders
509     var rootnode = document.getElementById("rootnode");
510     rootnode.onclick = dir_onclick_event;
511     rootnode.parentNode.name = "/";
512     function insert_branch(jsondoc) {
513         var newtable = get_folder("/", eval(jsondoc));
514         rootnode.parentNode.appendChild(newtable);
515         descend(path);
516         set_status("&nbsp;");
517     }
518     var h = http_action(insert_branch);
519     h.open("GET", "dirs?path=/", true);
520     h.setRequestHeader("Accept", "application/x-json");
521     h.send(null);
522    
523     fill_box(path);
524 }
525
526 function get_params() {
527     var map = new Object;
528     var params = window.location.search;
529     if (params) {
530         params = params.substr(1);
531         params = params.split("&");
532         for (var i = 0; i < params.length; i++) {
533             var pair = params[i].split("=");
534             map[pair[0]] = pair[1];
535         }
536     }
537     return map;
538 }
539
540 function descend(path) {
541     // Descend to a subfolder if requested via ?path=/a/b/c/
542     // This doesn't currently work for more than one subfolder because
543     // the inner loop doesn't wait for the async toggle_branch to finish.
544     // (The file box will be accurate, but not the tree).
545     var curnode = document.getElementById("rootnode").parentNode;
546     path = path.split("/");
547     var tpath = "/";
548     for (var i = 0; i < path.length; i++) {
549         var atom = path[i];
550         if (atom) {
551             tpath += atom + "/";
552             var children = curnode.getElementsByTagName("td");
553             for (var j = 0; j < children.length; j++) {
554                 var child = children[j];
555                 if (child.className == "branch" && child.name == tpath) {
556                     toggle_branch(child);
557                     curnode = child;
558                     break;
559                 }
560             }
561         }
562     }
563 }
564
565 function set_status(msg) {
566     document.getElementById("status").innerHTML = msg;
567 }
568
569 function verify_upload() {
570     var payload = document.getElementById("payload").value;
571     if (payload == '') {
572         alert("You must first select a file to upload.");
573         return false;
574     }
575     return true;
576 }
577
578 function remove_fileitem(obj) {
579     var box = document.getElementById("box");
580     box.removeChild(obj);
581     var numfiles = find_children(box, "div", "fileitem");
582     document.getElementById("boxhead").innerHTML = numfiles.length + " files";
583 }
584
585 function delete_sel_file() {
586     var sel_file = document.getElementById("sel_file");
587     if (sel_file) {
588         var msg = "Are you sure you want to delete " + sel_file.name + "?";
589         if (!confirm(msg)) return false;
590        
591         set_status("Deleting " + sel_file.name + "...");
592         function remove_obj(xmldoc) {
593             remove_fileitem(sel_file);
594             set_status("&nbsp;");
595         }
596         var h = http_action(remove_obj);
597         h.open("POST", "delete?path=" + sel_file.name, true);
598         h.setRequestHeader("Content-Length", "0");
599         h.send("");
600     }
601 }
602
603 function rename_on_click() {
604     var boxname = document.getElementById("box").name;
605     var sel_file = document.getElementById("sel_file");
606     var filep = find_children(sel_file, "p")[0]
607     var oldname = filep.innerHTML;
608    
609     var newname = prompt("Enter the new filename for '" + oldname + "'", oldname);
610     if (!newname) return false;
611    
612     set_status("Renaming '" + oldname + "' to '" + newname + "'...");
613    
614     function cleanup(xmldoc) {
615         sel_file.name = boxname + newname;
616         filep.innerHTML = newname;
617         set_status("&nbsp;");
618     }
619     var h = http_action(cleanup);
620     h.open("POST", "move?oldname=" + sel_file.name + "&newname=" + boxname + newname, true);
621     h.setRequestHeader("Content-Length", "0");
622     h.send("");
623 }
624
625 </script>
626 </head>
627
628 <body onload="init();">
629 <div id="header">
630 <div class='tools'>
631     <form action="upload" id="upload" method="POST"
632         enctype="multipart/form-data" onsubmit="return verify_upload()">
633     <input type="file" name="payload" id="payload" /><br />
634     <input type="hidden" id="path" name="path" value="/" />
635     <input type="checkbox" name="unzip" value="Y" /> Unzip
636     <input type="submit" value="Upload" />
637     </form>
638 </div>
639 <div class='tools'>
640     <input type='button' value='Delete' onclick='delete_sel_file()' />
641     <input type='button' value='Rename' onclick='rename_on_click()' />
642 </div>
643 <h1>HTTP Drop Box</h1>
644 <p id="status">&nbsp;</p>
645 </div>
646
647 <div id="tree">
648     <table>
649     <tr class='dir'>
650         <td>&nbsp;&nbsp;</td>
651         <td class="branch"><p class='dirname' id="rootnode"><img
652             src="icons/folder.gif" />root/</p></td>
653     </tr>
654     </table>
655 </div>
656
657 <div id="box"></div>
658
659 <div style='clear: both;'>&nbsp;</div>
660
661 </body>
662 </html>
Note: See TracBrowser for help on using the browser.