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 {PreviewPanel.CalculatingSizeLabel} |
| 59 * @private |
| 60 */ |
| 61 this.calculatingSizeLabel_ = new PreviewPanel.CalculatingSizeLabel( |
| 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. | |
116 * @param {Array.<Entry>} entries New entries. | |
117 */ | |
118 set entries(entries) { | |
119 this.entries_ = entries; | |
120 this.updateVisibility_(); | |
121 }, | |
122 | |
123 /** | |
124 * Setter for the current path. | 123 * Setter for the current path. |
125 * @param {string} path New path. | 124 * @param {string} path New path. |
126 */ | 125 */ |
127 set currentPath(path) { | 126 set currentPath(path) { |
128 this.currentPath_ = path; | 127 this.currentPath_ = path; |
129 this.updateVisibility_(); | 128 this.updateVisibility_(); |
130 }, | 129 }, |
131 | 130 |
132 /** | 131 /** |
133 * Setter for the visibility type. | 132 * Setter for the visibility type. |
(...skipping 19 matching lines...) Expand all Loading... |
153 return this.height_; | 152 return this.height_; |
154 } | 153 } |
155 }; | 154 }; |
156 | 155 |
157 /** | 156 /** |
158 * Initializes the element. | 157 * Initializes the element. |
159 */ | 158 */ |
160 PreviewPanel.prototype.initialize = function() { | 159 PreviewPanel.prototype.initialize = function() { |
161 this.element_.addEventListener('webkitTransitionEnd', | 160 this.element_.addEventListener('webkitTransitionEnd', |
162 this.onTransitionEnd_.bind(this)); | 161 this.onTransitionEnd_.bind(this)); |
| 162 this.updatePreviewText_(); |
163 this.updateVisibility_(); | 163 this.updateVisibility_(); |
164 }; | 164 }; |
165 | 165 |
166 /** | 166 /** |
| 167 * Apply the selection and update the view of the preview panel. |
| 168 * @param {FileSelection} selection Selection to be applied. |
| 169 */ |
| 170 PreviewPanel.prototype.setSelection = function(selection) { |
| 171 this.sequence_++; |
| 172 this.selection_ = selection; |
| 173 this.updateVisibility_(); |
| 174 this.updatePreviewText_(); |
| 175 }; |
| 176 |
| 177 /** |
167 * Update the visibility of the preview panel. | 178 * Update the visibility of the preview panel. |
168 * @private | 179 * @private |
169 */ | 180 */ |
170 PreviewPanel.prototype.updateVisibility_ = function() { | 181 PreviewPanel.prototype.updateVisibility_ = function() { |
171 // Get the new visibility value. | 182 // Get the new visibility value. |
172 var visibility = this.element_.getAttribute('visibility'); | 183 var visibility = this.element_.getAttribute('visibility'); |
173 var newVisible = null; | 184 var newVisible = null; |
174 switch (this.visibilityType_) { | 185 switch (this.visibilityType_) { |
175 case PreviewPanel.VisibilityType.ALWAYS_VISIBLE: | 186 case PreviewPanel.VisibilityType.ALWAYS_VISIBLE: |
176 newVisible = true; | 187 newVisible = true; |
177 break; | 188 break; |
178 case PreviewPanel.VisibilityType.AUTO: | 189 case PreviewPanel.VisibilityType.AUTO: |
179 newVisible = this.entries_.length != 0 || | 190 newVisible = this.selection_.entries.length != 0 || |
180 !PathUtil.isRootPath(this.currentPath_); | 191 !PathUtil.isRootPath(this.currentPath_); |
181 break; | 192 break; |
182 case PreviewPanel.VisibilityType.ALWAYS_HIDDEN: | 193 case PreviewPanel.VisibilityType.ALWAYS_HIDDEN: |
183 newVisible = false; | 194 newVisible = false; |
184 break; | 195 break; |
185 default: | 196 default: |
186 console.error('Invalid visibilityType.'); | 197 console.error('Invalid visibilityType.'); |
187 return; | 198 return; |
188 } | 199 } |
189 | 200 |
190 // If the visibility has been already the new value, just return. | 201 // If the visibility has been already the new value, just return. |
191 if ((visibility == PreviewPanel.Visibility_.VISIBLE && newVisible) || | 202 if ((visibility == PreviewPanel.Visibility_.VISIBLE && newVisible) || |
192 (visibility == PreviewPanel.Visibility_.HIDDEN && !newVisible)) | 203 (visibility == PreviewPanel.Visibility_.HIDDEN && !newVisible)) |
193 return; | 204 return; |
194 | 205 |
195 // Set the new visibility value. | 206 // Set the new visibility value. |
196 if (newVisible) { | 207 if (newVisible) { |
197 this.element_.setAttribute('visibility', PreviewPanel.Visibility_.VISIBLE); | 208 this.element_.setAttribute('visibility', PreviewPanel.Visibility_.VISIBLE); |
198 cr.dispatchSimpleEvent(this, PreviewPanel.Event.VISIBILITY_CHANGE); | 209 cr.dispatchSimpleEvent(this, PreviewPanel.Event.VISIBILITY_CHANGE); |
199 } else { | 210 } else { |
200 this.element_.setAttribute('visibility', PreviewPanel.Visibility_.HIDING); | 211 this.element_.setAttribute('visibility', PreviewPanel.Visibility_.HIDING); |
201 } | 212 } |
202 }; | 213 }; |
203 | 214 |
204 /** | 215 /** |
| 216 * Update the text in the preview panel. |
| 217 * @private |
| 218 */ |
| 219 PreviewPanel.prototype.updatePreviewText_ = function() { |
| 220 var selection = this.selection_; |
| 221 |
| 222 // Hides the preview text if zero or one file is selected. We shows a |
| 223 // breadcrumb list instead on the preview panel. |
| 224 if (selection.totalCount <= 1) { |
| 225 this.calculatingSizeLabel_.hidden = true; |
| 226 this.previewText_.textContent = ''; |
| 227 return; |
| 228 } |
| 229 |
| 230 // Obtains the preview text. |
| 231 var text; |
| 232 if (selection.directoryCount == 0) |
| 233 text = strf('MANY_FILES_SELECTED', selection.fileCount); |
| 234 else if (selection.fileCount == 0) |
| 235 text = strf('MANY_DIRECTORIES_SELECTED', selection.directoryCount); |
| 236 else |
| 237 text = strf('MANY_ENTRIES_SELECTED', selection.totalCount); |
| 238 |
| 239 // Obtains the size of files. |
| 240 this.calculatingSizeLabel_.hidden = selection.bytesKnown; |
| 241 if (selection.bytesKnown && selection.showBytes) |
| 242 text += ', ' + util.bytesToString(selection.bytes); |
| 243 |
| 244 // Set the preview text to the element. |
| 245 this.previewText_.textContent = text; |
| 246 |
| 247 // Request the byte calculation if needed. |
| 248 if (!selection.bytesKnown) { |
| 249 this.selection_.computeBytes(function(sequence) { |
| 250 // Selection has been already updated. |
| 251 if (this.sequence_ != sequence) |
| 252 return; |
| 253 this.updatePreviewText_(); |
| 254 }.bind(this, this.sequence_)); |
| 255 } |
| 256 }; |
| 257 |
| 258 /** |
205 * Event handler to be called at the end of hiding transition. | 259 * Event handler to be called at the end of hiding transition. |
206 * @param {Event} event The webkitTransitionEnd event. | 260 * @param {Event} event The webkitTransitionEnd event. |
207 * @private | 261 * @private |
208 */ | 262 */ |
209 PreviewPanel.prototype.onTransitionEnd_ = function(event) { | 263 PreviewPanel.prototype.onTransitionEnd_ = function(event) { |
210 if (event.target != this.element_ || event.propertyName != 'opacity') | 264 if (event.target != this.element_ || event.propertyName != 'opacity') |
211 return; | 265 return; |
212 var visibility = this.element_.getAttribute('visibility'); | 266 var visibility = this.element_.getAttribute('visibility'); |
213 if (visibility != PreviewPanel.Visibility_.HIDING) | 267 if (visibility != PreviewPanel.Visibility_.HIDING) |
214 return; | 268 return; |
215 this.element_.setAttribute('visibility', PreviewPanel.Visibility_.HIDDEN); | 269 this.element_.setAttribute('visibility', PreviewPanel.Visibility_.HIDDEN); |
216 cr.dispatchSimpleEvent(this, PreviewPanel.Event.VISIBILITY_CHANGE); | 270 cr.dispatchSimpleEvent(this, PreviewPanel.Event.VISIBILITY_CHANGE); |
217 }; | 271 }; |
| 272 |
| 273 /** |
| 274 * Animating label that is shown during the bytes of selection entries is being |
| 275 * calculated. |
| 276 * |
| 277 * This label shows dots and varying the number of dots every |
| 278 * CalculatingSizeLabel.PERIOD milliseconds. |
| 279 * @param {HTMLElement} element DOM element of the label. |
| 280 * @constructor |
| 281 */ |
| 282 PreviewPanel.CalculatingSizeLabel = function(element) { |
| 283 this.element_ = element; |
| 284 this.count_ = 0; |
| 285 this.intervalID_ = null; |
| 286 Object.seal(this); |
| 287 }; |
| 288 |
| 289 /** |
| 290 * Time period in milliseconds. |
| 291 * @const {number} |
| 292 */ |
| 293 PreviewPanel.CalculatingSizeLabel.PERIOD = 500; |
| 294 |
| 295 PreviewPanel.CalculatingSizeLabel.prototype = { |
| 296 /** |
| 297 * Set visibility of the label. |
| 298 * When it is displayed, the text is animated. |
| 299 * @param {boolean} hidden Whether to hide the label or not. |
| 300 */ |
| 301 set hidden(hidden) { |
| 302 this.element_.hidden = hidden; |
| 303 if (!hidden) { |
| 304 if (this.intervalID_ != null) |
| 305 return; |
| 306 this.count_ = 2; |
| 307 this.intervalID_ = |
| 308 setInterval(this.onStep_.bind(this), |
| 309 PreviewPanel.CalculatingSizeLabel.PERIOD); |
| 310 this.onStep_(); |
| 311 } else { |
| 312 if (this.intervalID_ == null) |
| 313 return; |
| 314 clearInterval(this.intervalID_); |
| 315 this.intervalID_ = null; |
| 316 } |
| 317 } |
| 318 }; |
| 319 |
| 320 /** |
| 321 * Increments the counter and updates the number of dots. |
| 322 * @private |
| 323 */ |
| 324 PreviewPanel.CalculatingSizeLabel.prototype.onStep_ = function() { |
| 325 var text = str('CALCULATING_SIZE'); |
| 326 for (var i = 0; i < ~~(this.count_ / 2) % 4; i++) { |
| 327 text += '.'; |
| 328 } |
| 329 this.element_.textContent = text; |
| 330 this.count_++; |
| 331 }; |
OLD | NEW |