| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * The minimum about of time to display the butter bar for, in ms. | |
| 7 * Justification is 1000ms for minimum display time plus 300ms for transition | |
| 8 * duration. | |
| 9 */ | |
| 10 var MINIMUM_BUTTER_DISPLAY_TIME_MS = 1300; | |
| 11 | |
| 12 /** | |
| 13 * Butter bar is shown on top of the file list and is used to show the copy | |
| 14 * progress and other messages. | |
| 15 * @constructor | |
| 16 * @param {HTMLElement} dialogDom FileManager top-level div. | |
| 17 * @param {FileCopyManagerWrapper} copyManager The copy manager. | |
| 18 */ | |
| 19 function ButterBar(dialogDom, copyManager) { | |
| 20 this.dialogDom_ = dialogDom; | |
| 21 this.butter_ = this.dialogDom_.querySelector('#butter-bar'); | |
| 22 this.document_ = this.butter_.ownerDocument; | |
| 23 this.copyManager_ = copyManager; | |
| 24 this.hideTimeout_ = null; | |
| 25 this.showTimeout_ = null; | |
| 26 this.lastShowTime_ = 0; | |
| 27 | |
| 28 this.copyManager_.addEventListener('copy-progress', | |
| 29 this.onCopyProgress_.bind(this)); | |
| 30 } | |
| 31 | |
| 32 /** | |
| 33 * @return {boolean} True if visible. | |
| 34 * @private | |
| 35 */ | |
| 36 ButterBar.prototype.isVisible_ = function() { | |
| 37 return this.butter_.classList.contains('visible'); | |
| 38 }; | |
| 39 | |
| 40 /** | |
| 41 * @return {boolean} True if displaying an error. | |
| 42 * @private | |
| 43 */ | |
| 44 ButterBar.prototype.isError_ = function() { | |
| 45 return this.butter_.classList.contains('error'); | |
| 46 }; | |
| 47 | |
| 48 /** | |
| 49 * Show butter bar. | |
| 50 * @param {string} message The message to be shown. | |
| 51 * @param {object} opt_options Options: 'actions', 'progress', 'timeout'. | |
| 52 */ | |
| 53 ButterBar.prototype.show = function(message, opt_options) { | |
| 54 this.clearShowTimeout_(); | |
| 55 this.clearHideTimeout_(); | |
| 56 | |
| 57 var actions = this.butter_.querySelector('.actions'); | |
| 58 actions.textContent = ''; | |
| 59 if (opt_options && 'actions' in opt_options) { | |
| 60 for (var label in opt_options.actions) { | |
| 61 var link = this.document_.createElement('a'); | |
| 62 link.addEventListener('click', function(callback) { | |
| 63 callback(); | |
| 64 return false; | |
| 65 }.bind(null, opt_options.actions[label])); | |
| 66 actions.appendChild(link); | |
| 67 } | |
| 68 actions.hidden = false; | |
| 69 } else { | |
| 70 actions.hidden = true; | |
| 71 } | |
| 72 | |
| 73 this.butter_.querySelector('.progress-bar').hidden = | |
| 74 !(opt_options && 'progress' in opt_options); | |
| 75 | |
| 76 this.butter_.classList.remove('error'); | |
| 77 this.butter_.classList.remove('visible'); // Will be shown in update_ | |
| 78 this.update_(message, opt_options); | |
| 79 }; | |
| 80 | |
| 81 /** | |
| 82 * Show error message in butter bar. | |
| 83 * @private | |
| 84 * @param {string} message Message. | |
| 85 * @param {object} opt_options Same as in show(). | |
| 86 */ | |
| 87 ButterBar.prototype.showError_ = function(message, opt_options) { | |
| 88 this.show(message, opt_options); | |
| 89 this.butter_.classList.add('error'); | |
| 90 }; | |
| 91 | |
| 92 /** | |
| 93 * Set message and/or progress. | |
| 94 * @private | |
| 95 * @param {string} message Message. | |
| 96 * @param {object} opt_options Same as in show(). | |
| 97 */ | |
| 98 ButterBar.prototype.update_ = function(message, opt_options) { | |
| 99 if (!opt_options) | |
| 100 opt_options = {}; | |
| 101 | |
| 102 this.clearHideTimeout_(); | |
| 103 | |
| 104 var timeout = ('timeout' in opt_options) ? opt_options.timeout : 10 * 1000; | |
| 105 if (timeout) { | |
| 106 this.hideTimeout_ = setTimeout(function() { | |
| 107 this.hideTimeout_ = null; | |
| 108 this.hide_(); | |
| 109 }.bind(this), timeout); | |
| 110 } | |
| 111 | |
| 112 this.butter_.querySelector('.butter-message').textContent = message; | |
| 113 if (message && !this.isVisible_()) { | |
| 114 // The butter bar is made visible on the first non-empty message. | |
| 115 this.butter_.classList.add('visible'); | |
| 116 this.lastShowTime_ = Date.now(); | |
| 117 } | |
| 118 if (opt_options && 'progress' in opt_options) { | |
| 119 this.butter_.querySelector('.progress-track').style.width = | |
| 120 (opt_options.progress * 100) + '%'; | |
| 121 } | |
| 122 }; | |
| 123 | |
| 124 /** | |
| 125 * Hide butter bar. There might be some delay before hiding so that butter bar | |
| 126 * would be shown for no less than the minimal time. | |
| 127 * @param {boolean} opt_force If true hide immediately. | |
| 128 * @private | |
| 129 */ | |
| 130 ButterBar.prototype.hide_ = function(opt_force) { | |
| 131 this.clearHideTimeout_(); | |
| 132 | |
| 133 if (!this.isVisible_()) | |
| 134 return; | |
| 135 | |
| 136 var delay = | |
| 137 MINIMUM_BUTTER_DISPLAY_TIME_MS - (Date.now() - this.lastShowTime_); | |
| 138 | |
| 139 if (opt_force || delay <= 0) { | |
| 140 this.butter_.classList.remove('visible'); | |
| 141 } else { | |
| 142 // Reschedule hide to comply with the minimal display time. | |
| 143 this.hideTimeout_ = setTimeout(function() { | |
| 144 this.hideTimeout_ = null; | |
| 145 this.hide_(true); | |
| 146 }.bind(this), delay); | |
| 147 } | |
| 148 }; | |
| 149 | |
| 150 /** | |
| 151 * If butter bar shows an error message, close it. | |
| 152 * @return {boolean} True if butter bar was closed. | |
| 153 */ | |
| 154 ButterBar.prototype.hideError = function() { | |
| 155 if (this.isVisible_() && this.isError_()) { | |
| 156 this.hide_(true /* force */); | |
| 157 return true; | |
| 158 } else { | |
| 159 return false; | |
| 160 } | |
| 161 }; | |
| 162 | |
| 163 /** | |
| 164 * Clear the show timeout if it is set. | |
| 165 * @private | |
| 166 */ | |
| 167 ButterBar.prototype.clearShowTimeout_ = function() { | |
| 168 if (this.showTimeout_) { | |
| 169 clearTimeout(this.showTimeout_); | |
| 170 this.showTimeout_ = null; | |
| 171 } | |
| 172 }; | |
| 173 | |
| 174 /** | |
| 175 * Clear the hide timeout if it is set. | |
| 176 * @private | |
| 177 */ | |
| 178 ButterBar.prototype.clearHideTimeout_ = function() { | |
| 179 if (this.hideTimeout_) { | |
| 180 clearTimeout(this.hideTimeout_); | |
| 181 this.hideTimeout_ = null; | |
| 182 } | |
| 183 }; | |
| 184 | |
| 185 /** | |
| 186 * @private | |
| 187 * @return {string?} The type of operation. | |
| 188 */ | |
| 189 ButterBar.prototype.transferType_ = function() { | |
| 190 var progress = this.progress_; | |
| 191 if (!progress || | |
| 192 progress.pendingMoves === 0 && progress.pendingCopies === 0) | |
| 193 return 'TRANSFER'; | |
| 194 | |
| 195 if (progress.pendingMoves > 0) { | |
| 196 if (progress.pendingCopies > 0) | |
| 197 return 'TRANSFER'; | |
| 198 return 'MOVE'; | |
| 199 } | |
| 200 | |
| 201 return 'COPY'; | |
| 202 }; | |
| 203 | |
| 204 /** | |
| 205 * Set up butter bar for showing copy progress. | |
| 206 * @private | |
| 207 */ | |
| 208 ButterBar.prototype.showProgress_ = function() { | |
| 209 this.progress_ = this.copyManager_.getStatus(); | |
| 210 var options = {progress: this.progress_.percentage, actions: {}, timeout: 0}; | |
| 211 | |
| 212 var type = this.transferType_(); | |
| 213 var progressString = (this.progress_.pendingItems === 1) ? | |
| 214 strf(type + '_FILE_NAME', this.progress_.filename) : | |
| 215 strf(type + '_ITEMS_REMAINING', this.progress_.pendingItems); | |
| 216 | |
| 217 if (this.isVisible_()) { | |
| 218 this.update_(progressString, options); | |
| 219 } else { | |
| 220 options.actions[str('CANCEL_LABEL')] = | |
| 221 this.copyManager_.requestCancel.bind(this.copyManager_); | |
| 222 this.show(progressString, options); | |
| 223 } | |
| 224 }; | |
| 225 | |
| 226 /** | |
| 227 * 'copy-progress' event handler. Show progress or an appropriate message. | |
| 228 * @private | |
| 229 * @param {cr.Event} event A 'copy-progress' event from FileCopyManager. | |
| 230 */ | |
| 231 ButterBar.prototype.onCopyProgress_ = function(event) { | |
| 232 if (event.reason != 'PROGRESS') | |
| 233 this.clearShowTimeout_(); | |
| 234 | |
| 235 switch (event.reason) { | |
| 236 case 'BEGIN': | |
| 237 this.showTimeout_ = setTimeout(function() { | |
| 238 this.showTimeout_ = null; | |
| 239 this.showProgress_(); | |
| 240 }.bind(this), 500); | |
| 241 break; | |
| 242 | |
| 243 case 'PROGRESS': | |
| 244 this.showProgress_(); | |
| 245 break; | |
| 246 | |
| 247 case 'SUCCESS': | |
| 248 this.hide_(); | |
| 249 break; | |
| 250 | |
| 251 case 'CANCELLED': | |
| 252 this.show(str(this.transferType_() + '_CANCELLED'), {timeout: 1000}); | |
| 253 break; | |
| 254 | |
| 255 case 'ERROR': | |
| 256 if (event.error.reason === 'TARGET_EXISTS') { | |
| 257 var name = event.error.data.name; | |
| 258 if (event.error.data.isDirectory) | |
| 259 name += '/'; | |
| 260 this.showError_(strf(this.transferType_() + | |
| 261 '_TARGET_EXISTS_ERROR', name)); | |
| 262 } else if (event.error.reason === 'FILESYSTEM_ERROR') { | |
| 263 if (event.error.data.toGDrive && | |
| 264 event.error.data.code === FileError.QUOTA_EXCEEDED_ERR) { | |
| 265 // The alert will be shown in FileManager.onCopyProgress_. | |
| 266 this.hide_(); | |
| 267 } else { | |
| 268 this.showError_(strf(this.transferType_() + '_FILESYSTEM_ERROR', | |
| 269 util.getFileErrorString(event.error.data.code))); | |
| 270 } | |
| 271 } else { | |
| 272 this.showError_(strf(this.transferType_() + '_UNEXPECTED_ERROR', | |
| 273 event.error)); | |
| 274 } | |
| 275 break; | |
| 276 | |
| 277 default: | |
| 278 console.log('Unknown "copy-progress" event reason: ' + event.reason); | |
| 279 } | |
| 280 }; | |
| OLD | NEW |