Add an ability to navigate upwards.
[armadillo.git] / web_frontend / main.js
1 goog.provide('armadillo');
2
3 goog.require('goog.array');
4 goog.require('goog.dom');
5 goog.require('goog.net.XhrIo');
6 goog.require('goog.Uri.QueryData');
7
8 armadillo = function() {
9 var start_path = '/';
10 if (window.location.hash) {
11 start_path = window.location.hash.substr(1);
12 }
13 this.list(start_path);
14 this.listeners_ = new Array();
15 goog.events.listen(window, goog.events.EventType.HASHCHANGE,
16 this.hashChanged_, false, this);
17 }
18
19 /**
20 * Starts a new XHR service request from the backend.
21 * @param {string} action Action to perform.
22 * @param {Object} extra_data Extra data to add.
23 * @param {Function} callback XHR callback.
24 */
25 armadillo.prototype.sendRequest_ = function(action, extra_data, callback) {
26 var data = new goog.Uri.QueryData();
27 data.set('action', 'list');
28 data.extend(extra_data);
29 goog.net.XhrIo.send('/service', callback, 'POST', data);
30 };
31
32 /**
33 * Updates the directory listing for a given path.
34 * @param {string} path Path to list; relative to jail.
35 */
36 armadillo.prototype.list = function(path) {
37 var callback = function(e) {
38 var data = e.target.getResponseJson();
39 if (data['error']) {
40 return; // Error.
41 }
42 // Unlisten all current listeners.
43 goog.array.forEach(app.listeners_, function(e) {
44 goog.events.unlistenByKey(e);
45 });
46
47 // Update the listing.
48 goog.dom.setTextContent(goog.dom.getElement('pwd'), path);
49 app.currentPath_ = path;
50 window.location.hash = path;
51 var list = goog.dom.getElement('ls');
52 goog.dom.removeChildren(list);
53
54 // Add a previous directory entry.
55 if (path != '/' && path != '')
56 goog.array.insertAt(data, '../', 0);
57
58 // Add items for each entry.
59 goog.array.forEach(data, function(file) {
60 var elm = goog.dom.createElement('li');
61 goog.dom.setTextContent(elm, file);
62 goog.dom.appendChild(list, elm);
63 app.listeners_.push(goog.events.listen(elm,
64 goog.events.EventType.CLICK, app.clickHandler_, false, app));
65 });
66 }
67 this.sendRequest_('list', {'path':path}, callback);
68 };
69
70 /**
71 * Click handler for elements.
72 * @param {Event} e
73 */
74 armadillo.prototype.clickHandler_ = function(e) {
75 var target = goog.dom.getTextContent(e.target);
76 if (target == '../') {
77 this.list(this.stripLastPathComponent_(this.currentPath_));
78 } else if (this.isDirectory_(target)) {
79 this.list(this.currentPath_ + target);
80 }
81 };
82
83 /**
84 * Event for when the hash changes.
85 * @param {Event} e
86 */
87 armadillo.prototype.hashChanged_ = function(e) {
88 if (window.location.hash.length)
89 this.list(window.location.hash.substr(1));
90 };
91
92 /**
93 * Checks whether a path is a directory.
94 * @param {string} path
95 * @returns boolean
96 */
97 armadillo.prototype.isDirectory_ = function(path) {
98 return path[path.length - 1] == '/';
99 };
100
101 /**
102 * Strips the last path component from a path.
103 * @param {string} path
104 * @returns string
105 */
106 armadillo.prototype.stripLastPathComponent_ = function(path) {
107 for (var i = path.length - 1; i >= 0; --i) {
108 if (path[i] == '/') {
109 if (i != path.length - 1) {
110 return path.substring(0, i + 1);
111 }
112 }
113 }
114 return '/';
115 };