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.visible_ = false; |
| 27 this.lastShowTime_ = 0; |
| 28 this.isError_ = false; |
| 29 |
| 30 this.copyManager_.addEventListener('copy-progress', |
| 31 this.onCopyProgress_.bind(this)); |
| 32 } |
| 33 |
| 34 /** |
| 35 * Show butter bar. |
| 36 * @param {string} message The message to be shown. |
| 37 * @param {object} opt_options Options: 'actions', 'progress', 'timeout'. |
| 38 */ |
| 39 ButterBar.prototype.show = function(message, opt_options) { |
| 40 if (opt_options) { |
| 41 if ('actions' in opt_options) { |
| 42 var actions = this.butter_.querySelector('.actions'); |
| 43 while (actions.childNodes.length) |
| 44 actions.removeChild(actions.firstChild); |
| 45 for (var label in opt_options.actions) { |
| 46 var link = this.document_.createElement('a'); |
| 47 link.addEventListener('click', function() { |
| 48 opt_options.actions[label](); |
| 49 return false; |
| 50 }); |
| 51 actions.appendChild(link); |
| 52 } |
| 53 actions.classList.remove('hide-in-butter'); |
| 54 } |
| 55 if ('progress' in opt_options) { |
| 56 this.butter_.querySelector('.progress-bar').classList.remove( |
| 57 'hide-in-butter'); |
| 58 } |
| 59 } |
| 60 |
| 61 this.visible_ = true; |
| 62 this.isError_ = false; |
| 63 this.update_(message, opt_options); |
| 64 this.lastShowTime_ = Date.now(); |
| 65 }; |
| 66 |
| 67 /** |
| 68 * Show error message in butter bar. |
| 69 * @private |
| 70 * @param {string} message Message. |
| 71 * @param {object} opt_options Same as in show(). |
| 72 */ |
| 73 ButterBar.prototype.showError_ = function(message, opt_options) { |
| 74 this.show(message, opt_options); |
| 75 this.isError_ = true; |
| 76 this.butter_.classList.add('error'); |
| 77 }; |
| 78 |
| 79 /** |
| 80 * Set message and/or progress. |
| 81 * @private |
| 82 * @param {string} message Message. |
| 83 * @param {object} opt_options Same as in show(). |
| 84 */ |
| 85 ButterBar.prototype.update_ = function(message, opt_options) { |
| 86 if (!opt_options) |
| 87 opt_options = {}; |
| 88 |
| 89 var timeout = ('timeout' in opt_options) ? opt_options.timeout : 10 * 1000; |
| 90 |
| 91 if (this.hideTimeout_) |
| 92 clearTimeout(this.hideTimeout_); |
| 93 |
| 94 if (timeout) { |
| 95 this.hideTimeout_ = setTimeout(function() { |
| 96 this.hideButter(); |
| 97 this.hideTimeout_ = null; |
| 98 }.bind(this), timeout); |
| 99 } |
| 100 |
| 101 this.butter_.querySelector('.butter-message').textContent = message; |
| 102 if (message) { |
| 103 // The butter bar is made visible on the first non-empty message. |
| 104 this.butter_.classList.remove('before-show'); |
| 105 } |
| 106 if (opt_options && 'progress' in opt_options) { |
| 107 this.butter_.querySelector('.progress-track').style.width = |
| 108 (opt_options.progress * 100) + '%'; |
| 109 } |
| 110 |
| 111 this.butter_.style.left = |
| 112 (this.dialogDom_.clientWidth - this.butter_.clientWidth) / 2 + 'px'; |
| 113 }; |
| 114 |
| 115 /** |
| 116 * Hide butter bar. There might be some delay before hiding so that butter bar |
| 117 * would be shown for no less than the minimal time. |
| 118 * @private |
| 119 */ |
| 120 ButterBar.prototype.hide_ = function() { |
| 121 if (this.visible_) { |
| 122 var delay = Math.max( |
| 123 MINIMUM_BUTTER_DISPLAY_TIME_MS - (Date.now() - this.lastShowTime_), 0); |
| 124 |
| 125 var butter = this.butter_; |
| 126 |
| 127 function hideButter() { |
| 128 butter.classList.remove('error'); |
| 129 butter.classList.remove('after-show'); |
| 130 butter.classList.add('before-show'); |
| 131 butter.querySelector('.actions').classList.add('hide-in-butter'); |
| 132 butter.querySelector('.progress-bar').classList.add('hide-in-butter'); |
| 133 } |
| 134 |
| 135 setTimeout(function() { butter.classList.add('after-show'); }, delay); |
| 136 setTimeout(hideButter, delay + 1000); |
| 137 this.visible_ = false; |
| 138 } |
| 139 }; |
| 140 |
| 141 /** |
| 142 * If butter bar shows an error message, close it. |
| 143 * @return {boolean} True if butter bar was closed. |
| 144 */ |
| 145 ButterBar.prototype.hideError = function() { |
| 146 if (this.visible_ && this.isError_) { |
| 147 this.hide_(); |
| 148 clearTimeout(this.hideTimeout_); |
| 149 return true; |
| 150 } else { |
| 151 return false; |
| 152 } |
| 153 }; |
| 154 |
| 155 /** |
| 156 * Init butter bar for showing copy progress. |
| 157 * @private |
| 158 */ |
| 159 ButterBar.prototype.init_ = function() { |
| 160 var progress = this.copyManager_.getProgress(); |
| 161 var options = {progress: progress.percentage, actions: {}, timeout: 0}; |
| 162 options.actions[str('CANCEL_LABEL')] = |
| 163 this.copyManager_.requestCancel.bind(this.copyManager_); |
| 164 this.show(strf('PASTE_ITEMS_REMAINING', progress.pendingItems), options); |
| 165 }; |
| 166 |
| 167 /** |
| 168 * 'copy-progress' event handler. Show progress or an appropriate message. |
| 169 * @private |
| 170 * @param {cr.Event} event A 'copy-progress' event from FileCopyManager. |
| 171 */ |
| 172 ButterBar.prototype.onCopyProgress_ = function(event) { |
| 173 var progress = this.copyManager_.getProgress(); |
| 174 |
| 175 switch (event.reason) { |
| 176 case 'BEGIN': |
| 177 this.hide_(); |
| 178 clearTimeout(this.timeout_); |
| 179 // If the copy process lasts more than 500 ms, we show a progress bar. |
| 180 this.showTimeout_ = setTimeout(this.init_.bind(this), 500); |
| 181 break; |
| 182 |
| 183 case 'PROGRESS': |
| 184 if (this.visible_) { |
| 185 var options = {'progress': progress.percentage, timeout: 0}; |
| 186 this.update_(strf('PASTE_ITEMS_REMAINING', progress.pendingItems), |
| 187 options); |
| 188 } |
| 189 break; |
| 190 |
| 191 case 'SUCCESS': |
| 192 clearTimeout(this.showTimeout_); |
| 193 this.hide_(); |
| 194 break; |
| 195 |
| 196 case 'CANCELLED': |
| 197 this.show(str('PASTE_CANCELLED'), {timeout: 1000}); |
| 198 break; |
| 199 |
| 200 case 'ERROR': |
| 201 clearTimeout(this.showTimeout_); |
| 202 if (event.error.reason === 'TARGET_EXISTS') { |
| 203 var name = event.error.data.name; |
| 204 if (event.error.data.isDirectory) |
| 205 name += '/'; |
| 206 this.showError_(strf('PASTE_TARGET_EXISTS_ERROR', name)); |
| 207 } else if (event.error.reason === 'FILESYSTEM_ERROR') { |
| 208 if (event.error.data.toGDrive && |
| 209 event.error.data.code === FileError.QUOTA_EXCEEDED_ERR) { |
| 210 // The alert will be shown in FileManager.onCopyProgress_. |
| 211 this.hide_(); |
| 212 } else { |
| 213 this.showError_(strf('PASTE_FILESYSTEM_ERROR', |
| 214 getFileErrorString(event.error.data.code))); |
| 215 } |
| 216 } else { |
| 217 this.showError_(strf('PASTE_UNEXPECTED_ERROR', event.error)); |
| 218 } |
| 219 break; |
| 220 |
| 221 default: |
| 222 console.log('Unknown "copy-progress" event reason: ' + event.reason); |
| 223 } |
| 224 }; |
OLD | NEW |