OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 (function() { | 5 (function() { |
6 'use strict'; | 6 'use strict'; |
7 | 7 |
8 /** | 8 /** |
9 * Moves |target| element above |anchor| element, in order to match the | 9 * Moves |target| element above |anchor| element, in order to match the |
10 * bottom lines. | 10 * bottom lines. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 type: Boolean, | 74 type: Boolean, |
75 value: false, | 75 value: false, |
76 notify: true | 76 notify: true |
77 }, | 77 }, |
78 | 78 |
79 /** | 79 /** |
80 * The audio volume. 0 is silent, and 100 is maximum loud. | 80 * The audio volume. 0 is silent, and 100 is maximum loud. |
81 */ | 81 */ |
82 volume: { | 82 volume: { |
83 type: Number, | 83 type: Number, |
84 notify: true | 84 notify: true, |
85 reflectToAttribute: true, | |
86 observer: 'volumeChanged_' | |
85 }, | 87 }, |
86 | 88 |
87 /** | 89 /** |
88 * Whether the expanded button is ON. | 90 * Whether the expanded button is ON. |
89 */ | 91 */ |
90 expanded: { | 92 expanded: { |
91 type: Boolean, | 93 type: Boolean, |
92 value: false, | 94 value: false, |
93 notify: true | 95 notify: true |
94 }, | 96 }, |
95 | 97 |
96 /** | 98 /** |
97 * Whether the volume slider is expanded or not. | |
98 */ | |
99 volumeSliderShown: { | |
100 type: Boolean, | |
101 value: false, | |
102 observer: 'volumeSliderShownChanged', | |
103 notify: true | |
104 }, | |
105 | |
106 /** | |
107 * Whether the knob of time slider is being dragged. | 99 * Whether the knob of time slider is being dragged. |
108 */ | 100 */ |
109 dragging: { | 101 dragging: { |
110 type: Boolean, | 102 type: Boolean, |
111 value: false, | 103 value: false, |
112 notify: true | 104 notify: true |
113 }, | 105 }, |
114 | 106 |
115 /** | 107 /** |
116 * Dictionary which contains aria-labels for each controls. | 108 * Dictionary which contains aria-labels for each controls. |
117 */ | 109 */ |
118 ariaLabels: { | 110 ariaLabels: { |
119 type: Object, | 111 type: Object, |
120 observer: 'ariaLabelsChanged_' | 112 observer: 'ariaLabelsChanged_' |
121 } | 113 } |
122 }, | 114 }, |
123 | 115 |
124 /** | 116 /** |
125 * Initializes an element. This method is called automatically when the | 117 * Initializes an element. This method is called automatically when the |
126 * element is ready. | 118 * element is ready. |
127 */ | 119 */ |
128 ready: function() { | 120 ready: function() { |
129 var onFocusoutBound = this.onVolumeControllerFocusout_.bind(this); | 121 var timeSlider = /** @type {PaperSliderElement} */ (this.$.timeSlider); |
130 | 122 timeSlider.addEventListener('value-change', function() { |
yawano
2015/12/01 07:51:31
value-change -> change?
fukino
2015/12/02 04:52:03
Yes, it should be 'change'. Done.
| |
131 this.$.volumeSlider.addEventListener('focusout', onFocusoutBound); | |
132 this.$.volumeButton.addEventListener('focusout', onFocusoutBound); | |
133 | |
134 this.$.timeSlider.addEventListener('value-change', function() { | |
135 if (this.dragging) | 123 if (this.dragging) |
136 this.dragging = false; | 124 this.dragging = false; |
137 }.bind(this)); | 125 }.bind(this)); |
138 this.$.timeSlider.addEventListener('immediate-value-change', function() { | 126 timeSlider.addEventListener('immediate-value-change', function() { |
139 if (!this.dragging) | 127 if (!this.dragging) |
140 this.dragging = true; | 128 this.dragging = true; |
141 }.bind(this)); | 129 }.bind(this)); |
130 | |
131 // Update volume on user inputs for volume slider. | |
132 // During a drag operation, the volume should be updated immediately. | |
133 var volumeSlider = | |
134 /** @type {PaperSliderElement} */ (this.$.volumeSlider); | |
135 volumeSlider.addEventListener('change', function() { | |
136 this.volume = volumeSlider.value; | |
137 }.bind(this)); | |
138 volumeSlider.addEventListener('immediate-value-change', function() { | |
139 this.volume = volumeSlider.immediateValue; | |
140 }.bind(this)); | |
142 }, | 141 }, |
143 | 142 |
144 /** | 143 /** |
145 * Invoked when the next button is clicked. | 144 * Invoked when the next button is clicked. |
146 */ | 145 */ |
147 nextClick: function() { | 146 nextClick: function() { |
148 this.fire('next-clicked'); | 147 this.fire('next-clicked'); |
149 }, | 148 }, |
150 | 149 |
151 /** | 150 /** |
152 * Invoked when the play button is clicked. | 151 * Invoked when the play button is clicked. |
153 */ | 152 */ |
154 playClick: function() { | 153 playClick: function() { |
155 this.playing = !this.playing; | 154 this.playing = !this.playing; |
156 }, | 155 }, |
157 | 156 |
158 /** | 157 /** |
159 * Invoked when the previous button is clicked. | 158 * Invoked when the previous button is clicked. |
160 */ | 159 */ |
161 previousClick: function() { | 160 previousClick: function() { |
162 this.fire('previous-clicked'); | 161 this.fire('previous-clicked'); |
163 }, | 162 }, |
164 | 163 |
165 /** | 164 /** |
166 * Invoked when the property 'volumeSliderShown' changes. | 165 * Invoked when the volume button is clicked. |
167 * @param {boolean} shown | |
168 */ | 166 */ |
169 volumeSliderShownChanged: function(shown) { | 167 volumeClick: function() { |
170 this.showVolumeController_(shown); | 168 if (this.volume !== 0) { |
171 }, | 169 this.savedVolume_ = this.volume; |
172 | 170 this.volume = 0; |
173 /** | 171 } else { |
174 * Invoked when the focus goes out of the volume elements. | 172 this.volume = this.savedVolume_ || 50; |
175 * @param {!UIEvent} event The focusout event. | |
176 * @private | |
177 */ | |
178 onVolumeControllerFocusout_: function(event) { | |
179 if (this.volumeSliderShown) { | |
180 // If the focus goes out of the volume, hide the volume control. | |
181 if (!event.relatedTarget || | |
182 (!this.$.volumeButton.contains(event.relatedTarget) && | |
183 !this.$.volumeSlider.contains(event.relatedTarget))) { | |
184 this.volumeSliderShown = false; | |
185 } | |
186 } | 173 } |
187 }, | 174 }, |
188 | 175 |
189 /** | |
190 * Shows/hides the volume controller. | |
191 * @param {boolean} show True to show the controller, false to hide. | |
192 * @private | |
193 */ | |
194 showVolumeController_: function(show) { | |
195 if (show) { | |
196 matchBottomLine(this.$.volumeContainer, this.$.volumeButton); | |
197 this.$.volumeContainer.style.visibility = 'visible'; | |
198 } else { | |
199 this.$.volumeContainer.style.visibility = 'hidden'; | |
200 } | |
201 }, | |
202 | |
203 /** | 176 /** |
204 * Converts the time into human friendly string. | 177 * Converts the time into human friendly string. |
205 * @param {number} time Time to be converted. | 178 * @param {number} time Time to be converted. |
206 * @return {string} String representation of the given time | 179 * @return {string} String representation of the given time |
207 */ | 180 */ |
208 time2string_: function(time) { | 181 time2string_: function(time) { |
209 return ~~(time / 60000) + ':' + ('0' + ~~(time / 1000 % 60)).slice(-2); | 182 return ~~(time / 60000) + ':' + ('0' + ~~(time / 1000 % 60)).slice(-2); |
210 }, | 183 }, |
211 | 184 |
212 /** | 185 /** |
(...skipping 12 matching lines...) Expand all Loading... | |
225 * @private | 198 * @private |
226 */ | 199 */ |
227 playingChanged_: function(playing) { | 200 playingChanged_: function(playing) { |
228 if (this.ariaLabels) { | 201 if (this.ariaLabels) { |
229 this.$.play.setAttribute('aria-label', | 202 this.$.play.setAttribute('aria-label', |
230 playing ? this.ariaLabels.pause : this.ariaLabels.play); | 203 playing ? this.ariaLabels.pause : this.ariaLabels.play); |
231 } | 204 } |
232 }, | 205 }, |
233 | 206 |
234 /** | 207 /** |
208 * Invoked when the volume property is changed. | |
209 * @param {number} volume | |
210 * @private | |
211 */ | |
212 volumeChanged_: function(volume) { | |
213 if (!this.$.volumeSlider.dragging) | |
214 this.$.volumeSlider.value = volume; | |
215 | |
216 if (this.ariaLabels) { | |
217 this.$.volumeButton.setAttribute('aria-label', | |
yawano
2015/12/01 07:51:31
This might be out of the scope of this CL. If you
fukino
2015/12/02 04:52:02
I'm not a big fun of tooltips when the buttons use
yawano
2015/12/02 06:11:43
Acknowledged.
| |
218 volume !== 0 ? this.ariaLabels.mute : this.ariaLabels.unmute); | |
219 } | |
220 }, | |
221 | |
222 /** | |
235 * Invoked when the ariaLabels property is changed. | 223 * Invoked when the ariaLabels property is changed. |
236 * @param {Object} ariaLabels | 224 * @param {Object} ariaLabels |
237 * @private | 225 * @private |
238 */ | 226 */ |
239 ariaLabelsChanged_: function(ariaLabels) { | 227 ariaLabelsChanged_: function(ariaLabels) { |
240 assert(ariaLabels); | 228 assert(ariaLabels); |
241 // TODO(fukino): Use data bindings. | 229 // TODO(fukino): Use data bindings. |
242 this.$.volumeSlider.setAttribute('aria-label', ariaLabels.volumeSlider); | 230 this.$.volumeSlider.setAttribute('aria-label', ariaLabels.volumeSlider); |
243 this.$.shuffle.setAttribute('aria-label', ariaLabels.shuffle); | 231 this.$.shuffle.setAttribute('aria-label', ariaLabels.shuffle); |
244 this.$.repeat.setAttribute('aria-label', ariaLabels.repeat); | 232 this.$.repeat.setAttribute('aria-label', ariaLabels.repeat); |
245 this.$.previous.setAttribute('aria-label', ariaLabels.previous); | 233 this.$.previous.setAttribute('aria-label', ariaLabels.previous); |
246 this.$.play.setAttribute('aria-label', | 234 this.$.play.setAttribute('aria-label', |
247 this.playing ? ariaLabels.pause : ariaLabels.play); | 235 this.playing ? ariaLabels.pause : ariaLabels.play); |
248 this.$.next.setAttribute('aria-label', ariaLabels.next); | 236 this.$.next.setAttribute('aria-label', ariaLabels.next); |
249 this.$.volumeButton.setAttribute('aria-label', ariaLabels.volume); | 237 this.$.volumeButton.setAttribute('aria-label', ariaLabels.volume); |
250 this.$.playList.setAttribute('aria-label', ariaLabels.playList); | 238 this.$.playList.setAttribute('aria-label', ariaLabels.playList); |
251 this.$.timeSlider.setAttribute('aria-label', ariaLabels.seekSlider); | 239 this.$.timeSlider.setAttribute('aria-label', ariaLabels.seekSlider); |
240 this.$.volumeButton.setAttribute('aria-label', | |
241 this.volume !== 0 ? ariaLabels.mute : ariaLabels.unmute); | |
242 this.$.volumeSlider.setAttribute('aria-label', ariaLabels.volumeSlider); | |
252 } | 243 } |
253 }); | 244 }); |
254 })(); // Anonymous closure | 245 })(); // Anonymous closure |
OLD | NEW |