2 // Armadillo File Manager
3 // Copyright (c) 2010-2011, Robert Sesek <http://www.bluestatic.org>
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.
10 goog
.provide('armadillo');
11 goog
.provide('armadillo.App');
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');
23 armadillo
.App
= function() {
25 if (window
.location
.hash
) {
26 start_path
= window
.location
.hash
.substr(1);
28 this.list(start_path
);
29 goog
.events
.listen(window
, goog
.events
.EventType
.HASHCHANGE
,
30 this.hashChanged_
, false, this);
32 this.clearError(false);
34 var mkdir
= goog
.dom
.getElement('mkdir');
35 goog
.events
.listen(mkdir
, goog
.events
.EventType
.CLICK
,
36 this.mkdirHandler_
, false, this);
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
)
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.
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
);
58 * Updates the directory listing for a given path.
59 * @param {string} path Path to list; relative to jail.
61 armadillo
.App
.prototype.list
= function(path
) {
62 var callback
= function(e
) {
63 var data
= e
.target
.getResponseJson();
65 app
.showError(data
['message']);
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
);
79 // Add a previous directory entry.
80 if (path
!= '/' && path
!= '')
81 goog
.array
.insertAt(data
, '../', 0);
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());
89 this.sendRequest('list', {'path':path
}, callback
);
93 * Navigates to a subpath. Can only handle directories.
94 * @param {string} target Relative path to |currentPath_|.
96 armadillo
.App
.prototype.navigate
= function(target
) {
97 if (target
== '../') {
98 this.list(this.stripLastPathComponent(this.currentPath_
));
100 this.list(this.currentPath_
+ target
);
105 * Event for when the hash changes.
108 armadillo
.App
.prototype.hashChanged_
= function(e
) {
109 if (window
.location
.hash
.length
)
110 this.list(window
.location
.hash
.substr(1));
114 * Checks whether a path is a directory.
115 * @param {string} path
118 armadillo
.App
.prototype.isDirectory
= function(path
) {
119 return path
[path
.length
- 1] == '/';
123 * Gets the current path of the directory being displayed, absolute to root.
126 armadillo
.App
.prototype.getCurrentPath
= function() {
127 return this.currentPath_
;
131 * Strips the last path component from a path.
132 * @param {string} path
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);
147 * Joins all the arguments together as a path.
148 * @param {string...} varargs Components to join
150 armadillo
.App
.prototype.joinPath
= function() {
153 var last
= arguments
.length
- 1;
154 goog
.array
.forEach(arguments
, function (c
, i
) {
155 if (c
== sep
&& i
!= 0)
158 if (c
[c
.length
- 1] != sep
&& i
!= last
)
165 * Clears the error message.
166 * @param {bool?} animate Whether or not to animate out.
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
) {
175 goog
.events
.listenOnce(anim
, goog
.fx
.Animation
.EventType
.END
, function() {
176 goog
.dom
.setTextContent(elm
, '');
182 * Shows an error message.
183 * @param {string} message
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);
193 * Creates a subdirectory in the current path.
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();
202 app
.showError(data
['message']);
205 app
.list(app
.getCurrentPath());