Chromium Code Reviews| Index: chrome/browser/resources/file_manager/audio_player/elements/track_list.js |
| diff --git a/chrome/browser/resources/file_manager/audio_player/elements/track_list.js b/chrome/browser/resources/file_manager/audio_player/elements/track_list.js |
| index 5faee2daac83b046a3f0ee69522b277a1c183b1b..be5263b632c69654e34143a8851737441680a513 100644 |
| --- a/chrome/browser/resources/file_manager/audio_player/elements/track_list.js |
| +++ b/chrome/browser/resources/file_manager/audio_player/elements/track_list.js |
| @@ -23,6 +23,12 @@ |
| tracks: [], |
| /** |
| + * Play order of the tracks. Each value is the index of 'this.tracks'. |
| + * @type {Array.<number>} |
| + */ |
| + playOrder: [], |
| + |
| + /** |
| * Track index of the current track. |
| * If the tracks propertye is empty, it should be -1. Otherwise, be a valid |
| * track number. |
| @@ -32,6 +38,21 @@ |
| currentTrackIndex: -1, |
| /** |
| + * Flag whether the shuffle mode is enabled. |
| + * @type {boolean} |
| + */ |
| + shuffle: false, |
| + |
| + /** |
| + * Invoked when 'shuffle' property is changed. |
| + * @param {boolean} oldValue Old value. |
| + * @param {boolean} newValue New value. |
| + */ |
| + shuffleChanged: function(oldValue, newValue) { |
| + this.generatePlayOrder(true /* keep the current track */); |
| + }, |
| + |
| + /** |
| * Invoked when the current track index is changed. |
| * @param {number} oldValue old value. |
| * @param {number} newValue new value. |
| @@ -40,17 +61,23 @@ |
| if (oldValue === newValue) |
| return; |
| - if (oldValue !== -1) |
| + if (!isNaN(oldValue) && oldValue !== -1) |
| this.tracks[oldValue].active = false; |
| - if (newValue < 0 || this.tracks.length <= newValue) { |
| - if (this.tracks.length === 0) |
| - this.currentTrackIndex = -1; |
| - else |
| - this.currentTrackIndex = 0; |
| - } else { |
| - this.tracks[newValue].active = true; |
| + if (0 <= newValue && newValue < this.tracks.length) { |
| + var currentPlayOrder = this.playOrder.indexOf(newValue); |
| + if (currentPlayOrder !== -1) { |
| + // Success |
| + this.tracks[newValue].active = true; |
| + return; |
| + } |
| } |
| + |
| + // Invalid index |
| + if (this.tracks.length === 0) |
| + this.currentTrackIndex = -1; |
| + else |
| + this.generatePlayOrder(false /* no need to keep the current track */); |
| }, |
| /** |
| @@ -59,16 +86,21 @@ |
| */ |
| tracksChanged: function(oldValue, newValue) { |
| if (oldValue !== newValue) { |
| + // Re-register the observer of 'this.tracks'. |
| this.tracksObserver_.close(); |
| this.tracksObserver_ = new ArrayObserver( |
| this.tracks, |
| this.tracksValueChanged_.bind(this)); |
| + |
| + // Reset play order and current index. |
| if (this.tracks.length !== 0) |
| - this.currentTrackIndex = 0; |
| + this.generatePlayOrder(false /* no need to keep the current track */); |
| } |
| - if (this.tracks.length === 0) |
| + if (this.tracks.length === 0) { |
| + this.playOrder = []; |
| this.currentTrackIndex = -1; |
| + } |
| }, |
| /** |
| @@ -92,6 +124,45 @@ |
| }, |
| /** |
| + * Invoked when the track element is clicked. |
| + * @param {Event} event Click event. |
|
hirono
2014/02/03 08:09:52
nit: @param {boolean} keepCurrentTrack ... ?
yoshiki
2014/02/03 09:38:41
Yes, Thanks!
|
| + */ |
| + generatePlayOrder: function(keepCurrentTrack) { |
| + if (this.tracks.length === 0) { |
| + this.playOrder = []; |
| + return; |
| + } |
| + |
| + // Creates sequenced array. |
| + this.playOrder = |
|
hirono
2014/02/03 08:09:52
How about: this.tracks.map(function(unused, index)
yoshiki
2014/02/03 09:38:41
Done.
|
| + Array.apply(null, Array(this.tracks.length)). |
| + map(function(unused, index) { return index; }); |
| + |
| + if (this.shuffle) { |
| + // Randomizes the play order array (Schwarzian-transform algorithm). |
| + this.playOrder = |
| + this.playOrder. |
| + map(function(a) { |
| + return {weight: Math.random(), index: a}; |
| + }). |
| + sort(function(a, b) { return a.weight - b.weight }). |
| + map(function(a) { return a.index }); |
| + |
| + if (keepCurrentTrack) { |
| + // Puts the current track at the beginning of the play order. |
| + this.playOrder = |
| + this.playOrder.filter(function(value) { |
| + return this.currentTrackIndex !== value; |
| + }, this); |
| + this.playOrder.splice(0, 0, this.currentTrackIndex); |
| + } |
| + } |
| + |
| + if (!keepCurrentTrack) |
| + this.currentTrackIndex = this.playOrder[0]; |
| + }, |
| + |
| + /** |
| * Sets the current track. |
| * @param {AudioPlayer.TrackInfo} track TrackInfo to be set as the current |
| * track. |
| @@ -127,23 +198,23 @@ |
| * @return {AudioPlayer.TrackInfo} TrackInfo of the next track. If there is |
|
hirono
2014/02/03 08:09:52
nit: @return {number} ... ?
yoshiki
2014/02/03 09:38:41
Done.
|
| * no track, the return value is null. |
| */ |
| - getNextTrackIndex: function(forward) { |
| - var defaultTrack = forward ? 0 : (this.tracks.length - 1); |
| - var tentativeNewTrackIndex = this.currentTrackIndex + (forward ? +1 : -1); |
| - var newTrackIndex; |
| + getNextTrackIndex: function(forward) { |
| + if (this.tracks.length === 0) |
| + return -1; |
| - if (this.tracks.length === 0) { |
| - newTrackIndex = -1; |
| - } else { |
| - if (this.currentTrackIndex === -1) { |
| - newTrackIndex = defaultTrack; |
| - } else if (0 <= tentativeNewTrackIndex && |
| - tentativeNewTrackIndex < this.tracks.length) { |
| - newTrackIndex = tentativeNewTrackIndex; |
| - } else { |
| - newTrackIndex = defaultTrack; |
| - } |
| - } |
| + var defaultTrack = |
|
hirono
2014/02/03 08:09:52
Please rename it with defaultTrackIndex.
yoshiki
2014/02/03 09:38:41
Done.
|
| + forward ? this.playOrder[0] : this.playOrder[this.tracks.length - 1]; |
| + |
| + var currentPlayOrder = this.playOrder.indexOf(this.currentTrackIndex); |
| + var newPlayOrder = currentPlayOrder + (forward ? +1 : -1); |
| + // The below "if (!(...))" is intentional, to catch undefined and NaN. |
| + if (!(0 <= newPlayOrder && newPlayOrder < this.tracks.length)) |
| + return defaultTrack; |
| + |
| + var newTrackIndex = this.playOrder[newPlayOrder]; |
| + console.assert( |
| + (0 <= newTrackIndex && newTrackIndex < this.tracks.length), |
| + 'Insufficient TrackList.playOrder. New Play Order: ' + newPlayOrder); |
| return newTrackIndex; |
| }, |
| @@ -157,21 +228,21 @@ |
| * otherwise. |
| */ |
| isNextTrackAvailable: function(forward) { |
| - if (this.tracks.length === 0) { |
| + if (this.tracks.length === 0) |
| return false; |
| - } else { |
| - var tentativeNewTrackIndex = |
| - this.currentTrackIndex + (forward ? +1 : -1); |
| - |
| - if (this.currentTrackIndex === -1) { |
| - return false; |
| - } else if (0 <= tentativeNewTrackIndex && |
| - tentativeNewTrackIndex < this.tracks.length) { |
| - return true; |
| - } else { |
| - return false; |
| - } |
| - } |
| - } |
| + |
| + var currentPlayOrder = this.playOrder.indexOf(this.currentTrackIndex); |
| + var newPlayOrder = currentPlayOrder + (forward ? +1 : -1); |
| + // The below "if (!(...))" is intentional, to catch undefined and NaN. |
| + if (!(0 <= newPlayOrder && newPlayOrder < this.tracks.length)) |
|
hirono
2014/02/03 08:09:52
If currentPlayOrder is -1, it would return true.
I
yoshiki
2014/02/03 09:38:41
It's ok. Added the comment to explain this.
hirono
2014/02/03 09:57:48
Maybe I lost the point.
Can we ensure currentPlay
yoshiki
2014/02/03 10:46:14
That's good point. It shouldn't be occurred, but a
|
| + return false; |
| + |
| + var newTrackIndex = this.playOrder[newPlayOrder]; |
| + console.assert( |
| + (0 <= newTrackIndex && newTrackIndex < this.tracks.length), |
| + 'Insufficient TrackList.playOrder. New Play Order: ' + newPlayOrder); |
| + |
| + return true; |
| + }, |
| }); // Polymer('track-list') block |
| })(); // Anonymous closure |