Create a new JS class for representing files in directory listings.
[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 goog.provide('armadillo.App');
12
13 goog.require('armadillo.File');
14 goog.require('goog.array');
15 goog.require('goog.dom');
16 goog.require('goog.fx.dom.FadeInAndShow');
17 goog.require('goog.net.XhrIo');
18 goog.require('goog.Uri.QueryData');
19
20 armadillo.App = function() {
21 var start_path = '/';
22 if (window.location.hash) {
23 start_path = window.location.hash.substr(1);
24 }
25 this.list(start_path);
26 this.listeners_ = new Array();
27 this.errorEffect_ =
28 new goog.fx.dom.FadeInAndShow(goog.dom.getElement('error'), 2.0);
29 this.errorEffect_.hide();
30 goog.events.listen(window, goog.events.EventType.HASHCHANGE,
31 this.hashChanged_, false, this);
32 }
33
34 /**
35 * Starts a new XHR service request from the backend.
36 * @param {string} action Action to perform.
37 * @param {Object} extra_data Extra data to add.
38 * @param {Function} callback XHR callback.
39 */
40 armadillo.App.prototype.sendRequest_ = function(action, extra_data, callback) {
41 var data = new goog.Uri.QueryData();
42 data.set('action', action);
43 data.extend(extra_data);
44 goog.net.XhrIo.send('/service', callback, 'POST', data);
45 };
46
47 /**
48 * Updates the directory listing for a given path.
49 * @param {string} path Path to list; relative to jail.
50 */
51 armadillo.App.prototype.list = function(path) {
52 var callback = function(e) {
53 var data = e.target.getResponseJson();
54 if (data['error']) {
55 app.showError_(data['message']);
56 return; // Error.
57 } else {
58 app.clearError_();
59 }
60
61 // Unlisten all current listeners.
62 goog.array.forEach(app.listeners_, function(e) {
63 goog.events.unlistenByKey(e);
64 });
65
66 // Update the listing.
67 goog.dom.setTextContent(goog.dom.getElement('pwd'), path);
68 app.currentPath_ = path;
69 window.location.hash = path;
70 var list = goog.dom.getElement('ls');
71 goog.dom.removeChildren(list);
72
73 // Add a previous directory entry.
74 if (path != '/' && path != '')
75 goog.array.insertAt(data, '../', 0);
76
77 // Add items for each entry.
78 goog.array.forEach(data, function(file) {
79 var fileObject = new armadillo.File(file);
80 goog.dom.appendChild(list, fileObject.draw());
81 });
82 }
83 this.sendRequest_('list', {'path':path}, callback);
84 };
85
86 /**
87 * Click handler for elements.
88 * @param {Event} e
89 */
90 armadillo.App.prototype.clickHandler_ = function(e) {
91 var target = goog.dom.getTextContent(e.target);
92 if (target == '../') {
93 this.list(this.stripLastPathComponent_(this.currentPath_));
94 } else if (this.isDirectory_(target)) {
95 this.list(this.currentPath_ + target);
96 }
97 };
98
99 /**
100 * Event for when the hash changes.
101 * @param {Event} e
102 */
103 armadillo.App.prototype.hashChanged_ = function(e) {
104 if (window.location.hash.length)
105 this.list(window.location.hash.substr(1));
106 };
107
108 /**
109 * Checks whether a path is a directory.
110 * @param {string} path
111 * @returns boolean
112 */
113 armadillo.App.prototype.isDirectory_ = function(path) {
114 return path[path.length - 1] == '/';
115 };
116
117 /**
118 * Strips the last path component from a path.
119 * @param {string} path
120 * @returns string
121 */
122 armadillo.App.prototype.stripLastPathComponent_ = function(path) {
123 for (var i = path.length - 1; i >= 0; --i) {
124 if (path[i] == '/') {
125 if (i != path.length - 1) {
126 return path.substring(0, i + 1);
127 }
128 }
129 }
130 return '/';
131 };
132
133 /**
134 * Clears the error message.
135 */
136 armadillo.App.prototype.clearError_ = function() {
137 this.errorEffect_.hide();
138 goog.dom.setTextContent(this.errorEffect_.element, '');
139 };
140
141 /**
142 * Shows an error message.
143 * @param {string} message
144 */
145 armadillo.App.prototype.showError_ = function(message) {
146 goog.dom.setTextContent(this.errorEffect_.element, message);
147 this.errorEffect_.show();
148 };