Break up the /service handler into individual HTTP handlers.
[armadillo.git] / 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 $.namespace('armadillo.App');
11
12 $(document).ready(function() {
13 app = new armadillo.App();
14 });
15
16 armadillo.App = function() {
17 var start_path = '/';
18 if (window.location.hash) {
19 start_path = window.location.hash.substr(1);
20 }
21 this.list(start_path);
22
23 $(window).bind('hashchange', this.hashChanged_.bind(this));
24
25 this.clearError(false);
26
27 $('#mkdir').click(this.mkdirHandler_.bind(this));
28
29 var version = 'Armadillo ' + armadillo.Version.MAJOR + '.' + armadillo.Version.MINOR +
30 ' (' + armadillo.Version.BUILD + ')';
31 $('#footer').text(version);
32 }
33
34 /**
35 * Starts a new XHR service request from the backend.
36 * @param {string} action Action to perform.
37 * @param {Object} data Extra data to add.
38 * @param {Function} callback XHR callback.
39 * @return {jqXHR} The jQuery XHR object.
40 */
41 armadillo.App.prototype.sendRequest = function(action, data, callback) {
42 return $.ajax({
43 url: 'service/' + action,
44 type: 'POST',
45 data: data,
46 success: callback,
47 error: function(xhr, status, error) {
48 app.showError(xhr.responseText);
49 console.log(xhr);
50 console.log(status);
51 console.log(error);
52 }
53 });
54 };
55
56 /**
57 * Updates the directory listing for a given path.
58 * @param {string} path Path to list; relative to jail.
59 */
60 armadillo.App.prototype.list = function(path) {
61 var callback = function(data, status, xhr) {
62 if (data['error']) {
63 app.showError(data['message']);
64 return; // Error.
65 } else {
66 app.clearError(true);
67 }
68
69 // Update the listing.
70 $('#pwd').text(path);
71 app.currentPath_ = path;
72 window.location.hash = path;
73 document.title = path + ' - Armadillo';
74
75 var list = $('#ls');
76 list.empty();
77
78 // Add a previous directory entry.
79 if (path != '/' && path != '')
80 data.unshift('../');
81
82 // Add items for each entry.
83 $.each(data, function(i, file) {
84 var fileObject = new armadillo.File(file, path);
85 list.append(fileObject.createDom());
86 });
87 }
88 this.sendRequest('list', {'path':path}, callback);
89 };
90
91 /**
92 * Navigates to a subpath. Can only handle directories.
93 * @param {string} target Relative path to |currentPath_|.
94 */
95 armadillo.App.prototype.navigate = function(target) {
96 if (target == '../') {
97 this.list(this.stripLastPathComponent(this.currentPath_));
98 } else {
99 this.list(this.currentPath_ + target);
100 }
101 };
102
103 /**
104 * Event for when the hash changes.
105 * @param {Event} e
106 */
107 armadillo.App.prototype.hashChanged_ = function(e) {
108 if (window.location.hash.length)
109 this.list(window.location.hash.substr(1));
110 };
111
112 /**
113 * Checks whether a path is a directory.
114 * @param {string} path
115 * @returns boolean
116 */
117 armadillo.App.prototype.isDirectory = function(path) {
118 return path[path.length - 1] == '/';
119 };
120
121 /**
122 * Gets the current path of the directory being displayed, absolute to root.
123 * @returns string
124 */
125 armadillo.App.prototype.getCurrentPath = function() {
126 return this.currentPath_;
127 };
128
129 /**
130 * Strips the last path component from a path.
131 * @param {string} path
132 * @returns string
133 */
134 armadillo.App.prototype.stripLastPathComponent = function(path) {
135 for (var i = path.length - 1; i >= 0; --i) {
136 if (path[i] == '/') {
137 if (i != path.length - 1) {
138 return path.substring(0, i + 1);
139 }
140 }
141 }
142 return '/';
143 };
144
145 /**
146 * Joins all the arguments together as a path.
147 * @param {string...} varargs Components to join
148 */
149 armadillo.App.prototype.joinPath = function() {
150 var path = '';
151 var sep = '/';
152 var last = arguments.length - 1;
153 $.each(arguments, function (i, c) {
154 if (c == sep && i != 0)
155 return;
156 path += c;
157 if (c[c.length - 1] != sep && i != last)
158 path += sep;
159 });
160 return path;
161 };
162
163 /**
164 * Clears the error message.
165 * @param {bool?} animate Whether or not to animate out.
166 */
167 armadillo.App.prototype.clearError = function(animate) {
168 var elm = $('#error');
169 if (!elm.text() || !animate) {
170 elm.hide();
171 return;
172 }
173
174 elm.fadeOut(500, function() {
175 elm.text('');
176 });
177 };
178
179 /**
180 * Shows an error message.
181 * @param {string} message
182 */
183 armadillo.App.prototype.showError = function(message) {
184 $('#error').text(message).fadeIn(1000);
185 };
186
187 /**
188 * Creates a subdirectory in the current path.
189 */
190 armadillo.App.prototype.mkdirHandler_ = function() {
191 var name = prompt('Name the new subdirectory', '');
192 if (name != null && name != '') {
193 var path = this.joinPath(this.getCurrentPath(), name);
194 this.sendRequest('mkdir', {'path':path}, function(data, status, xhr) {
195 if (data['error']) {
196 app.showError(data['message']);
197 } else {
198 app.clearError();
199 app.list(app.getCurrentPath());
200 }
201 });
202 }
203 };