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