Chromium Code Reviews| Index: ui/file_manager/audio_player/elements/audio_player.js |
| diff --git a/ui/file_manager/audio_player/elements/audio_player.js b/ui/file_manager/audio_player/elements/audio_player.js |
| index 979dc719d6e1c2bd3e7d9f6bad0a919a3edccc64..8d6b0b02fb8db9eaaa33390f5496c2ff6b0c997d 100644 |
| --- a/ui/file_manager/audio_player/elements/audio_player.js |
| +++ b/ui/file_manager/audio_player/elements/audio_player.js |
| @@ -9,46 +9,140 @@ |
| var AudioPlayerElement = function() {}; |
| AudioPlayerElement.prototype = { |
| + is: 'audio-player', |
| + |
| // Child Elements |
| - audioController: null, |
| audioElement: null, |
| trackList: null, |
| - // Published values |
| - playing: true, |
| - currenttrackurl: '', |
| - playcount: 0, |
| - |
| - // Attributes of the element (lower characters only). |
| - // These values must be used only to data binding and shouldn't be assigned |
| - // any value nowhere except in the handler. |
| - publish: { |
| + properties: { |
| + /** |
| + * Flag whether the audio is playing or paused. True if playing, or false |
| + * paused. |
| + */ |
| playing: { |
| - value: true, |
| - reflect: true |
| + type: Boolean, |
| + observer: 'playingChanged', |
| + reflectToAttribute: true |
| + }, |
| + |
| + /** |
| + * Current elapsed time in the current music in millisecond. |
| + */ |
| + time: { |
| + type: Number, |
| + observer: 'timeChanged' |
| + }, |
| + |
| + /** |
| + * Whether the shuffle button is ON. |
| + */ |
| + shuffle: { |
| + type: Boolean, |
| + observer: 'shuffleChanged' |
| + }, |
| + |
| + /** |
| + * Whether the repeat button is ON. |
| + */ |
| + repeat: { |
| + type: Boolean, |
| + observer: 'repeatChanged' |
| + }, |
| + |
| + /** |
| + * The audio volume. 0 is silent, and 100 is maximum loud. |
| + */ |
| + volume: { |
| + type: Number, |
| + observer: 'volumeChanged' |
| + }, |
| + |
| + /** |
| + * Whether the expanded button is ON. |
| + */ |
| + expanded: { |
| + type: Boolean, |
| + observer: 'expandedChanged' |
| + }, |
| + |
| + /** |
| + * Track index of the current track. |
| + */ |
| + currentTrackIndex: { |
| + type: Number, |
| + observer: 'currentTrackIndexChanged' |
| + }, |
| + |
| + /** |
| + * Model object of the Audio Player. |
| + * @type {AudioPlayerModel} |
| + */ |
| + model: { |
| + type: Object, |
| + value: null, |
| + observer: 'modelChanged' |
| }, |
| + |
| + /** |
| + * URL of the current track. (exposed publicly for tests) |
| + */ |
| currenttrackurl: { |
| + type: String, |
| value: '', |
| - reflect: true |
| + reflectToAttribute: true |
| }, |
| + |
| + /** |
| + * The number of played tracks. (exposed publicly for tests) |
| + */ |
| playcount: { |
| + type: Number, |
| value: 0, |
| - reflect: true |
| + reflectToAttribute: true |
| } |
| }, |
| /** |
| - * Model object of the Audio Player. |
| - * @type {AudioPlayerModel} |
| + * Handles change event for shuffle mode. |
| + * @param {boolean} shuffle |
| + */ |
| + shuffleChanged: function(shuffle) { |
| + if (this.model) |
| + this.model.shuffle = shuffle; |
| + }, |
| + |
| + /** |
| + * Handles change event for repeat mode. |
| + * @param {boolean} repeat |
| */ |
| - model: null, |
| + repeatChanged: function(repeat) { |
| + if (this.model) |
| + this.model.repeat = repeat; |
| + }, |
| + |
| + /** |
| + * Handles change event for audio volume. |
| + * @param {boolean} volume |
| + */ |
| + volumeChanged: function(volume) { |
| + if (this.model) |
| + this.model.volume = volume; |
| + }, |
| + |
| + /** |
| + * Handles change event for expanded state of track list. |
| + */ |
| + expandedChanged: function(expanded) { |
| + if (this.model) |
| + this.model.expanded = expanded; |
| + }, |
| /** |
| * Initializes an element. This method is called automatically when the |
| * element is ready. |
| */ |
| ready: function() { |
| - this.audioController = this.$.audioController; |
| this.audioElement = this.$.audio; |
| this.trackList = this.$.trackList; |
| @@ -71,21 +165,14 @@ AudioPlayerElement.prototype = { |
| }, |
| /** |
| - * Registers handlers for changing of external variables |
| - */ |
| - observe: { |
| - 'trackList.currentTrackIndex': 'onCurrentTrackIndexChanged', |
| - 'audioController.playing': 'onControllerPlayingChanged', |
| - 'audioController.time': 'onControllerTimeChanged', |
| - 'model.volume': 'onVolumeChanged', |
| - }, |
| - |
| - /** |
| * Invoked when trackList.currentTrackIndex is changed. |
| - * @param {number} oldValue old value. |
| * @param {number} newValue new value. |
| + * @param {number} oldValue old value. |
| */ |
| - onCurrentTrackIndexChanged: function(oldValue, newValue) { |
| + currentTrackIndexChanged: function(newValue, oldValue) { |
| + 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,
|
| + return; |
| + |
| var currentTrackUrl = ''; |
| if (oldValue != newValue) { |
| @@ -93,7 +180,7 @@ AudioPlayerElement.prototype = { |
| if (currentTrack && currentTrack.url != this.audioElement.src) { |
| this.audioElement.src = currentTrack.url; |
| currentTrackUrl = this.audioElement.src; |
| - if (this.audioController.playing) |
| + if (this.playing) |
| this.audioElement.play(); |
| } |
| } |
| @@ -103,13 +190,11 @@ AudioPlayerElement.prototype = { |
| }, |
| /** |
| - * Invoked when audioController.playing is changed. |
| - * @param {boolean} oldValue old value. |
| + * Invoked when playing is changed. |
| * @param {boolean} newValue new value. |
| + * @param {boolean} oldValue old value. |
| */ |
| - onControllerPlayingChanged: function(oldValue, newValue) { |
| - this.playing = newValue; |
| - |
| + playingChanged: function(newValue, oldValue) { |
| if (newValue) { |
| if (!this.audioElement.src) { |
| var currentTrack = this.trackList.getCurrentTrack(); |
| @@ -127,45 +212,39 @@ AudioPlayerElement.prototype = { |
| // When the new status is "stopped". |
| this.cancelAutoAdvance_(); |
| - this.audioElement.pause(); |
| + if (this.audioElement) |
| + this.audioElement.pause(); |
| this.currenttrackurl = ''; |
| this.lastAudioUpdateTime_ = null; |
| }, |
| /** |
| - * Invoked when audioController.volume is changed. |
| - * @param {number} oldValue old value. |
| - * @param {number} newValue new value. |
| - */ |
| - onVolumeChanged: function(oldValue, newValue) { |
| - this.audioElement.volume = newValue / 100; |
| - }, |
| - |
| - /** |
| * Invoked when the model changed. |
| - * @param {AudioPlayerModel} oldValue Old Value. |
| - * @param {AudioPlayerModel} newValue New Value. |
| + * @param {AudioPlayerModel} newModel New model. |
| + * @param {AudioPlayerModel} oldModel Old model. |
| */ |
| - modelChanged: function(oldValue, newValue) { |
| - this.trackList.model = newValue; |
| - this.audioController.model = newValue; |
| - |
| - // Invoke the handler manually. |
| - this.onVolumeChanged(0, newValue.volume); |
| + modelChanged: function(newModel, oldModel) { |
| + // Setting up the UI |
| + if (newModel !== oldModel && newModel) { |
| + this.shuffle = newModel.shuffle; |
| + this.repeat = newModel.repeat; |
| + this.volume = newModel.volume; |
| + this.expanded = newModel.expanded; |
| + } |
| }, |
| /** |
| - * Invoked when audioController.time is changed. |
| - * @param {number} oldValue old time (in ms). |
| + * Invoked when time is changed. |
| * @param {number} newValue new time (in ms). |
| + * @param {number} oldValue old time (in ms). |
| */ |
| - onControllerTimeChanged: function(oldValue, newValue) { |
| + timeChanged: function(newValue, oldValue) { |
| // Ignores updates from the audio element. |
| if (this.lastAudioUpdateTime_ === newValue) |
| return; |
| - if (this.audioElement.readyState !== 0) |
| - this.audioElement.currentTime = this.audioController.time / 1000; |
| + if (this.audioElement && this.audioElement.readyState !== 0) |
| + this.audioElement.currentTime = this.time / 1000; |
| }, |
| /** |
| @@ -190,7 +269,7 @@ AudioPlayerElement.prototype = { |
| */ |
| onAudioEnded: function() { |
| this.playcount++; |
| - this.advance_(true /* forward */, this.model.repeat); |
| + this.advance_(true /* forward */, this.repeat); |
| }, |
| /** |
| @@ -198,7 +277,7 @@ AudioPlayerElement.prototype = { |
| * This handler is registered in this.ready(). |
| */ |
| onAudioError: function() { |
| - this.scheduleAutoAdvance_(true /* forward */, this.model.repeat); |
| + this.scheduleAutoAdvance_(true /* forward */, this.repeat); |
| }, |
| /** |
| @@ -207,10 +286,10 @@ AudioPlayerElement.prototype = { |
| * @private |
| */ |
| onAudioStatusUpdate_: function() { |
| - this.audioController.time = |
| + this.time = |
| (this.lastAudioUpdateTime_ = this.audioElement.currentTime * 1000); |
| - this.audioController.duration = this.audioElement.duration * 1000; |
| - this.audioController.playing = !this.audioElement.paused; |
| + this.duration = this.audioElement.duration * 1000; |
| + this.playing = !this.audioElement.paused; |
| }, |
| /** |
| @@ -221,7 +300,7 @@ AudioPlayerElement.prototype = { |
| // Changes the current time back to the beginning, regardless of the current |
| // status (playing or paused). |
| this.audioElement.currentTime = 0; |
| - this.audioController.time = 0; |
| + this.time = 0; |
| }, |
| /** |
| @@ -237,7 +316,7 @@ AudioPlayerElement.prototype = { |
| var isNextTrackAvailable = |
| (this.trackList.getNextTrackIndex(forward, repeat) !== -1); |
| - this.audioController.playing = isNextTrackAvailable; |
| + this.playing = isNextTrackAvailable; |
| // If there is only a single file in the list, 'currentTrackInde' is not |
| // changed and the handler is not invoked. Instead, plays here. |
| @@ -303,19 +382,6 @@ AudioPlayerElement.prototype = { |
| }, |
| /** |
| - * The index of the current track. |
| - * If the list has no tracks, the value must be -1. |
| - * |
| - * @type {number} |
| - */ |
| - get currentTrackIndex() { |
| - return this.trackList.currentTrackIndex; |
| - }, |
| - set currentTrackIndex(value) { |
| - this.trackList.currentTrackIndex = value; |
| - }, |
| - |
| - /** |
| * The list of the tracks in the playlist. |
| * |
| * When it changed, current operation including playback is stopped and |
| @@ -354,27 +420,26 @@ AudioPlayerElement.prototype = { |
| onKeyDown_: function(event) { |
| switch (event.keyIdentifier) { |
| case 'Up': |
| - if (this.audioController.volumeSliderShown && this.model.volume < 100) |
| + if (this.$.audioController.volumeSliderShown && this.model.volume < 100) |
| this.model.volume += 1; |
| break; |
| case 'Down': |
| - if (this.audioController.volumeSliderShown && this.model.volume > 0) |
| + if (this.$.audioController.volumeSliderShown && this.model.volume > 0) |
| this.model.volume -= 1; |
| break; |
| case 'PageUp': |
| - if (this.audioController.volumeSliderShown && this.model.volume < 91) |
| + if (this.$.audioController.volumeSliderShown && this.model.volume < 91) |
| this.model.volume += 10; |
| break; |
| case 'PageDown': |
| - if (this.audioController.volumeSliderShown && this.model.volume > 9) |
| + if (this.$.audioController.volumeSliderShown && this.model.volume > 9) |
| this.model.volume -= 10; |
| break; |
| case 'MediaNextTrack': |
| this.onControllerNextClicked(); |
| break; |
| case 'MediaPlayPause': |
| - var playing = this.audioController.playing; |
| - this.onControllerPlayingChanged(playing, !playing); |
| + this.playing = !this.playing; |
| break; |
| case 'MediaPreviousTrack': |
| this.onControllerPreviousClicked(); |
| @@ -384,6 +449,15 @@ AudioPlayerElement.prototype = { |
| break; |
| } |
| }, |
| + |
| + /** |
| + * Computes volume value for audio element. (should be in [0.0, 1.0]) |
| + * @param {number} volume Volume which is set in the UI. ([0, 100]) |
| + * @return {number} |
| + */ |
| + computeAudioVolume_: function(volume) { |
| + return volume / 100; |
| + } |
| }; |
| -Polymer('audio-player', AudioPlayerElement.prototype); |
| +Polymer(AudioPlayerElement.prototype); |