OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** | 7 /** |
8 * PreviewPanel UI class. | 8 * PreviewPanel UI class. |
9 * @param {HTMLElement} element DOM Element of preview panel. | 9 * @param {HTMLElement} element DOM Element of preview panel. |
10 * @param {PreviewPanel.VisibilityType} visibilityType Initial value of the | 10 * @param {PreviewPanel.VisibilityType} visibilityType Initial value of the |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
48 */ | 48 */ |
49 this.thumbnailElement_ = element.querySelector('.preview-thumbnails'); | 49 this.thumbnailElement_ = element.querySelector('.preview-thumbnails'); |
50 | 50 |
51 /** | 51 /** |
52 * @type {HTMLElement} | 52 * @type {HTMLElement} |
53 * @private | 53 * @private |
54 */ | 54 */ |
55 this.summaryElement_ = element.querySelector('.preview-summary'); | 55 this.summaryElement_ = element.querySelector('.preview-summary'); |
56 | 56 |
57 /** | 57 /** |
58 * @type {CalculatingLabel} | |
59 * @private | |
60 */ | |
61 this.calculatingLabel_ = new CalculatingLabel( | |
62 this.summaryElement_.querySelector('.calculating-size')); | |
63 | |
64 /** | |
58 * @type {HTMLElement} | 65 * @type {HTMLElement} |
59 * @private | 66 * @private |
60 */ | 67 */ |
61 this.textElement_ = element.querySelector('.preview-text'); | 68 this.previewText_ = element.querySelector('.preview-text'); |
62 | 69 |
63 /** | 70 /** |
64 * Function to be called at the end of visibility change. | 71 * FileSelection to be displayed. |
65 * @type {function(boolean)} | 72 * @type {FileSelection} |
66 * @private | 73 * @private |
67 */ | 74 */ |
68 this.visibilityChangedCallback_ = null; | 75 this.selection_ = {entries: [], computeBytes: function() {}}; |
69 | 76 |
70 /** | 77 /** |
71 * Entries to be displayed. | 78 * Sequence value that is incremented by every selection update nad is used to |
72 * @type {Array.<Entry>} | 79 * check if the callback is up to date or not. |
80 * @type {number} | |
73 * @private | 81 * @private |
74 */ | 82 */ |
75 this.entries_ = []; | 83 this.sequence_ = 0; |
76 | 84 |
77 cr.EventTarget.call(this); | 85 cr.EventTarget.call(this); |
78 }; | 86 }; |
79 | 87 |
80 /** | 88 /** |
81 * Name of PreviewPanels's event. | 89 * Name of PreviewPanels's event. |
82 * @enum {string} | 90 * @enum {string} |
83 * @const | 91 * @const |
84 */ | 92 */ |
85 PreviewPanel.Event = Object.freeze({ | 93 PreviewPanel.Event = Object.freeze({ |
86 // Event to be triggered at the end of visibility change. | 94 // Event to be triggered at the end of visibility change. |
87 VISIBILITY_CHANGE: 'visibilityChange' | 95 VISIBILITY_CHANGE: 'visibilityChange' |
88 }); | 96 }); |
89 | 97 |
90 /** | 98 /** |
91 * Visibility type of the preview panel. | 99 * Visibility type of the preview panel. |
92 */ | 100 */ |
93 PreviewPanel.VisibilityType = Object.freeze({ | 101 PreviewPanel.VisibilityType = Object.freeze({ |
94 // Preview panel always shows. | 102 // Preview panel always shows. |
95 ALWAYS_VISIBLE: 'alwaysVisible', | 103 ALWAYS_VISIBLE: 'alwaysVisible', |
96 // Preview panel shows when the entries property are set. | 104 // Preview panel shows when the selection property are set. |
97 AUTO: 'auto', | 105 AUTO: 'auto', |
98 // Preview panel does not show. | 106 // Preview panel does not show. |
99 ALWAYS_HIDDEN: 'alwaysHidden' | 107 ALWAYS_HIDDEN: 'alwaysHidden' |
100 }); | 108 }); |
101 | 109 |
102 /** | 110 /** |
103 * @private | 111 * @private |
104 */ | 112 */ |
105 PreviewPanel.Visibility_ = Object.freeze({ | 113 PreviewPanel.Visibility_ = Object.freeze({ |
106 VISIBLE: 'visible', | 114 VISIBLE: 'visible', |
107 HIDING: 'hiding', | 115 HIDING: 'hiding', |
108 HIDDEN: 'hidden' | 116 HIDDEN: 'hidden' |
109 }); | 117 }); |
110 | 118 |
111 PreviewPanel.prototype = { | 119 PreviewPanel.prototype = { |
112 __proto__: cr.EventTarget.prototype, | 120 __proto__: cr.EventTarget.prototype, |
113 | 121 |
114 /** | 122 /** |
115 * Setter for entries to be displayed in the preview panel. | 123 * Setter for selection to be displayed in the preview panel. |
116 * @param {Array.<Entry>} entries New entries. | 124 * @param {FileSelection} selection New selection. |
117 */ | 125 */ |
118 set entries(entries) { | 126 set selection(selection) { |
yoshiki
2013/09/06 06:56:03
It should be a method like setSelection(selectio)
hirono
2013/09/09 07:15:06
Done.
| |
119 this.entries_ = entries; | 127 this.sequence_++; |
128 this.selection_ = selection; | |
120 this.updateVisibility_(); | 129 this.updateVisibility_(); |
130 this.updatePreviewText_(); | |
121 }, | 131 }, |
122 | 132 |
123 /** | 133 /** |
124 * Setter for the current path. | 134 * Setter for the current path. |
125 * @param {string} path New path. | 135 * @param {string} path New path. |
126 */ | 136 */ |
127 set currentPath(path) { | 137 set currentPath(path) { |
128 this.currentPath_ = path; | 138 this.currentPath_ = path; |
129 this.updateVisibility_(); | 139 this.updateVisibility_(); |
130 }, | 140 }, |
(...skipping 18 matching lines...) Expand all Loading... | |
149 return this.height_; | 159 return this.height_; |
150 } | 160 } |
151 }; | 161 }; |
152 | 162 |
153 /** | 163 /** |
154 * Initializes the element. | 164 * Initializes the element. |
155 */ | 165 */ |
156 PreviewPanel.prototype.initialize = function() { | 166 PreviewPanel.prototype.initialize = function() { |
157 this.element_.addEventListener('webkitTransitionEnd', | 167 this.element_.addEventListener('webkitTransitionEnd', |
158 this.onTransitionEnd_.bind(this)); | 168 this.onTransitionEnd_.bind(this)); |
169 this.updatePreviewText_(); | |
159 this.updateVisibility_(); | 170 this.updateVisibility_(); |
160 }; | 171 }; |
161 | 172 |
162 /** | 173 /** |
163 * Update the visibility of the preview panel. | 174 * Update the visibility of the preview panel. |
164 * @private | 175 * @private |
165 */ | 176 */ |
166 PreviewPanel.prototype.updateVisibility_ = function() { | 177 PreviewPanel.prototype.updateVisibility_ = function() { |
167 // Get the new visibility value. | 178 // Get the new visibility value. |
168 var visibility = this.element_.getAttribute('visibility'); | 179 var visibility = this.element_.getAttribute('visibility'); |
169 var newVisible = null; | 180 var newVisible = null; |
170 switch (this.visibilityType_) { | 181 switch (this.visibilityType_) { |
171 case PreviewPanel.VisibilityType.ALWAYS_VISIBLE: | 182 case PreviewPanel.VisibilityType.ALWAYS_VISIBLE: |
172 newVisible = true; | 183 newVisible = true; |
173 break; | 184 break; |
174 case PreviewPanel.VisibilityType.AUTO: | 185 case PreviewPanel.VisibilityType.AUTO: |
175 newVisible = this.entries_.length != 0 || | 186 newVisible = this.selection_.entries.length != 0 || |
176 !PathUtil.isRootPath(this.currentPath_); | 187 !PathUtil.isRootPath(this.currentPath_); |
177 break; | 188 break; |
178 case PreviewPanel.VisibilityType.ALWAYS_HIDDEN: | 189 case PreviewPanel.VisibilityType.ALWAYS_HIDDEN: |
179 newVisible = false; | 190 newVisible = false; |
180 break; | 191 break; |
181 default: | 192 default: |
182 console.error('Invalid visibilityType.'); | 193 console.error('Invalid visibilityType.'); |
183 return; | 194 return; |
184 } | 195 } |
185 | 196 |
186 // If the visibility has been already the new value, just return. | 197 // If the visibility has been already the new value, just return. |
187 if ((visibility == PreviewPanel.Visibility_.VISIBLE && newVisible) || | 198 if ((visibility == PreviewPanel.Visibility_.VISIBLE && newVisible) || |
188 (visibility == PreviewPanel.Visibility_.HIDDEN && !newVisible)) | 199 (visibility == PreviewPanel.Visibility_.HIDDEN && !newVisible)) |
189 return; | 200 return; |
190 | 201 |
191 // Set the new visibility value. | 202 // Set the new visibility value. |
192 if (newVisible) { | 203 if (newVisible) { |
193 this.element_.setAttribute('visibility', PreviewPanel.Visibility_.VISIBLE); | 204 this.element_.setAttribute('visibility', PreviewPanel.Visibility_.VISIBLE); |
194 cr.dispatchSimpleEvent(this, PreviewPanel.Event.VISIBILITY_CHANGE); | 205 cr.dispatchSimpleEvent(this, PreviewPanel.Event.VISIBILITY_CHANGE); |
195 } else { | 206 } else { |
196 this.element_.setAttribute('visibility', PreviewPanel.Visibility_.HIDING); | 207 this.element_.setAttribute('visibility', PreviewPanel.Visibility_.HIDING); |
197 } | 208 } |
198 }; | 209 }; |
199 | 210 |
200 /** | 211 /** |
212 * Update the text in the preview panel. | |
213 * @private | |
214 */ | |
215 PreviewPanel.prototype.updatePreviewText_ = function() { | |
216 var selection = this.selection_; | |
217 | |
218 // Hides the preview text if zero or one file is selected. We shows a | |
219 // breadcrumb list instead on the preview panel. | |
220 if (selection.totalCount <= 1) { | |
221 this.calculatingLabel_.hidden = true; | |
222 this.previewText_.textContent = ''; | |
223 return; | |
224 } | |
225 | |
226 // Obtains the preview text. | |
227 var text = ''; | |
228 if (selection.directoryCount == 0) | |
229 text = strf('MANY_FILES_SELECTED', selection.fileCount); | |
230 else if (selection.fileCount == 0) | |
231 text = strf('MANY_DIRECTORIES_SELECTED', selection.directoryCount); | |
232 else | |
233 text = strf('MANY_ENTRIES_SELECTED', selection.totalCount); | |
234 | |
235 // Obtains the size of files. | |
236 this.calculatingLabel_.hidden = selection.bytesKnown; | |
237 if (selection.bytesKnown && selection.showBytes) | |
238 text += ', ' + util.bytesToString(selection.bytes); | |
239 | |
240 // Set the preview text to the element. | |
241 this.previewText_.textContent = text; | |
242 | |
243 // Request the byte calculation if needed. | |
244 if (!selection.bytesKnown) { | |
245 this.selection_.computeBytes(function(sequence) { | |
246 // Selection has been already updated. | |
247 if (this.sequence_ != sequence) | |
248 return; | |
249 this.updatePreviewText_(); | |
250 }.bind(this, this.sequence_)); | |
251 } | |
252 }; | |
253 | |
254 /** | |
201 * Event handler to be called at the end of hiding transition. | 255 * Event handler to be called at the end of hiding transition. |
202 * @param {Event} event The webkitTransitionEnd event. | 256 * @param {Event} event The webkitTransitionEnd event. |
203 * @private | 257 * @private |
204 */ | 258 */ |
205 PreviewPanel.prototype.onTransitionEnd_ = function(event) { | 259 PreviewPanel.prototype.onTransitionEnd_ = function(event) { |
206 if (event.target != this.element_ || event.propertyName != 'opacity') | 260 if (event.target != this.element_ || event.propertyName != 'opacity') |
207 return; | 261 return; |
208 var visibility = this.element_.getAttribute('visibility'); | 262 var visibility = this.element_.getAttribute('visibility'); |
209 if (visibility != PreviewPanel.Visibility_.HIDING) | 263 if (visibility != PreviewPanel.Visibility_.HIDING) |
210 return; | 264 return; |
211 this.element_.setAttribute('visibility', PreviewPanel.Visibility_.HIDDEN); | 265 this.element_.setAttribute('visibility', PreviewPanel.Visibility_.HIDDEN); |
212 cr.dispatchSimpleEvent(this, PreviewPanel.Event.VISIBILITY_CHANGE); | 266 cr.dispatchSimpleEvent(this, PreviewPanel.Event.VISIBILITY_CHANGE); |
213 }; | 267 }; |
268 | |
269 /** | |
270 * Animating colculating label. | |
yoshiki
2013/09/06 06:56:03
s/colculating/calculating/
And please describe wh
hirono
2013/09/09 07:15:06
Done.
| |
271 * @param {HTMLElement} element DOM element of the label. | |
272 * @constructor | |
273 */ | |
274 var CalculatingLabel = function(element) { | |
yoshiki
2013/09/06 06:56:03
This should be move to PreviewPanel class like "Pr
yoshiki
2013/09/06 06:56:03
How about renaming it to "CalculatingSizeLabel"? J
hirono
2013/09/09 07:15:06
Done.
hirono
2013/09/09 07:15:06
Done.
| |
275 this.element_ = element; | |
276 this.count_ = 0; | |
277 this.intervalID_ = null; | |
278 Object.seal(this); | |
279 }; | |
280 | |
281 /** | |
282 * Period in milliseconds. | |
283 * @const {number} | |
284 */ | |
285 CalculatingLabel.PERIOD = 500; | |
286 | |
287 CalculatingLabel.prototype = { | |
288 /** | |
289 * Set visibility of the label. | |
290 * When it is displayed, the text is animated. | |
291 * @param {boolean} hidden Whether to hide the label or not. | |
292 */ | |
293 set hidden(hidden) { | |
294 this.element_.hidden = hidden; | |
295 if (!hidden) { | |
296 if (this.intervalID_ != null) | |
297 return; | |
298 this.count_ = 2; | |
299 this.intervalID_ = | |
300 setInterval(this.onStep_.bind(this), CalculatingLabel.PERIOD); | |
301 this.onStep_(); | |
302 } else { | |
303 if (this.intervalID_ == null) | |
304 return; | |
305 clearInterval(this.intervalID_); | |
306 this.intervalID_ = null; | |
307 } | |
308 } | |
309 }; | |
310 | |
311 /** | |
312 * @private | |
313 */ | |
314 CalculatingLabel.prototype.onStep_ = function() { | |
315 var text = str('CALCULATING_SIZE'); | |
316 for (var i = 0; i < ~~(this.count_ / 2) % 4; i++) { | |
317 text += '.'; | |
318 } | |
319 this.element_.textContent = text; | |
320 this.count_++; | |
321 }; | |
OLD | NEW |