Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(468)

Side by Side Diff: chrome/browser/resources/file_manager/js/butter_bar.js

Issue 10826137: Fix CSS and timeout handling for the Files app butter bar (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 /** 5 /**
6 * The minimum about of time to display the butter bar for, in ms. 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 7 * Justification is 1000ms for minimum display time plus 300ms for transition
8 * duration. 8 * duration.
9 */ 9 */
10 var MINIMUM_BUTTER_DISPLAY_TIME_MS = 1300; 10 var MINIMUM_BUTTER_DISPLAY_TIME_MS = 1300;
11 11
12 /** 12 /**
13 * Butter bar is shown on top of the file list and is used to show the copy 13 * Butter bar is shown on top of the file list and is used to show the copy
14 * progress and other messages. 14 * progress and other messages.
15 * @constructor 15 * @constructor
16 * @param {HTMLElement} dialogDom FileManager top-level div. 16 * @param {HTMLElement} dialogDom FileManager top-level div.
17 * @param {FileCopyManagerWrapper} copyManager The copy manager. 17 * @param {FileCopyManagerWrapper} copyManager The copy manager.
18 */ 18 */
19 function ButterBar(dialogDom, copyManager) { 19 function ButterBar(dialogDom, copyManager) {
20 this.dialogDom_ = dialogDom; 20 this.dialogDom_ = dialogDom;
21 this.butter_ = this.dialogDom_.querySelector('#butter-bar'); 21 this.butter_ = this.dialogDom_.querySelector('#butter-bar');
22 this.document_ = this.butter_.ownerDocument; 22 this.document_ = this.butter_.ownerDocument;
23 this.copyManager_ = copyManager; 23 this.copyManager_ = copyManager;
24 this.hideTimeout_ = null; 24 this.hideTimeout_ = null;
25 this.showTimeout_ = null; 25 this.showTimeout_ = null;
26 this.visible_ = false;
27 this.lastShowTime_ = 0; 26 this.lastShowTime_ = 0;
28 this.isError_ = false;
29 27
30 this.copyManager_.addEventListener('copy-progress', 28 this.copyManager_.addEventListener('copy-progress',
31 this.onCopyProgress_.bind(this)); 29 this.onCopyProgress_.bind(this));
32 } 30 }
33 31
34 /** 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 /**
35 * Show butter bar. 49 * Show butter bar.
36 * @param {string} message The message to be shown. 50 * @param {string} message The message to be shown.
37 * @param {object} opt_options Options: 'actions', 'progress', 'timeout'. 51 * @param {object} opt_options Options: 'actions', 'progress', 'timeout'.
38 */ 52 */
39 ButterBar.prototype.show = function(message, opt_options) { 53 ButterBar.prototype.show = function(message, opt_options) {
40 if (opt_options) { 54 this.clearShowTimeout_();
41 if ('actions' in opt_options) { 55 this.clearHideTimeout_();
42 var actions = this.butter_.querySelector('.actions'); 56
43 while (actions.childNodes.length) 57 var actions = this.butter_.querySelector('.actions');
44 actions.removeChild(actions.firstChild); 58 actions.textContent = '';
45 for (var label in opt_options.actions) { 59 if (opt_options && 'actions' in opt_options) {
46 var link = this.document_.createElement('a'); 60 for (var label in opt_options.actions) {
47 link.addEventListener('click', function() { 61 var link = this.document_.createElement('a');
48 opt_options.actions[label](); 62 link.addEventListener('click', function(callback) {
49 return false; 63 callback();
50 }); 64 return false;
51 actions.appendChild(link); 65 }.bind(null, opt_options.actions[label]));
52 } 66 actions.appendChild(link);
53 actions.classList.remove('hide-in-butter');
54 } 67 }
55 if ('progress' in opt_options) { 68 actions.hidden = false;
56 this.butter_.querySelector('.progress-bar').classList.remove( 69 } else {
57 'hide-in-butter'); 70 actions.hidden = true;
58 }
59 } 71 }
60 72
61 this.visible_ = true; 73 this.butter_.querySelector('.progress-bar').hidden =
62 this.isError_ = false; 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_
63 this.update_(message, opt_options); 78 this.update_(message, opt_options);
64 this.lastShowTime_ = Date.now();
65 }; 79 };
66 80
67 /** 81 /**
68 * Show error message in butter bar. 82 * Show error message in butter bar.
69 * @private 83 * @private
70 * @param {string} message Message. 84 * @param {string} message Message.
71 * @param {object} opt_options Same as in show(). 85 * @param {object} opt_options Same as in show().
72 */ 86 */
73 ButterBar.prototype.showError_ = function(message, opt_options) { 87 ButterBar.prototype.showError_ = function(message, opt_options) {
74 this.show(message, opt_options); 88 this.show(message, opt_options);
75 this.isError_ = true;
76 this.butter_.classList.add('error'); 89 this.butter_.classList.add('error');
77 }; 90 };
78 91
79 /** 92 /**
80 * Set message and/or progress. 93 * Set message and/or progress.
81 * @private 94 * @private
82 * @param {string} message Message. 95 * @param {string} message Message.
83 * @param {object} opt_options Same as in show(). 96 * @param {object} opt_options Same as in show().
84 */ 97 */
85 ButterBar.prototype.update_ = function(message, opt_options) { 98 ButterBar.prototype.update_ = function(message, opt_options) {
86 if (!opt_options) 99 if (!opt_options)
87 opt_options = {}; 100 opt_options = {};
88 101
102 this.clearHideTimeout_();
103
89 var timeout = ('timeout' in opt_options) ? opt_options.timeout : 10 * 1000; 104 var timeout = ('timeout' in opt_options) ? opt_options.timeout : 10 * 1000;
90
91 if (this.hideTimeout_)
92 clearTimeout(this.hideTimeout_);
93
94 if (timeout) { 105 if (timeout) {
95 this.hideTimeout_ = setTimeout(function() { 106 this.hideTimeout_ = setTimeout(function() {
96 this.hideButter(); 107 this.hideTimeout_ = null;
97 this.hideTimeout_ = null; 108 this.hide_();
98 }.bind(this), timeout); 109 }.bind(this), timeout);
99 } 110 }
100 111
101 this.butter_.querySelector('.butter-message').textContent = message; 112 this.butter_.querySelector('.butter-message').textContent = message;
102 if (message) { 113 if (message && !this.isVisible_()) {
103 // The butter bar is made visible on the first non-empty message. 114 // The butter bar is made visible on the first non-empty message.
104 this.butter_.classList.remove('before-show'); 115 this.butter_.classList.add('visible');
116 this.lastShowTime_ = Date.now();
105 } 117 }
106 if (opt_options && 'progress' in opt_options) { 118 if (opt_options && 'progress' in opt_options) {
107 this.butter_.querySelector('.progress-track').style.width = 119 this.butter_.querySelector('.progress-track').style.width =
108 (opt_options.progress * 100) + '%'; 120 (opt_options.progress * 100) + '%';
109 } 121 }
110 122
111 this.butter_.style.left = 123 this.butter_.style.left =
112 (this.dialogDom_.clientWidth - this.butter_.clientWidth) / 2 + 'px'; 124 (this.dialogDom_.clientWidth - this.butter_.clientWidth) / 2 + 'px';
113 }; 125 };
114 126
115 /** 127 /**
116 * Hide butter bar. There might be some delay before hiding so that butter bar 128 * 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. 129 * would be shown for no less than the minimal time.
130 * @param {boolean} opt_force If true hide immediately.
118 * @private 131 * @private
119 */ 132 */
120 ButterBar.prototype.hide_ = function() { 133 ButterBar.prototype.hide_ = function(opt_force) {
121 if (this.visible_) { 134 this.clearHideTimeout_();
122 var delay = Math.max(
123 MINIMUM_BUTTER_DISPLAY_TIME_MS - (Date.now() - this.lastShowTime_), 0);
124 135
125 var butter = this.butter_; 136 if (!this.isVisible_())
137 return;
126 138
127 function hideButter() { 139 var delay =
128 butter.classList.remove('error'); 140 MINIMUM_BUTTER_DISPLAY_TIME_MS - (Date.now() - this.lastShowTime_);
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 141
135 setTimeout(function() { butter.classList.add('after-show'); }, delay); 142 if (opt_force || delay <= 0) {
136 setTimeout(hideButter, delay + 1000); 143 this.butter_.classList.remove('visible');
137 this.visible_ = false; 144 } else {
145 // Reschedule hide to comply with the minimal display time.
146 this.hideTimeout_ = setTimeout(function() {
147 this.hideTimeout_ = null;
148 this.hide_(true);
149 }.bind(this), delay);
138 } 150 }
139 }; 151 };
140 152
141 /** 153 /**
142 * If butter bar shows an error message, close it. 154 * If butter bar shows an error message, close it.
143 * @return {boolean} True if butter bar was closed. 155 * @return {boolean} True if butter bar was closed.
144 */ 156 */
145 ButterBar.prototype.hideError = function() { 157 ButterBar.prototype.hideError = function() {
146 if (this.visible_ && this.isError_) { 158 if (this.isVisible_() && this.isError_()) {
147 this.hide_(); 159 this.hide_(true /* force */);
148 clearTimeout(this.hideTimeout_);
149 return true; 160 return true;
150 } else { 161 } else {
151 return false; 162 return false;
152 } 163 }
153 }; 164 };
154 165
155 /** 166 /**
156 * Init butter bar for showing copy progress. 167 * Clear the show timeout if it is set.
157 * @private 168 * @private
158 */ 169 */
159 ButterBar.prototype.init_ = function() { 170 ButterBar.prototype.clearShowTimeout_ = function() {
171 if (this.showTimeout_) {
172 clearTimeout(this.hideTimeout_);
173 this.showTimeout_ = null;
174 }
175 };
176
177 /**
178 * Clear the hide timeout if it is set.
179 * @private
180 */
181 ButterBar.prototype.clearHideTimeout_ = function() {
182 if (this.hideTimeout_) {
183 clearTimeout(this.hideTimeout_);
184 this.hideTimeout_ = null;
185 }
186 };
187
188 /**
189 * Set up butter bar for showing copy progress.
190 * @private
191 */
192 ButterBar.prototype.showProgress_ = function() {
160 var progress = this.copyManager_.getProgress(); 193 var progress = this.copyManager_.getProgress();
161 var options = {progress: progress.percentage, actions: {}, timeout: 0}; 194 var options = {progress: progress.percentage, actions: {}, timeout: 0};
162 options.actions[str('CANCEL_LABEL')] = 195 options.actions[str('CANCEL_LABEL')] =
163 this.copyManager_.requestCancel.bind(this.copyManager_); 196 this.copyManager_.requestCancel.bind(this.copyManager_);
164 this.show(strf('PASTE_ITEMS_REMAINING', progress.pendingItems), options); 197 this.show(strf('PASTE_ITEMS_REMAINING', progress.pendingItems), options);
165 }; 198 };
166 199
167 /** 200 /**
168 * 'copy-progress' event handler. Show progress or an appropriate message. 201 * 'copy-progress' event handler. Show progress or an appropriate message.
169 * @private 202 * @private
170 * @param {cr.Event} event A 'copy-progress' event from FileCopyManager. 203 * @param {cr.Event} event A 'copy-progress' event from FileCopyManager.
171 */ 204 */
172 ButterBar.prototype.onCopyProgress_ = function(event) { 205 ButterBar.prototype.onCopyProgress_ = function(event) {
173 var progress = this.copyManager_.getProgress(); 206 var progress = this.copyManager_.getProgress();
174 207
208 if (event.reason != 'PROGRESS')
209 this.clearShowTimeout_();
210
175 switch (event.reason) { 211 switch (event.reason) {
176 case 'BEGIN': 212 case 'BEGIN':
177 this.hide_(); 213 this.showTimeout_ = setTimeout(function() {
178 clearTimeout(this.timeout_); 214 this.showTimeout_ = null;
179 // If the copy process lasts more than 500 ms, we show a progress bar. 215 this.showProgress_();
180 this.showTimeout_ = setTimeout(this.init_.bind(this), 500); 216 }.bind(this), 500);
181 break; 217 break;
182 218
183 case 'PROGRESS': 219 case 'PROGRESS':
184 if (this.visible_) { 220 if (this.isVisible_()) {
185 var options = {'progress': progress.percentage, timeout: 0}; 221 var options = {'progress': progress.percentage, timeout: 0};
186 this.update_(strf('PASTE_ITEMS_REMAINING', progress.pendingItems), 222 this.update_(strf('PASTE_ITEMS_REMAINING', progress.pendingItems),
187 options); 223 options);
188 } 224 }
189 break; 225 break;
190 226
191 case 'SUCCESS': 227 case 'SUCCESS':
192 clearTimeout(this.showTimeout_);
193 this.hide_(); 228 this.hide_();
194 break; 229 break;
195 230
196 case 'CANCELLED': 231 case 'CANCELLED':
197 this.show(str('PASTE_CANCELLED'), {timeout: 1000}); 232 this.show(str('PASTE_CANCELLED'), {timeout: 1000});
198 break; 233 break;
199 234
200 case 'ERROR': 235 case 'ERROR':
201 clearTimeout(this.showTimeout_);
202 if (event.error.reason === 'TARGET_EXISTS') { 236 if (event.error.reason === 'TARGET_EXISTS') {
203 var name = event.error.data.name; 237 var name = event.error.data.name;
204 if (event.error.data.isDirectory) 238 if (event.error.data.isDirectory)
205 name += '/'; 239 name += '/';
206 this.showError_(strf('PASTE_TARGET_EXISTS_ERROR', name)); 240 this.showError_(strf('PASTE_TARGET_EXISTS_ERROR', name));
207 } else if (event.error.reason === 'FILESYSTEM_ERROR') { 241 } else if (event.error.reason === 'FILESYSTEM_ERROR') {
208 if (event.error.data.toGDrive && 242 if (event.error.data.toGDrive &&
209 event.error.data.code === FileError.QUOTA_EXCEEDED_ERR) { 243 event.error.data.code === FileError.QUOTA_EXCEEDED_ERR) {
210 // The alert will be shown in FileManager.onCopyProgress_. 244 // The alert will be shown in FileManager.onCopyProgress_.
211 this.hide_(); 245 this.hide_();
212 } else { 246 } else {
213 this.showError_(strf('PASTE_FILESYSTEM_ERROR', 247 this.showError_(strf('PASTE_FILESYSTEM_ERROR',
214 getFileErrorString(event.error.data.code))); 248 getFileErrorString(event.error.data.code)));
215 } 249 }
216 } else { 250 } else {
217 this.showError_(strf('PASTE_UNEXPECTED_ERROR', event.error)); 251 this.showError_(strf('PASTE_UNEXPECTED_ERROR', event.error));
218 } 252 }
219 break; 253 break;
220 254
221 default: 255 default:
222 console.log('Unknown "copy-progress" event reason: ' + event.reason); 256 console.log('Unknown "copy-progress" event reason: ' + event.reason);
223 } 257 }
224 }; 258 };
OLDNEW
« no previous file with comments | « chrome/browser/resources/file_manager/css/file_manager.css ('k') | chrome/browser/resources/file_manager/main.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698