OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 * Javascript for Snackbar controls, served from chrome://bluetooth-internals/. | 6 * Javascript for Snackbar controls, served from chrome://bluetooth-internals/. |
7 */ | 7 */ |
8 | 8 |
9 cr.define('snackbar', function() { | 9 cr.define('snackbar', function() { |
10 /** @typedef {{ | 10 /** @typedef {{ |
11 * message: string, | 11 * message: string, |
12 * type: string, | 12 * type: string, |
13 * actionText: (string|undefined), | 13 * actionText: (string|undefined), |
14 * action: (function()|undefined) | 14 * action: (function()|undefined) |
15 * }} | 15 * }} |
16 */ | 16 */ |
17 var SnackbarOptions; | 17 var SnackbarOptions; |
18 | 18 |
19 /** @const {number} */ var SHOW_DURATION = 5000; | 19 /** @const {number} */ var SHOW_DURATION = 5000; |
20 /** @const {number} */ var TRANSITION_DURATION = 225; | |
20 | 21 |
21 /** | 22 /** |
22 * Enum of Snackbar types. Used by Snackbar to determine the styling for the | 23 * Enum of Snackbar types. Used by Snackbar to determine the styling for the |
23 * Snackbar. | 24 * Snackbar. |
24 * @enum {string} | 25 * @enum {string} |
25 */ | 26 */ |
26 var SnackbarType = { | 27 var SnackbarType = { |
27 INFO: 'info', | 28 INFO: 'info', |
28 SUCCESS: 'success', | 29 SUCCESS: 'success', |
29 WARNING: 'warning', | 30 WARNING: 'warning', |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 this.classList.add(options.type); | 71 this.classList.add(options.type); |
71 this.actionLink_.textContent = options.actionText || 'Dismiss'; | 72 this.actionLink_.textContent = options.actionText || 'Dismiss'; |
72 | 73 |
73 this.actionLink_.addEventListener('click', function() { | 74 this.actionLink_.addEventListener('click', function() { |
74 if (options.action) options.action(); | 75 if (options.action) options.action(); |
75 this.dismiss(); | 76 this.dismiss(); |
76 }.bind(this)); | 77 }.bind(this)); |
77 }, | 78 }, |
78 | 79 |
79 /** | 80 /** |
80 * Shows the Snackbar. | 81 * Shows the Snackbar and dispatches the 'showed' event. |
81 */ | 82 */ |
82 show: function() { | 83 show: function() { |
83 this.classList.add('open'); | 84 this.classList.add('open'); |
84 if (Snackbar.hasContentFocus_) this.startTimeout_(); | 85 if (Snackbar.hasContentFocus_) this.startTimeout_(); |
85 else this.stopTimeout_(); | 86 else this.stopTimeout_(); |
86 | 87 |
87 document.addEventListener('contentfocus', this.boundStartTimeout_); | 88 document.addEventListener('contentfocus', this.boundStartTimeout_); |
88 document.addEventListener('contentblur', this.boundStopTimeout_); | 89 document.addEventListener('contentblur', this.boundStopTimeout_); |
90 this.dispatchEvent(new CustomEvent('showed')); | |
89 }, | 91 }, |
90 | 92 |
91 /** | 93 /** |
92 * Dismisses the Snackbar. Once the Snackbar is completely hidden, the | 94 * Dismisses the Snackbar. Once the Snackbar is completely hidden, the |
93 * 'dismissed' event is fired. | 95 * 'dismissed' event is fired and the returned Promise is resolved. If the |
96 * snackbar is already hidden, a resolved Promise is returned. | |
97 * @return {!Promise} | |
94 */ | 98 */ |
95 dismiss: function() { | 99 dismiss: function() { |
96 this.addEventListener('webkitTransitionEnd', function(event) { | 100 this.stopTimeout_(); |
97 if (event.propertyName === 'transform') | 101 |
98 this.dispatchEvent(new CustomEvent('dismissed')); | 102 if (!this.classList.contains('open')) { |
103 return Promise.resolve(); | |
104 } | |
Dan Beam
2017/01/04 01:44:09
no curlies
mbrunson
2017/01/04 03:46:19
Done.
| |
105 | |
106 return new Promise(function(resolve) { | |
107 this.boundOnTransitionEnd_ = this.onTransitionEnd_(resolve).bind(this); | |
Dan Beam
2017/01/04 01:44:09
nit: can we use listenOnce from util.js instead?
mbrunson
2017/01/04 03:46:19
Done.
| |
108 this.addEventListener( | |
109 'webkitTransitionEnd', this.boundOnTransitionEnd_); | |
110 | |
111 ensureTransitionEndEvent(this, TRANSITION_DURATION); | |
112 this.classList.remove('open'); | |
113 | |
114 document.removeEventListener('contentfocus', this.boundStartTimeout_); | |
115 document.removeEventListener('contentblur', this.boundStopTimeout_); | |
99 }.bind(this)); | 116 }.bind(this)); |
100 | |
101 ensureTransitionEndEvent(this, SHOW_DURATION); | |
102 this.classList.remove('open'); | |
103 | |
104 document.removeEventListener('contentfocus', this.boundStartTimeout_); | |
105 document.removeEventListener('contentblur', this.boundStopTimeout_); | |
106 }, | 117 }, |
107 | 118 |
108 /** | 119 /** |
120 * Generates a function that dispatches the 'dismissed' event and removes | |
121 * itself from the webkitTransitionEnd event when called. | |
122 * @param {!function()} resolve Promise resolve function. | |
123 * @return {!function()} Function that is called on webkitTransitionEnd. | |
124 */ | |
125 onTransitionEnd_: function(resolve) { | |
126 return function() { | |
127 this.removeEventListener( | |
128 'webkitTransitionEnd', this.boundOnTransitionEnd_); | |
129 this.boundOnTransitionEnd_ = null; | |
130 this.dispatchEvent(new CustomEvent('dismissed')); | |
131 resolve(); | |
132 }; | |
133 }, | |
134 | |
135 /** | |
109 * Starts the timeout for dismissing the Snackbar. | 136 * Starts the timeout for dismissing the Snackbar. |
110 * @private | 137 * @private |
111 */ | 138 */ |
112 startTimeout_: function() { | 139 startTimeout_: function() { |
113 this.timeoutId_ = setTimeout(function() { | 140 this.timeoutId_ = setTimeout(function() { |
114 this.dismiss(); | 141 this.dismiss(); |
115 }.bind(this), SHOW_DURATION); | 142 }.bind(this), SHOW_DURATION); |
116 }, | 143 }, |
117 | 144 |
118 /** | 145 /** |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 }, 10); | 234 }, 10); |
208 }; | 235 }; |
209 | 236 |
210 /** | 237 /** |
211 * Dismisses the Snackbar currently showing. | 238 * Dismisses the Snackbar currently showing. |
212 * @param {boolean} clearQueue If true, clears the Snackbar queue before | 239 * @param {boolean} clearQueue If true, clears the Snackbar queue before |
213 * dismissing. | 240 * dismissing. |
214 */ | 241 */ |
215 Snackbar.dismiss = function(clearQueue) { | 242 Snackbar.dismiss = function(clearQueue) { |
216 if (clearQueue) Snackbar.queue_ = []; | 243 if (clearQueue) Snackbar.queue_ = []; |
217 if (Snackbar.current_) Snackbar.current_.dismiss(); | 244 if (Snackbar.current_) return Snackbar.current_.dismiss(); |
245 return Promise.resolve(); | |
218 }; | 246 }; |
219 | 247 |
220 | 248 |
221 | 249 |
222 return { | 250 return { |
223 Snackbar: Snackbar, | 251 Snackbar: Snackbar, |
224 SnackbarType: SnackbarType, | 252 SnackbarType: SnackbarType, |
225 }; | 253 }; |
226 }); | 254 }); |
OLD | NEW |