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

Side by Side Diff: chrome/browser/resources/bluetooth_internals/snackbar.js

Issue 2568283003: bluetooth: Add notification system to internals page. (Closed)
Patch Set: CSS/Snackbar/test changes Created 4 years 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 /**
6 * Javascript for Snackbar controls, served from chrome://bluetooth-internals/.
7 */
8
9 cr.define('snackbar', function() {
10 /** @typedef {{
11 * message: string,
12 * type: string,
13 * actionText: (string|undefined),
14 * action: (function()|undefined)
15 * }}
Dan Beam 2016/12/16 21:54:40 arguable nit: /** * @typedef {{ * message: st
mbrunson 2016/12/17 02:21:59 No. I'm not compiling it. IIRC, WebUI pages that u
16 */
17 var SnackbarOptions;
18
19 /** @const {number} */ var SHOW_DURATION = 5000;
20
21 /**
22 * Enum of Snackbar types. Used by Snackbar to determine the styling for the
23 * Snackbar.
24 * @enum {string}
25 */
26 var SnackbarType = {
27 INFO: 'info',
28 SUCCESS: 'success',
29 WARNING: 'warning',
30 ERROR: 'error',
31 };
32
33 /**
34 * Notification bar for displaying a simple message with an action link.
35 * This element should not be instantiated directly. Instead, users should
36 * use the Snackbar.show and Snackbar.dismiss functions to ensure proper
37 * queuing of messages.
38 */
39 var Snackbar = cr.ui.define('div');
40
41 Snackbar.prototype = {
42 __proto__: HTMLDivElement.prototype,
43
44 /**
45 * Decorates an element as a UI element class. Creates the message div and
46 * action link for the new Snackbar.
47 */
48 decorate: function() {
49 this.classList.add('snackbar');
50 this.messageDiv_ = document.createElement('div');
51 this.appendChild(this.messageDiv_);
52 this.actionLink_ = document.createElement('a', 'action-link');
53 this.appendChild(this.actionLink_);
54
55 this.timeoutId_ = null;
56 this.addEventListener('mouseleave', this.startTimeout_.bind(this));
57 this.addEventListener('mouseenter', this.stopTimeout_.bind(this));
58
59 document.addEventListener('contentfocus', this.startTimeout_.bind(this));
60 document.addEventListener('contentblur', this.stopTimeout_.bind(this));
61 },
62
63 /**
64 * Initializes the content of the Snackbar with the given |options|
65 * including the message, action link text, and click action of the link.
66 * @param {!SnackbarOptions} options
67 */
68 initialize: function(options) {
69 this.messageDiv_.textContent = options.message;
70 this.classList.add(options.type);
71 this.actionLink_.textContent = options.actionText || 'Dismiss';
72
73 this.actionLink_.addEventListener('click', function() {
74 if (options.action) options.action();
75 this.dismiss();
76 }.bind(this));
77 },
78
79 /**
80 * Shows the Snackbar.
81 */
82 show: function() {
83 this.classList.add('open');
84 this.startTimeout_();
85 },
86
87 /**
88 * Dismisses the Snackbar. Once the Snackbar is completely hidden, the
89 * 'dismissed' event is fired.
90 */
91 dismiss: function() {
92 this.addEventListener('webkitTransitionEnd', function(event) {
93 if (event.propertyName === 'transform')
94 this.dispatchEvent(new CustomEvent('dismissed'));
95 }.bind(this));
96
97 ensureTransitionEndEvent(this, SHOW_DURATION);
98 this.classList.remove('open');
99 },
100
101 /**
102 * Starts the timeout for dismissing the Snackbar.
103 * @private
104 */
105 startTimeout_: function() {
106 this.timeoutId_ = setTimeout(function() {
107 this.dismiss();
108 }.bind(this), SHOW_DURATION);
109 },
110
111 /**
112 * Stops the timeout for dismissing the Snackbar. Only clears the timeout
113 * when the Snackbar is open.
114 * @private
115 */
116 stopTimeout_: function() {
117 if (this.classList.contains('open')) {
118 clearTimeout(this.timeoutId_);
119 this.timeoutId_ = null;
120 }
121 },
122 };
123
124 /** @private {?Snackbar} */
125 Snackbar.current_ = null;
126
127 /** @private {!Array<!SnackbarOptions>} */
128 Snackbar.queue_ = [];
129
130 /**
131 * Creates a Snackbar and shows it if one is not showing already. If a
132 * Snackbar is already active, the next Snackbar is queued.
133 * @param {string} message The message to display in the Snackbar.
134 * @param {string=} opt_type A string determining the Snackbar type: info,
135 * success, warning, error. If not provided, info type is used.
136 * @param {string=} opt_actionText The text to display for the action link.
137 * @param {function()=} opt_action A function to be called when the user
138 * presses the action link.
139 * @return {!Snackbar}
140 */
141 Snackbar.show = function(message, opt_type, opt_actionText, opt_action) {
142 var options = {
143 message: message,
144 type: opt_type || SnackbarType.INFO,
145 actionText: opt_actionText,
146 action: opt_action,
147 };
148
149 var newSnackbar = new Snackbar();
150 newSnackbar.initialize(options);
151
152 if (Snackbar.current_) {
153 Snackbar.queue_.push(newSnackbar);
Dan Beam 2016/12/16 21:54:40 ah, so these are queued until others are dismissed
154 return newSnackbar;
155 }
156
157 Snackbar.show_(newSnackbar);
158 return newSnackbar;
Dan Beam 2016/12/16 21:54:40 nit: if (Snackbar.current_) Snackbar.queue_.pus
mbrunson 2016/12/17 02:21:59 Done.
159 };
160
161 /**
162 * Creates a Snackbar and sets events for queuing the next Snackbar to show.
163 * @param {!Snackbar} newSnackbar
164 * @private
165 */
166 Snackbar.show_ = function(newSnackbar) {
167 $('snackbar-container').appendChild(newSnackbar);
Dan Beam 2016/12/16 21:54:40 probably OK for now, but maybe pass $('snackbar-co
mbrunson 2016/12/17 02:21:59 Added a TODO. Done.
168
169 newSnackbar.addEventListener('dismissed', function() {
170 $('snackbar-container').removeChild(Snackbar.current_);
171
172 var newSnackbar = Snackbar.queue_.shift();
173 if (newSnackbar) {
174 Snackbar.show_(newSnackbar);
175 return;
176 }
177
178 Snackbar.current_ = null;
179 });
180
181 Snackbar.current_ = newSnackbar;
182
183 // Show the Snackbar after a slight delay to allow for a layout reflow.
184 setTimeout(function() {
185 newSnackbar.show();
186 }, 10);
187 };
188
189 /**
190 * Dismisses the Snackbar currently showing.
191 * @param {boolean} clearQueue If true, clears the Snackbar queue before
192 * dismissing.
193 */
194 Snackbar.dismiss = function(clearQueue) {
195 if (clearQueue) Snackbar.queue_ = [];
196 if (Snackbar.current_) Snackbar.current_.dismiss();
197 };
198
199 return {
200 Snackbar: Snackbar,
201 SnackbarType: SnackbarType,
202 };
203 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698