| 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..a5b07e2d2e3666118b44f1ac671bd32f9bcc827c 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,48 @@
|
| },
|
|
|
| /**
|
| + * Invoked when the track element is clicked.
|
| + * @param {boolean} keepCurrentTrack Keep the current track or not.
|
| + */
|
| + generatePlayOrder: function(keepCurrentTrack) {
|
| + console.assert((keepCurrentTrack !== undefined),
|
| + 'The argument "forward" is undefined');
|
| +
|
| + if (this.tracks.length === 0) {
|
| + this.playOrder = [];
|
| + return;
|
| + }
|
| +
|
| + // Creates sequenced array.
|
| + this.playOrder =
|
| + this.tracks.
|
| + 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.
|
| @@ -120,58 +194,39 @@
|
| },
|
|
|
| /**
|
| - * Returns the next (or previous) track in the track list.
|
| + * Returns the next (or previous) track in the track list. If there is no
|
| + * next track, returns -1.
|
| *
|
| * @param {boolean} forward Specify direction: forward or previous mode.
|
| * True: forward mode, false: previous mode.
|
| - * @return {AudioPlayer.TrackInfo} TrackInfo of the next track. If there is
|
| - * no track, the return value is null.
|
| + * @param {boolean} cyclic Specify if cyclically or not: It true, the first
|
| + * track is succeeding to the last track, otherwise no track after the
|
| + * last.
|
| + * @return {number} The next track index.
|
| */
|
| - getNextTrackIndex: function(forward) {
|
| - var defaultTrack = forward ? 0 : (this.tracks.length - 1);
|
| - var tentativeNewTrackIndex = this.currentTrackIndex + (forward ? +1 : -1);
|
| - var newTrackIndex;
|
| + getNextTrackIndex: function(forward, cyclic) {
|
| + 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 defaultTrackIndex =
|
| + forward ? this.playOrder[0] : this.playOrder[this.tracks.length - 1];
|
| +
|
| + var currentPlayOrder = this.playOrder.indexOf(this.currentTrackIndex);
|
| + console.assert(
|
| + (0 <= currentPlayOrder && currentPlayOrder < this.tracks.length),
|
| + 'Insufficient TrackList.playOrder. The current track is not on the ' +
|
| + 'track list.');
|
| +
|
| + var newPlayOrder = currentPlayOrder + (forward ? +1 : -1);
|
| + if (newPlayOrder === -1 || newPlayOrder === this.tracks.length)
|
| + return cyclic ? defaultTrackIndex : -1;
|
| +
|
| + var newTrackIndex = this.playOrder[newPlayOrder];
|
| + console.assert(
|
| + (0 <= newTrackIndex && newTrackIndex < this.tracks.length),
|
| + 'Insufficient TrackList.playOrder. New Play Order: ' + newPlayOrder);
|
|
|
| return newTrackIndex;
|
| },
|
| -
|
| - /**
|
| - * Returns if the next (or previous) track in the track list is available.
|
| - *
|
| - * @param {boolean} forward Specify direction: forward or previous mode.
|
| - * True: forward mode, false: previous mode.
|
| - * @return {true} True if the next (or previous) track available. False
|
| - * otherwise.
|
| - */
|
| - isNextTrackAvailable: function(forward) {
|
| - 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;
|
| - }
|
| - }
|
| - }
|
| }); // Polymer('track-list') block
|
| })(); // Anonymous closure
|
|
|