Replace File's use of Zippy with jQuery slide
[armadillo.git] / web_frontend / file.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.File');
11
12 goog.require('armadillo.Actor');
13 goog.require('goog.Disposable');
14 goog.require('goog.dom');
15
16 /**
17 * A file in a directory listing.
18 * @param {string} File name.
19 * @param {string} The path the file resides at.
20 * @constructor
21 */
22 armadillo.File = function(name, path) {
23 goog.Disposable.call(this);
24 this.name_ = name;
25 this.path_ = path;
26 this.highlight_ = '';
27 this.isDirectory_ = app.isDirectory(name);
28 this.actor_ = new armadillo.Actor(this);
29 };
30 goog.inherits(armadillo.File, goog.Disposable);
31
32 armadillo.File.Highlight = {
33 NONE : '',
34 SELECTED : 'file-selected',
35 ACTIVE : 'file-active'
36 };
37
38 /**
39 * Disposer
40 * @protected
41 */
42 armadillo.File.prototype.disposeInternal = function() {
43 armadillo.File.superClass_.disposeInternal.call(this);
44 this.element_ = null;
45 this.link_ = null;
46 goog.events.unlistenByKey(this.linkListener_);
47 goog.events.unlistenByKey(this.actorListener_);
48 this.actor_.dispose();
49 };
50
51 /**
52 * Returns the name of the file.
53 * @returns string
54 */
55 armadillo.File.prototype.getName = function() {
56 return this.name_;
57 };
58
59 /**
60 * Returns the path the file without the name. This is equivalent to calling
61 * dirname on the absolute path.
62 * @returns string
63 */
64 armadillo.File.prototype.getParentPath = function() {
65 return this.path_;
66 };
67
68 /**
69 * Gets the fully qualified path of the file, from the root of the jail to the
70 * name of the file.
71 * @returns string
72 */
73 armadillo.File.prototype.getFullPath = function() {
74 return this.path_ + this.name_;
75 };
76
77 /**
78 * Returns whether or not this is a directory.
79 * @returns boolean
80 */
81 armadillo.File.prototype.isDirectory = function() {
82 return this.isDirectory_;
83 };
84
85 /**
86 * Returns the extension of the file, or an empty string if theh file is a
87 * directory or does not have an extension.
88 * @returns string
89 */
90 armadillo.File.prototype.getExtension = function() {
91 if (this.isDirectory())
92 return '';
93 var index = this.getName().lastIndexOf('.');
94 if (index == -1)
95 return '';
96 return this.getName().substring(index);
97 };
98
99 /**
100 * Sets the highlight state.
101 */
102 armadillo.File.prototype.setHighlight = function(h) {
103 /*
104 // TODO: enable.
105 goog.dom.classes.addRemove(this.element_, this.highlight_, h);
106 this.highlight_ = h;
107 */
108 };
109
110 /**
111 * Constructs the Elements that make up the UI.
112 * @returns {Element} An element ready for insertion into DOM.
113 */
114 armadillo.File.prototype.draw = function() {
115 // Create the element if it does not exist. If it does, remove all children.
116 if (!this.element_) {
117 this.element_ = goog.dom.createElement('li');
118 this.element_.representedObject = this;
119 var handler = (this.isSpecial_() ? this.clickHandler_ : this.actorHandler_);
120 }
121 goog.dom.removeChildren(this.element_);
122
123 // Set the name of the entry.
124 this.title_ = goog.dom.createDom('div', null);
125 if (this.isDirectory()) {
126 this.link_ = goog.dom.createDom('a', null, this.name_);
127 this.linkListener_ = goog.events.listen(this.link_,
128 goog.events.EventType.CLICK, this.clickHandler_, false, this);
129 goog.dom.appendChild(this.title_, this.link_);
130 } else {
131 goog.dom.setTextContent(this.title_, this.name_);
132 }
133 goog.dom.appendChild(this.element_, this.title_);
134 this.actorListener_ = goog.events.listen(this.title_,
135 goog.events.EventType.CLICK, handler, false, this);
136
137 return this.element_;
138 };
139
140 /**
141 * Deletes the given file in the backend by sending a request. On return, it
142 * will re-query the directory.
143 */
144 armadillo.File.prototype.remove = function() {
145 var file = this;
146 var callback = function(data) {
147 if (data['error']) {
148 app.showError(data['message']);
149 return;
150 } else {
151 app.clearError();
152 }
153 app.list(file.path_);
154 };
155 app.sendRequest('remove', {'path':this.path_ + this.name_}, callback);
156 };
157
158 /**
159 * Moves a file from one absolute path to another. On success, it will navigate
160 * to the new path.
161 * @param {string} dest The destination path.
162 */
163 armadillo.File.prototype.move = function(dest) {
164 var file = this;
165 var callback = function(data) {
166 if (data['error']) {
167 app.showError(data['message']);
168 } else {
169 app.clearError();
170 app.list(app.stripLastPathComponent(dest));
171 }
172 };
173 app.sendRequest('move', {'source':this.getFullPath(), 'target':dest}, callback);
174 };
175
176 /**
177 * Click handler for the link element; only for directories.
178 * @param {Event} e
179 */
180 armadillo.File.prototype.clickHandler_ = function(e) {
181 if (this.isDirectory_) {
182 app.navigate(this.name_);
183 }
184 e.stopPropagation();
185 };
186
187 /**
188 * Click handler for the row, which brings up the Actor interface.
189 * @param {Event} e
190 */
191 armadillo.File.prototype.actorHandler_ = function(e) {
192 e.stopPropagation();
193 if (!this.actor_.isInDocument())
194 this.actor_.render(this.element_);
195 $(this.actor_.getElement()).slideToggle('fast');
196 };
197
198 /**
199 * Returns TRUE if this File is not a real file, but a special kind.
200 * @returns boolean
201 */
202 armadillo.File.prototype.isSpecial_ = function() {
203 return this.name_ == '../';
204 };