diff options
Diffstat (limited to 'javascript/videojs/src/js/tracks/video-track-list.js')
| -rw-r--r-- | javascript/videojs/src/js/tracks/video-track-list.js | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/javascript/videojs/src/js/tracks/video-track-list.js b/javascript/videojs/src/js/tracks/video-track-list.js new file mode 100644 index 0000000..d6f8bfb --- /dev/null +++ b/javascript/videojs/src/js/tracks/video-track-list.js @@ -0,0 +1,119 @@ +/** + * @file video-track-list.js + */ +import TrackList from './track-list'; + +/** @import VideoTrack from './video-track' */ + +/** + * Un-select all other {@link VideoTrack}s that are selected. + * + * @param {VideoTrackList} list + * list to work on + * + * @param {VideoTrack} track + * The track to skip + * + * @private + */ +const disableOthers = function(list, track) { + for (let i = 0; i < list.length; i++) { + if (!Object.keys(list[i]).length || track.id === list[i].id) { + continue; + } + // another video track is enabled, disable it + list[i].selected = false; + } +}; + +/** + * The current list of {@link VideoTrack} for a video. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist} + * @extends TrackList + */ +class VideoTrackList extends TrackList { + + /** + * Create an instance of this class. + * + * @param {VideoTrack[]} [tracks=[]] + * A list of `VideoTrack` to instantiate the list with. + */ + constructor(tracks = []) { + // make sure only 1 track is enabled + // sorted from last index to first index + for (let i = tracks.length - 1; i >= 0; i--) { + if (tracks[i].selected) { + disableOthers(tracks, tracks[i]); + break; + } + } + + super(tracks); + this.changing_ = false; + + /** + * @member {number} VideoTrackList#selectedIndex + * The current index of the selected {@link VideoTrack`}. + */ + Object.defineProperty(this, 'selectedIndex', { + get() { + for (let i = 0; i < this.length; i++) { + if (this[i].selected) { + return i; + } + } + return -1; + }, + set() {} + }); + } + + /** + * Add a {@link VideoTrack} to the `VideoTrackList`. + * + * @param {VideoTrack} track + * The VideoTrack to add to the list + * + * @fires TrackList#addtrack + */ + addTrack(track) { + if (track.selected) { + disableOthers(this, track); + } + + super.addTrack(track); + // native tracks don't have this + if (!track.addEventListener) { + return; + } + + track.selectedChange_ = () => { + if (this.changing_) { + return; + } + this.changing_ = true; + disableOthers(this, track); + this.changing_ = false; + this.trigger('change'); + }; + + /** + * @listens VideoTrack#selectedchange + * @fires TrackList#change + */ + track.addEventListener('selectedchange', track.selectedChange_); + } + + removeTrack(rtrack) { + super.removeTrack(rtrack); + + if (rtrack.removeEventListener && rtrack.selectedChange_) { + rtrack.removeEventListener('selectedchange', rtrack.selectedChange_); + rtrack.selectedChange_ = null; + } + } +} + +export default VideoTrackList; |
