* Add some basic styling
[armadillo.git] / web_frontend / main.js
1 //
2 // Armadillo File Manager
3 // Copyright (c) 2010, Robert Sesek <http://www.bluestatic.org>
4 //
5 // This program is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free Software
7 // Foundation, either version 3 of the License, or any later version.
8 //
9
10 goog.provide('armadillo');
11
12 goog.require('goog.array');
13 goog.require('goog.dom');
14 goog.require('goog.fx.dom.FadeInAndShow');
15 goog.require('goog.net.XhrIo');
16 goog.require('goog.Uri.QueryData');
17
18 armadillo = function() {
19 var start_path = '/';
20 if (window.location.hash) {
21 start_path = window.location.hash.substr(1);
22 }
23 this.list(start_path);
24 this.listeners_ = new Array();
25 this.errorEffect_ =
26 new goog.fx.dom.FadeInAndShow(goog.dom.getElement('error'), 2.0);
27 this.errorEffect_.hide();
28 goog.events.listen(window, goog.events.EventType.HASHCHANGE,
29 this.hashChanged_, false, this);
30 }
31
32 /**
33 * Starts a new XHR service request from the backend.
34 * @param {string} action Action to perform.
35 * @param {Object} extra_data Extra data to add.
36 * @param {Function} callback XHR callback.
37 */
38 armadillo.prototype.sendRequest_ = function(action, extra_data, callback) {
39 var data = new goog.Uri.QueryData();
40 data.set('action', action);
41 data.extend(extra_data);
42 goog.net.XhrIo.send('/service', callback, 'POST', data);
43 };
44
45 /**
46 * Updates the directory listing for a given path.
47 * @param {string} path Path to list; relative to jail.
48 */
49 armadillo.prototype.list = function(path) {
50 var callback = function(e) {
51 var data = e.target.getResponseJson();
52 if (data['error']) {
53 app.showError_(data['message']);
54 return; // Error.
55 } else {
56 app.clearError_();
57 }
58
59 // Unlisten all current listeners.
60 goog.array.forEach(app.listeners_, function(e) {
61 goog.events.unlistenByKey(e);
62 });
63
64 // Update the listing.
65 goog.dom.setTextContent(goog.dom.getElement('pwd'), path);
66 app.currentPath_ = path;
67 window.location.hash = path;
68 var list = goog.dom.getElement('ls');
69 goog.dom.removeChildren(list);
70
71 // Add a previous directory entry.
72 if (path != '/' && path != '')
73 goog.array.insertAt(data, '../', 0);
74
75 // Add items for each entry.
76 goog.array.forEach(data, function(file) {
77 var elm = goog.dom.createElement('li');
78 goog.dom.setTextContent(elm, file);
79 goog.dom.appendChild(list, elm);
80 app.listeners_.push(goog.events.listen(elm,
81 goog.events.EventType.CLICK, app.clickHandler_, false, app));
82 });
83 }
84 this.sendRequest_('list', {'path':path}, callback);
85 };
86
87 /**
88 * Click handler for elements.
89 * @param {Event} e
90 */
91 armadillo.prototype.clickHandler_ = function(e) {
92 var target = goog.dom.getTextContent(e.target);
93 if (target == '../') {
94 this.list(this.stripLastPathComponent_(this.currentPath_));
95 } else if (this.isDirectory_(target)) {
96 this.list(this.currentPath_ + target);
97 }
98 };
99
100 /**
101 * Event for when the hash changes.
102 * @param {Event} e
103 */
104 armadillo.prototype.hashChanged_ = function(e) {
105 if (window.location.hash.length)
106 this.list(window.location.hash.substr(1));
107 };
108
109 /**
110 * Checks whether a path is a directory.
111 * @param {string} path
112 * @returns boolean
113 */
114 armadillo.prototype.isDirectory_ = function(path) {
115 return path[path.length - 1] == '/';
116 };
117
118 /**
119 * Strips the last path component from a path.
120 * @param {string} path
121 * @returns string
122 */
123 armadillo.prototype.stripLastPathComponent_ = function(path) {
124 for (var i = path.length - 1; i >= 0; --i) {
125 if (path[i] == '/') {
126 if (i != path.length - 1) {
127 return path.substring(0, i + 1);
128 }
129 }
130 }
131 return '/';
132 };
133
134 /**
135 * Clears the error message.
136 */
137 armadillo.prototype.clearError_ = function() {
138 this.errorEffect_.hide();
139 goog.dom.setTextContent(this.errorEffect_.element, '');
140 };
141
142 /**
143 * Shows an error message.
144 * @param {string} message
145 */
146 armadillo.prototype.showError_ = function(message) {
147 goog.dom.setTextContent(this.errorEffect_.element, message);
148 this.errorEffect_.show();
149 };