Remove the Users map now that it is taken care of by MFE
[armadillo.git] / web_frontend / main.js
1 //
2 // Armadillo File Manager
3 // Copyright (c) 2010-2011, 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 goog.provide('armadillo.App');
12
13 goog.require('armadillo.File');
14 goog.require('armadillo.Version');
15 goog.require('goog.array');
16 goog.require('goog.dom');
17 goog.require('goog.fx.dom.FadeInAndShow');
18 goog.require('goog.fx.dom.FadeOutAndHide');
19 goog.require('goog.net.XhrIo');
20 goog.require('goog.string.format');
21 goog.require('goog.Uri.QueryData');
22
23 armadillo.App = function() {
24 var start_path = '/';
25 if (window.location.hash) {
26 start_path = window.location.hash.substr(1);
27 }
28 this.list(start_path);
29 goog.events.listen(window, goog.events.EventType.HASHCHANGE,
30 this.hashChanged_, false, this);
31
32 this.clearError(false);
33
34 var mkdir = goog.dom.getElement('mkdir');
35 goog.events.listen(mkdir, goog.events.EventType.CLICK,
36 this.mkdirHandler_, false, this);
37
38 var version = goog.string.format('Armadillo %d.%d (%f)',
39 armadillo.Version.MAJOR, armadillo.Version.MINOR,
40 armadillo.Version.BUILD);
41 goog.dom.setTextContent(goog.dom.getElement('footer'), version)
42 }
43
44 /**
45 * Starts a new XHR service request from the backend.
46 * @param {string} action Action to perform.
47 * @param {Object} extra_data Extra data to add.
48 * @param {Function} callback XHR callback.
49 */
50 armadillo.App.prototype.sendRequest = function(action, extra_data, callback) {
51 var data = new goog.Uri.QueryData();
52 data.set('action', action);
53 data.extend(extra_data);
54 goog.net.XhrIo.send('service', callback, 'POST', data);
55 };
56
57 /**
58 * Updates the directory listing for a given path.
59 * @param {string} path Path to list; relative to jail.
60 */
61 armadillo.App.prototype.list = function(path) {
62 var callback = function(e) {
63 var data = e.target.getResponseJson();
64 if (data['error']) {
65 app.showError(data['message']);
66 return; // Error.
67 } else {
68 app.clearError(true);
69 }
70
71 // Update the listing.
72 goog.dom.setTextContent(goog.dom.getElement('pwd'), path);
73 app.currentPath_ = path;
74 window.location.hash = path;
75 document.title = path + ' - Armadillo';
76 var list = goog.dom.getElement('ls');
77 goog.dom.removeChildren(list);
78
79 // Add a previous directory entry.
80 if (path != '/' && path != '')
81 goog.array.insertAt(data, '../', 0);
82
83 // Add items for each entry.
84 goog.array.forEach(data, function(file) {
85 var fileObject = new armadillo.File(file, path);
86 goog.dom.appendChild(list, fileObject.draw());
87 });
88 }
89 this.sendRequest('list', {'path':path}, callback);
90 };
91
92 /**
93 * Navigates to a subpath. Can only handle directories.
94 * @param {string} target Relative path to |currentPath_|.
95 */
96 armadillo.App.prototype.navigate = function(target) {
97 if (target == '../') {
98 this.list(this.stripLastPathComponent(this.currentPath_));
99 } else {
100 this.list(this.currentPath_ + target);
101 }
102 };
103
104 /**
105 * Event for when the hash changes.
106 * @param {Event} e
107 */
108 armadillo.App.prototype.hashChanged_ = function(e) {
109 if (window.location.hash.length)
110 this.list(window.location.hash.substr(1));
111 };
112
113 /**
114 * Checks whether a path is a directory.
115 * @param {string} path
116 * @returns boolean
117 */
118 armadillo.App.prototype.isDirectory = function(path) {
119 return path[path.length - 1] == '/';
120 };
121
122 /**
123 * Gets the current path of the directory being displayed, absolute to root.
124 * @returns string
125 */
126 armadillo.App.prototype.getCurrentPath = function() {
127 return this.currentPath_;
128 };
129
130 /**
131 * Strips the last path component from a path.
132 * @param {string} path
133 * @returns string
134 */
135 armadillo.App.prototype.stripLastPathComponent = function(path) {
136 for (var i = path.length - 1; i >= 0; --i) {
137 if (path[i] == '/') {
138 if (i != path.length - 1) {
139 return path.substring(0, i + 1);
140 }
141 }
142 }
143 return '/';
144 };
145
146 /**
147 * Joins all the arguments together as a path.
148 * @param {string...} varargs Components to join
149 */
150 armadillo.App.prototype.joinPath = function() {
151 var path = '';
152 var sep = '/';
153 var last = arguments.length - 1;
154 goog.array.forEach(arguments, function (c, i) {
155 if (c == sep && i != 0)
156 return;
157 path += c;
158 if (c[c.length - 1] != sep && i != last)
159 path += sep;
160 });
161 return path;
162 };
163
164 /**
165 * Clears the error message.
166 * @param {bool?} animate Whether or not to animate out.
167 */
168 armadillo.App.prototype.clearError = function(animate) {
169 var elm = goog.dom.getElement('error');
170 var anim = new goog.fx.dom.FadeOutAndHide(elm, 500);
171 if (!goog.dom.getTextContent(elm) || !animate) {
172 anim.hide();
173 return;
174 }
175 goog.events.listenOnce(anim, goog.fx.Animation.EventType.END, function() {
176 goog.dom.setTextContent(elm, '');
177 });
178 anim.play();
179 };
180
181 /**
182 * Shows an error message.
183 * @param {string} message
184 */
185 armadillo.App.prototype.showError = function(message) {
186 var elm = goog.dom.getElement('error');
187 goog.dom.setTextContent(elm, message);
188 var anim = new goog.fx.dom.FadeInAndShow(elm, 1000);
189 anim.play();
190 };
191
192 /**
193 * Creates a subdirectory in the current path.
194 */
195 armadillo.App.prototype.mkdirHandler_ = function() {
196 var name = prompt('Name the new subdirectory', '');
197 if (name != null && name != '') {
198 var path = this.joinPath(this.getCurrentPath(), name);
199 this.sendRequest('mkdir', {'path':path}, function(e) {
200 var data = e.target.getResponseJson();
201 if (data['error']) {
202 app.showError(data['message']);
203 } else {
204 app.clearError();
205 app.list(app.getCurrentPath());
206 }
207 });
208 }
209 };