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 /** | 5 /** |
6 * @constructor | 6 * @constructor |
7 * @extends {PolymerElement} | 7 * @extends {PolymerElement} |
8 */ | 8 */ |
9 var AudioPlayerElement = function() {}; | 9 var AudioPlayerElement = function() {}; |
10 | 10 |
11 AudioPlayerElement.prototype = { | 11 AudioPlayerElement.prototype = { |
12 // Child Elements | 12 is: 'audio-player', |
13 audioController: null, | |
14 audioElement: null, | |
15 trackList: null, | |
16 | 13 |
17 // Published values | 14 properties: { |
18 playing: true, | 15 /** |
19 currenttrackurl: '', | 16 * Flag whether the audio is playing or paused. True if playing, or false |
20 playcount: 0, | 17 * paused. |
| 18 */ |
| 19 playing: { |
| 20 type: Boolean, |
| 21 observer: 'playingChanged', |
| 22 reflectToAttribute: true |
| 23 }, |
21 | 24 |
22 // Attributes of the element (lower characters only). | 25 /** |
23 // These values must be used only to data binding and shouldn't be assigned | 26 * Current elapsed time in the current music in millisecond. |
24 // any value nowhere except in the handler. | 27 */ |
25 publish: { | 28 time: { |
26 playing: { | 29 type: Number, |
27 value: true, | 30 observer: 'timeChanged' |
28 reflect: true | |
29 }, | 31 }, |
| 32 |
| 33 /** |
| 34 * Whether the shuffle button is ON. |
| 35 */ |
| 36 shuffle: { |
| 37 type: Boolean, |
| 38 observer: 'shuffleChanged' |
| 39 }, |
| 40 |
| 41 /** |
| 42 * Whether the repeat button is ON. |
| 43 */ |
| 44 repeat: { |
| 45 type: Boolean, |
| 46 observer: 'repeatChanged' |
| 47 }, |
| 48 |
| 49 /** |
| 50 * The audio volume. 0 is silent, and 100 is maximum loud. |
| 51 */ |
| 52 volume: { |
| 53 type: Number, |
| 54 observer: 'volumeChanged' |
| 55 }, |
| 56 |
| 57 /** |
| 58 * Whether the expanded button is ON. |
| 59 */ |
| 60 expanded: { |
| 61 type: Boolean, |
| 62 observer: 'expandedChanged' |
| 63 }, |
| 64 |
| 65 /** |
| 66 * Track index of the current track. |
| 67 */ |
| 68 currentTrackIndex: { |
| 69 type: Number, |
| 70 observer: 'currentTrackIndexChanged' |
| 71 }, |
| 72 |
| 73 /** |
| 74 * Model object of the Audio Player. |
| 75 * @type {AudioPlayerModel} |
| 76 */ |
| 77 model: { |
| 78 type: Object, |
| 79 value: null, |
| 80 observer: 'modelChanged' |
| 81 }, |
| 82 |
| 83 /** |
| 84 * URL of the current track. (exposed publicly for tests) |
| 85 */ |
30 currenttrackurl: { | 86 currenttrackurl: { |
| 87 type: String, |
31 value: '', | 88 value: '', |
32 reflect: true | 89 reflectToAttribute: true |
33 }, | 90 }, |
| 91 |
| 92 /** |
| 93 * The number of played tracks. (exposed publicly for tests) |
| 94 */ |
34 playcount: { | 95 playcount: { |
| 96 type: Number, |
35 value: 0, | 97 value: 0, |
36 reflect: true | 98 reflectToAttribute: true |
37 } | 99 } |
38 }, | 100 }, |
39 | 101 |
40 /** | 102 /** |
41 * Model object of the Audio Player. | 103 * Handles change event for shuffle mode. |
42 * @type {AudioPlayerModel} | 104 * @param {boolean} shuffle |
43 */ | 105 */ |
44 model: null, | 106 shuffleChanged: function(shuffle) { |
| 107 if (this.model) |
| 108 this.model.shuffle = shuffle; |
| 109 }, |
| 110 |
| 111 /** |
| 112 * Handles change event for repeat mode. |
| 113 * @param {boolean} repeat |
| 114 */ |
| 115 repeatChanged: function(repeat) { |
| 116 if (this.model) |
| 117 this.model.repeat = repeat; |
| 118 }, |
| 119 |
| 120 /** |
| 121 * Handles change event for audio volume. |
| 122 * @param {boolean} volume |
| 123 */ |
| 124 volumeChanged: function(volume) { |
| 125 if (this.model) |
| 126 this.model.volume = volume; |
| 127 }, |
| 128 |
| 129 /** |
| 130 * Handles change event for expanded state of track list. |
| 131 */ |
| 132 expandedChanged: function(expanded) { |
| 133 if (this.model) |
| 134 this.model.expanded = expanded; |
| 135 }, |
45 | 136 |
46 /** | 137 /** |
47 * Initializes an element. This method is called automatically when the | 138 * Initializes an element. This method is called automatically when the |
48 * element is ready. | 139 * element is ready. |
49 */ | 140 */ |
50 ready: function() { | 141 ready: function() { |
51 this.audioController = this.$.audioController; | |
52 this.audioElement = this.$.audio; | |
53 this.trackList = this.$.trackList; | |
54 | |
55 this.addEventListener('keydown', this.onKeyDown_.bind(this)); | 142 this.addEventListener('keydown', this.onKeyDown_.bind(this)); |
56 | 143 |
57 this.audioElement.volume = 0; // Temporary initial volume. | 144 this.$.audio.volume = 0; // Temporary initial volume. |
58 this.audioElement.addEventListener('ended', this.onAudioEnded.bind(this)); | 145 this.$.audio.addEventListener('ended', this.onAudioEnded.bind(this)); |
59 this.audioElement.addEventListener('error', this.onAudioError.bind(this)); | 146 this.$.audio.addEventListener('error', this.onAudioError.bind(this)); |
60 | 147 |
61 var onAudioStatusUpdatedBound = this.onAudioStatusUpdate_.bind(this); | 148 var onAudioStatusUpdatedBound = this.onAudioStatusUpdate_.bind(this); |
62 this.audioElement.addEventListener('timeupdate', onAudioStatusUpdatedBound); | 149 this.$.audio.addEventListener('timeupdate', onAudioStatusUpdatedBound); |
63 this.audioElement.addEventListener('ended', onAudioStatusUpdatedBound); | 150 this.$.audio.addEventListener('ended', onAudioStatusUpdatedBound); |
64 this.audioElement.addEventListener('play', onAudioStatusUpdatedBound); | 151 this.$.audio.addEventListener('play', onAudioStatusUpdatedBound); |
65 this.audioElement.addEventListener('pause', onAudioStatusUpdatedBound); | 152 this.$.audio.addEventListener('pause', onAudioStatusUpdatedBound); |
66 this.audioElement.addEventListener('suspend', onAudioStatusUpdatedBound); | 153 this.$.audio.addEventListener('suspend', onAudioStatusUpdatedBound); |
67 this.audioElement.addEventListener('abort', onAudioStatusUpdatedBound); | 154 this.$.audio.addEventListener('abort', onAudioStatusUpdatedBound); |
68 this.audioElement.addEventListener('error', onAudioStatusUpdatedBound); | 155 this.$.audio.addEventListener('error', onAudioStatusUpdatedBound); |
69 this.audioElement.addEventListener('emptied', onAudioStatusUpdatedBound); | 156 this.$.audio.addEventListener('emptied', onAudioStatusUpdatedBound); |
70 this.audioElement.addEventListener('stalled', onAudioStatusUpdatedBound); | 157 this.$.audio.addEventListener('stalled', onAudioStatusUpdatedBound); |
71 }, | |
72 | |
73 /** | |
74 * Registers handlers for changing of external variables | |
75 */ | |
76 observe: { | |
77 'trackList.currentTrackIndex': 'onCurrentTrackIndexChanged', | |
78 'audioController.playing': 'onControllerPlayingChanged', | |
79 'audioController.time': 'onControllerTimeChanged', | |
80 'model.volume': 'onVolumeChanged', | |
81 }, | 158 }, |
82 | 159 |
83 /** | 160 /** |
84 * Invoked when trackList.currentTrackIndex is changed. | 161 * Invoked when trackList.currentTrackIndex is changed. |
| 162 * @param {number} newValue new value. |
85 * @param {number} oldValue old value. | 163 * @param {number} oldValue old value. |
86 * @param {number} newValue new value. | |
87 */ | 164 */ |
88 onCurrentTrackIndexChanged: function(oldValue, newValue) { | 165 currentTrackIndexChanged: function(newValue, oldValue) { |
89 var currentTrackUrl = ''; | 166 var currentTrackUrl = ''; |
90 | 167 |
91 if (oldValue != newValue) { | 168 if (oldValue != newValue) { |
92 var currentTrack = this.trackList.getCurrentTrack(); | 169 var currentTrack = this.$.trackList.getCurrentTrack(); |
93 if (currentTrack && currentTrack.url != this.audioElement.src) { | 170 if (currentTrack && currentTrack.url != this.$.audio.src) { |
94 this.audioElement.src = currentTrack.url; | 171 this.$.audio.src = currentTrack.url; |
95 currentTrackUrl = this.audioElement.src; | 172 currentTrackUrl = this.$.audio.src; |
96 if (this.audioController.playing) | 173 if (this.playing) |
97 this.audioElement.play(); | 174 this.$.audio.play(); |
98 } | 175 } |
99 } | 176 } |
100 | 177 |
101 // The attributes may be being watched, so we change it at the last. | 178 // The attributes may be being watched, so we change it at the last. |
102 this.currenttrackurl = currentTrackUrl; | 179 this.currenttrackurl = currentTrackUrl; |
103 }, | 180 }, |
104 | 181 |
105 /** | 182 /** |
106 * Invoked when audioController.playing is changed. | 183 * Invoked when playing is changed. |
| 184 * @param {boolean} newValue new value. |
107 * @param {boolean} oldValue old value. | 185 * @param {boolean} oldValue old value. |
108 * @param {boolean} newValue new value. | |
109 */ | 186 */ |
110 onControllerPlayingChanged: function(oldValue, newValue) { | 187 playingChanged: function(newValue, oldValue) { |
111 this.playing = newValue; | |
112 | |
113 if (newValue) { | 188 if (newValue) { |
114 if (!this.audioElement.src) { | 189 if (!this.$.audio.src) { |
115 var currentTrack = this.trackList.getCurrentTrack(); | 190 var currentTrack = this.$.trackList.getCurrentTrack(); |
116 if (currentTrack && currentTrack.url != this.audioElement.src) { | 191 if (currentTrack && currentTrack.url != this.$.audio.src) { |
117 this.audioElement.src = currentTrack.url; | 192 this.$.audio.src = currentTrack.url; |
118 } | 193 } |
119 } | 194 } |
120 | 195 |
121 if (this.audioElement.src) { | 196 if (this.$.audio.src) { |
122 this.currenttrackurl = this.audioElement.src; | 197 this.currenttrackurl = this.$.audio.src; |
123 this.audioElement.play(); | 198 this.$.audio.play(); |
124 return; | 199 return; |
125 } | 200 } |
126 } | 201 } |
127 | 202 |
128 // When the new status is "stopped". | 203 // When the new status is "stopped". |
129 this.cancelAutoAdvance_(); | 204 this.cancelAutoAdvance_(); |
130 this.audioElement.pause(); | 205 this.$.audio.pause(); |
131 this.currenttrackurl = ''; | 206 this.currenttrackurl = ''; |
132 this.lastAudioUpdateTime_ = null; | 207 this.lastAudioUpdateTime_ = null; |
133 }, | 208 }, |
134 | 209 |
135 /** | 210 /** |
136 * Invoked when audioController.volume is changed. | 211 * Invoked when the model changed. |
137 * @param {number} oldValue old value. | 212 * @param {AudioPlayerModel} newModel New model. |
138 * @param {number} newValue new value. | 213 * @param {AudioPlayerModel} oldModel Old model. |
139 */ | 214 */ |
140 onVolumeChanged: function(oldValue, newValue) { | 215 modelChanged: function(newModel, oldModel) { |
141 this.audioElement.volume = newValue / 100; | 216 // Setting up the UI |
| 217 if (newModel !== oldModel && newModel) { |
| 218 this.shuffle = newModel.shuffle; |
| 219 this.repeat = newModel.repeat; |
| 220 this.volume = newModel.volume; |
| 221 this.expanded = newModel.expanded; |
| 222 } |
142 }, | 223 }, |
143 | 224 |
144 /** | 225 /** |
145 * Invoked when the model changed. | 226 * Invoked when time is changed. |
146 * @param {AudioPlayerModel} oldValue Old Value. | 227 * @param {number} newValue new time (in ms). |
147 * @param {AudioPlayerModel} newValue New Value. | 228 * @param {number} oldValue old time (in ms). |
148 */ | 229 */ |
149 modelChanged: function(oldValue, newValue) { | 230 timeChanged: function(newValue, oldValue) { |
150 this.trackList.model = newValue; | |
151 this.audioController.model = newValue; | |
152 | |
153 // Invoke the handler manually. | |
154 this.onVolumeChanged(0, newValue.volume); | |
155 }, | |
156 | |
157 /** | |
158 * Invoked when audioController.time is changed. | |
159 * @param {number} oldValue old time (in ms). | |
160 * @param {number} newValue new time (in ms). | |
161 */ | |
162 onControllerTimeChanged: function(oldValue, newValue) { | |
163 // Ignores updates from the audio element. | 231 // Ignores updates from the audio element. |
164 if (this.lastAudioUpdateTime_ === newValue) | 232 if (this.lastAudioUpdateTime_ === newValue) |
165 return; | 233 return; |
166 | 234 |
167 if (this.audioElement.readyState !== 0) | 235 if (this.$.audio.readyState !== 0) |
168 this.audioElement.currentTime = this.audioController.time / 1000; | 236 this.$.audio.currentTime = this.time / 1000; |
169 }, | 237 }, |
170 | 238 |
171 /** | 239 /** |
172 * Invoked when the next button in the controller is clicked. | 240 * Invoked when the next button in the controller is clicked. |
173 * This handler is registered in the 'on-click' attribute of the element. | 241 * This handler is registered in the 'on-click' attribute of the element. |
174 */ | 242 */ |
175 onControllerNextClicked: function() { | 243 onControllerNextClicked: function() { |
176 this.advance_(true /* forward */, true /* repeat */); | 244 this.advance_(true /* forward */, true /* repeat */); |
177 }, | 245 }, |
178 | 246 |
179 /** | 247 /** |
180 * Invoked when the previous button in the controller is clicked. | 248 * Invoked when the previous button in the controller is clicked. |
181 * This handler is registered in the 'on-click' attribute of the element. | 249 * This handler is registered in the 'on-click' attribute of the element. |
182 */ | 250 */ |
183 onControllerPreviousClicked: function() { | 251 onControllerPreviousClicked: function() { |
184 this.advance_(false /* forward */, true /* repeat */); | 252 this.advance_(false /* forward */, true /* repeat */); |
185 }, | 253 }, |
186 | 254 |
187 /** | 255 /** |
188 * Invoked when the playback in the audio element is ended. | 256 * Invoked when the playback in the audio element is ended. |
189 * This handler is registered in this.ready(). | 257 * This handler is registered in this.ready(). |
190 */ | 258 */ |
191 onAudioEnded: function() { | 259 onAudioEnded: function() { |
192 this.playcount++; | 260 this.playcount++; |
193 this.advance_(true /* forward */, this.model.repeat); | 261 this.advance_(true /* forward */, this.repeat); |
194 }, | 262 }, |
195 | 263 |
196 /** | 264 /** |
197 * Invoked when the playback in the audio element gets error. | 265 * Invoked when the playback in the audio element gets error. |
198 * This handler is registered in this.ready(). | 266 * This handler is registered in this.ready(). |
199 */ | 267 */ |
200 onAudioError: function() { | 268 onAudioError: function() { |
201 this.scheduleAutoAdvance_(true /* forward */, this.model.repeat); | 269 this.scheduleAutoAdvance_(true /* forward */, this.repeat); |
202 }, | 270 }, |
203 | 271 |
204 /** | 272 /** |
205 * Invoked when the time of playback in the audio element is updated. | 273 * Invoked when the time of playback in the audio element is updated. |
206 * This handler is registered in this.ready(). | 274 * This handler is registered in this.ready(). |
207 * @private | 275 * @private |
208 */ | 276 */ |
209 onAudioStatusUpdate_: function() { | 277 onAudioStatusUpdate_: function() { |
210 this.audioController.time = | 278 this.time = (this.lastAudioUpdateTime_ = this.$.audio.currentTime * 1000); |
211 (this.lastAudioUpdateTime_ = this.audioElement.currentTime * 1000); | 279 this.duration = this.$.audio.duration * 1000; |
212 this.audioController.duration = this.audioElement.duration * 1000; | 280 this.playing = !this.$.audio.paused; |
213 this.audioController.playing = !this.audioElement.paused; | |
214 }, | 281 }, |
215 | 282 |
216 /** | 283 /** |
217 * Invoked when receiving a request to replay the current music from the track | 284 * Invoked when receiving a request to replay the current music from the track |
218 * list element. | 285 * list element. |
219 */ | 286 */ |
220 onReplayCurrentTrack: function() { | 287 onReplayCurrentTrack: function() { |
221 // Changes the current time back to the beginning, regardless of the current | 288 // Changes the current time back to the beginning, regardless of the current |
222 // status (playing or paused). | 289 // status (playing or paused). |
223 this.audioElement.currentTime = 0; | 290 this.$.audio.currentTime = 0; |
224 this.audioController.time = 0; | 291 this.time = 0; |
225 }, | 292 }, |
226 | 293 |
227 /** | 294 /** |
228 * Goes to the previous or the next track. | 295 * Goes to the previous or the next track. |
229 * @param {boolean} forward True if next, false if previous. | 296 * @param {boolean} forward True if next, false if previous. |
230 * @param {boolean} repeat True if repeat-mode is enabled. False otherwise. | 297 * @param {boolean} repeat True if repeat-mode is enabled. False otherwise. |
231 * @private | 298 * @private |
232 */ | 299 */ |
233 advance_: function(forward, repeat) { | 300 advance_: function(forward, repeat) { |
234 this.cancelAutoAdvance_(); | 301 this.cancelAutoAdvance_(); |
235 | 302 |
236 var nextTrackIndex = this.trackList.getNextTrackIndex(forward, true); | 303 var nextTrackIndex = this.$.trackList.getNextTrackIndex(forward, true); |
237 var isNextTrackAvailable = | 304 var isNextTrackAvailable = |
238 (this.trackList.getNextTrackIndex(forward, repeat) !== -1); | 305 (this.$.trackList.getNextTrackIndex(forward, repeat) !== -1); |
239 | 306 |
240 this.audioController.playing = isNextTrackAvailable; | 307 this.playing = isNextTrackAvailable; |
241 | 308 |
242 // If there is only a single file in the list, 'currentTrackInde' is not | 309 // If there is only a single file in the list, 'currentTrackInde' is not |
243 // changed and the handler is not invoked. Instead, plays here. | 310 // changed and the handler is not invoked. Instead, plays here. |
244 // TODO(yoshiki): clean up the code around here. | 311 // TODO(yoshiki): clean up the code around here. |
245 if (isNextTrackAvailable && | 312 if (isNextTrackAvailable && |
246 this.trackList.currentTrackIndex == nextTrackIndex) { | 313 this.$.trackList.currentTrackIndex == nextTrackIndex) { |
247 this.audioElement.play(); | 314 this.$.audio.play(); |
248 } | 315 } |
249 | 316 |
250 this.trackList.currentTrackIndex = nextTrackIndex; | 317 this.$.trackList.currentTrackIndex = nextTrackIndex; |
251 }, | 318 }, |
252 | 319 |
253 /** | 320 /** |
254 * Timeout ID of auto advance. Used internally in scheduleAutoAdvance_() and | 321 * Timeout ID of auto advance. Used internally in scheduleAutoAdvance_() and |
255 * cancelAutoAdvance_(). | 322 * cancelAutoAdvance_(). |
256 * @type {number?} | 323 * @type {number?} |
257 * @private | 324 * @private |
258 */ | 325 */ |
259 autoAdvanceTimer_: null, | 326 autoAdvanceTimer_: null, |
260 | 327 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 * @private | 363 * @private |
297 */ | 364 */ |
298 cancelAutoAdvance_: function() { | 365 cancelAutoAdvance_: function() { |
299 if (this.autoAdvanceTimer_) { | 366 if (this.autoAdvanceTimer_) { |
300 clearTimeout(this.autoAdvanceTimer_); | 367 clearTimeout(this.autoAdvanceTimer_); |
301 this.autoAdvanceTimer_ = null; | 368 this.autoAdvanceTimer_ = null; |
302 } | 369 } |
303 }, | 370 }, |
304 | 371 |
305 /** | 372 /** |
306 * The index of the current track. | |
307 * If the list has no tracks, the value must be -1. | |
308 * | |
309 * @type {number} | |
310 */ | |
311 get currentTrackIndex() { | |
312 return this.trackList.currentTrackIndex; | |
313 }, | |
314 set currentTrackIndex(value) { | |
315 this.trackList.currentTrackIndex = value; | |
316 }, | |
317 | |
318 /** | |
319 * The list of the tracks in the playlist. | 373 * The list of the tracks in the playlist. |
320 * | 374 * |
321 * When it changed, current operation including playback is stopped and | 375 * When it changed, current operation including playback is stopped and |
322 * restarts playback with new tracks if necessary. | 376 * restarts playback with new tracks if necessary. |
323 * | 377 * |
324 * @type {Array<AudioPlayer.TrackInfo>} | 378 * @type {Array<AudioPlayer.TrackInfo>} |
325 */ | 379 */ |
326 get tracks() { | 380 get tracks() { |
327 return this.trackList ? this.trackList.tracks : null; | 381 return this.$.trackList ? this.$.trackList.tracks : null; |
328 }, | 382 }, |
329 set tracks(tracks) { | 383 set tracks(tracks) { |
330 if (this.trackList.tracks === tracks) | 384 if (this.$.trackList.tracks === tracks) |
331 return; | 385 return; |
332 | 386 |
333 this.cancelAutoAdvance_(); | 387 this.cancelAutoAdvance_(); |
334 | 388 |
335 this.trackList.tracks = tracks; | 389 this.$.trackList.tracks = tracks; |
336 var currentTrack = this.trackList.getCurrentTrack(); | 390 var currentTrack = this.$.trackList.getCurrentTrack(); |
337 if (currentTrack && currentTrack.url != this.audioElement.src) { | 391 if (currentTrack && currentTrack.url != this.$.audio.src) { |
338 this.audioElement.src = currentTrack.url; | 392 this.$.audio.src = currentTrack.url; |
339 this.audioElement.play(); | 393 this.$.audio.play(); |
340 } | 394 } |
341 }, | 395 }, |
342 | 396 |
343 /** | 397 /** |
344 * Invoked when the audio player is being unloaded. | 398 * Invoked when the audio player is being unloaded. |
345 */ | 399 */ |
346 onPageUnload: function() { | 400 onPageUnload: function() { |
347 this.audioElement.src = ''; // Hack to prevent crashing. | 401 this.$.audio.src = ''; // Hack to prevent crashing. |
348 }, | 402 }, |
349 | 403 |
350 /** | 404 /** |
351 * Invoked when the 'keydown' event is fired. | 405 * Invoked when the 'keydown' event is fired. |
352 * @param {Event} event The event object. | 406 * @param {Event} event The event object. |
353 */ | 407 */ |
354 onKeyDown_: function(event) { | 408 onKeyDown_: function(event) { |
355 switch (event.keyIdentifier) { | 409 switch (event.keyIdentifier) { |
356 case 'Up': | 410 case 'Up': |
357 if (this.audioController.volumeSliderShown && this.model.volume < 100) | 411 if (this.$.audioController.volumeSliderShown && this.model.volume < 100) |
358 this.model.volume += 1; | 412 this.model.volume += 1; |
359 break; | 413 break; |
360 case 'Down': | 414 case 'Down': |
361 if (this.audioController.volumeSliderShown && this.model.volume > 0) | 415 if (this.$.audioController.volumeSliderShown && this.model.volume > 0) |
362 this.model.volume -= 1; | 416 this.model.volume -= 1; |
363 break; | 417 break; |
364 case 'PageUp': | 418 case 'PageUp': |
365 if (this.audioController.volumeSliderShown && this.model.volume < 91) | 419 if (this.$.audioController.volumeSliderShown && this.model.volume < 91) |
366 this.model.volume += 10; | 420 this.model.volume += 10; |
367 break; | 421 break; |
368 case 'PageDown': | 422 case 'PageDown': |
369 if (this.audioController.volumeSliderShown && this.model.volume > 9) | 423 if (this.$.audioController.volumeSliderShown && this.model.volume > 9) |
370 this.model.volume -= 10; | 424 this.model.volume -= 10; |
371 break; | 425 break; |
372 case 'MediaNextTrack': | 426 case 'MediaNextTrack': |
373 this.onControllerNextClicked(); | 427 this.onControllerNextClicked(); |
374 break; | 428 break; |
375 case 'MediaPlayPause': | 429 case 'MediaPlayPause': |
376 var playing = this.audioController.playing; | 430 this.playing = !this.playing; |
377 this.onControllerPlayingChanged(playing, !playing); | |
378 break; | 431 break; |
379 case 'MediaPreviousTrack': | 432 case 'MediaPreviousTrack': |
380 this.onControllerPreviousClicked(); | 433 this.onControllerPreviousClicked(); |
381 break; | 434 break; |
382 case 'MediaStop': | 435 case 'MediaStop': |
383 // TODO: Define "Stop" behavior. | 436 // TODO: Define "Stop" behavior. |
384 break; | 437 break; |
385 } | 438 } |
386 }, | 439 }, |
| 440 |
| 441 /** |
| 442 * Computes volume value for audio element. (should be in [0.0, 1.0]) |
| 443 * @param {number} volume Volume which is set in the UI. ([0, 100]) |
| 444 * @return {number} |
| 445 */ |
| 446 computeAudioVolume_: function(volume) { |
| 447 return volume / 100; |
| 448 } |
387 }; | 449 }; |
388 | 450 |
389 Polymer('audio-player', AudioPlayerElement.prototype); | 451 Polymer(AudioPlayerElement.prototype); |
OLD | NEW |