diff --git a/src/js/tracks/audio-track-list.js b/src/js/tracks/audio-track-list.js index 07c072c24d..60b8c5bcc6 100644 --- a/src/js/tracks/audio-track-list.js +++ b/src/js/tracks/audio-track-list.js @@ -6,11 +6,16 @@ import * as browser from '../utils/browser.js'; import document from 'global/document'; /** - * anywhere we call this function we diverge from the spec + * Anywhere we call this function we diverge from the spec * as we only support one enabled audiotrack at a time * - * @param {Array|AudioTrackList} list list to work on - * @param {AudioTrack} track the track to skip + * @param {AudioTrackList} list + * list to work on + * + * @param {AudioTrack} track + * The track to skip + * + * @private */ const disableOthers = function(list, track) { for (let i = 0; i < list.length; i++) { @@ -23,25 +28,19 @@ const disableOthers = function(list, track) { }; /** - * A list of possible audio tracks. All functionality is in the - * base class Tracklist and the spec for AudioTrackList is located at: - * @link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist - * - * interface AudioTrackList : EventTarget { - * readonly attribute unsigned long length; - * getter AudioTrack (unsigned long index); - * AudioTrack? getTrackById(DOMString id); + * The current list of {@link AudioTrack} for a media file. * - * attribute EventHandler onchange; - * attribute EventHandler onaddtrack; - * attribute EventHandler onremovetrack; - * }; - * - * @param {AudioTrack[]} tracks a list of audio tracks to instantiate the list with + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist} * @extends TrackList - * @class AudioTrackList */ class AudioTrackList extends TrackList { + + /** + * Create an instance of this class. + * + * @param {AudioTrack[]} [tracks=[]] + * A list of `AudioTrack` to instantiate the list with. + */ constructor(tracks = []) { let list; @@ -76,6 +75,15 @@ class AudioTrackList extends TrackList { return list; } + /** + * Add an {@link AudioTrack} to the `AudioTrackList`. + * + * @param {AudioTrack} track + * The AudioTrack to add to the list + * + * @fires Track#addtrack + * @private + */ addTrack_(track) { if (track.enabled) { disableOthers(this, track); @@ -87,6 +95,10 @@ class AudioTrackList extends TrackList { return; } + /** + * @listens AudioTrack#enabledchange + * @fires TrackList#change + */ track.addEventListener('enabledchange', () => { // when we are disabling other tracks (since we don't support // more than one track at a time) we will set changing_ @@ -101,10 +113,26 @@ class AudioTrackList extends TrackList { }); } + /** + * Add an {@link AudioTrack} to the `AudioTrackList`. + * + * @param {AudioTrack} track + * The AudioTrack to add to the list + * + * @fires Track#addtrack + */ addTrack(track) { this.addTrack_(track); } + /** + * Remove an {@link AudioTrack} from the `AudioTrackList`. + * + * @param {AudioTrack} track + * The AudioTrack to remove from the list + * + * @fires Track#removetrack + */ removeTrack(track) { super.removeTrack_(track); } diff --git a/src/js/tracks/audio-track.js b/src/js/tracks/audio-track.js index aa8892c18b..1334e01f1b 100644 --- a/src/js/tracks/audio-track.js +++ b/src/js/tracks/audio-track.js @@ -4,21 +4,36 @@ import merge from '../utils/merge-options'; import * as browser from '../utils/browser.js'; /** - * A single audio text track as defined in: - * @link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack + * A representation of a single `AudioTrack`. If it is part of an {@link AudioTrackList} + * only one `AudioTrack` in the list will be enabled at a time. * - * interface AudioTrack { - * readonly attribute DOMString id; - * readonly attribute DOMString kind; - * readonly attribute DOMString label; - * readonly attribute DOMString language; - * attribute boolean enabled; - * }; - * - * @param {Object=} options Object of option names and values - * @class AudioTrack + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack} + * @extends Track */ class AudioTrack extends Track { + + /** + * Create an instance of this class. + * + * @param {Object} [options={}] + * Object of option names and values + * + * @param {AudioTrack~Kind} [options.kind=''] + * A valid audio track kind + * + * @param {string} [options.id='vjs_track_' + Guid.newGUID()] + * A unique id for this AudioTrack. + * + * @param {string} [options.label=''] + * The menu label for this track. + * + * @param {string} [options.language=''] + * A valid two character language code. + * + * @param {boolean} [options.enabled] + * If this track is the one that is currently playing. If this track is part of + * an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled. + */ constructor(options = {}) { const settings = merge(options, { kind: AudioTrackKind[options.kind] || '' @@ -35,7 +50,13 @@ class AudioTrack extends Track { } } } - + /** + * @member {boolean} enabled + * If this `AudioTrack` is enabled or not. When setting this will + * fire {@link AudioTrack#enabledchange} if the state of enabled is changed. + * + * @fires VideoTrack#selectedchange + */ Object.defineProperty(track, 'enabled', { get() { return enabled; @@ -46,6 +67,17 @@ class AudioTrack extends Track { return; } enabled = newEnabled; + + /** + * An event that fires when enabled changes on this track. This allows + * the AudioTrackList that holds this track to act accordingly. + * + * > Note: This is not part of the spec! Native tracks will do + * this internally without an event. + * + * @event AudioTrack#enabledchange + * @type {EventTarget~Event} + */ this.trigger('enabledchange'); } }); diff --git a/src/js/tracks/html-track-element-list.js b/src/js/tracks/html-track-element-list.js index 92e9a1a9ee..5f18320993 100644 --- a/src/js/tracks/html-track-element-list.js +++ b/src/js/tracks/html-track-element-list.js @@ -5,7 +5,17 @@ import * as browser from '../utils/browser.js'; import document from 'global/document'; +/** + * The current list of {@link HtmlTrackElement}s. + */ class HtmlTrackElementList { + + /** + * Create an instance of this class. + * + * @param {HtmlTrackElement[]} [tracks=[]] + * A list of `HtmlTrackElement` to instantiate the list with. + */ constructor(trackElements = []) { let list = this; // eslint-disable-line @@ -21,6 +31,10 @@ class HtmlTrackElementList { list.trackElements_ = []; + /** + * @member {number} length + * The current number of `Track`s in the this Trackist. + */ Object.defineProperty(list, 'length', { get() { return this.trackElements_.length; @@ -36,6 +50,14 @@ class HtmlTrackElementList { } } + /** + * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList` + * + * @param {HtmlTrackElement} trackElement + * The track element to add to the list. + * + * @private + */ addTrackElement_(trackElement) { const index = this.trackElements_.length; @@ -53,6 +75,18 @@ class HtmlTrackElementList { } } + /** + * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an + * {@link TextTrack}. + * + * @param {TextTrack} track + * The track associated with a track element. + * + * @return {HtmlTrackElement|undefined} + * The track element that was found or undefined. + * + * @private + */ getTrackElementByTrack_(track) { let trackElement_; @@ -67,6 +101,14 @@ class HtmlTrackElementList { return trackElement_; } + /** + * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList` + * + * @param {HtmlTrackElement} trackElement + * The track element to remove from the list. + * + * @private + */ removeTrackElement_(trackElement) { for (let i = 0, length = this.trackElements_.length; i < length; i++) { if (trackElement === this.trackElements_[i]) { diff --git a/src/js/tracks/html-track-element.js b/src/js/tracks/html-track-element.js index c3e3d393d4..f61d15a986 100644 --- a/src/js/tracks/html-track-element.js +++ b/src/js/tracks/html-track-element.js @@ -7,35 +7,57 @@ import document from 'global/document'; import EventTarget from '../event-target'; import TextTrack from '../tracks/text-track'; +/** + * @typedef {HTMLTrackElement~ReadyState} + * @enum {number} + */ const NONE = 0; const LOADING = 1; const LOADED = 2; const ERROR = 3; /** - * https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement - * - * interface HTMLTrackElement : HTMLElement { - * attribute DOMString kind; - * attribute DOMString src; - * attribute DOMString srclang; - * attribute DOMString label; - * attribute boolean default; - * - * const unsigned short NONE = 0; - * const unsigned short LOADING = 1; - * const unsigned short LOADED = 2; - * const unsigned short ERROR = 3; - * readonly attribute unsigned short readyState; + * A single track represented in the DOM. * - * readonly attribute TextTrack track; - * }; - * - * @param {Object} options TextTrack configuration - * @class HTMLTrackElement + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement} + * @extends EventTarget */ - class HTMLTrackElement extends EventTarget { + + /** + * Create an instance of this class. + * + * @param {Object} options={} + * Object of option names and values + * + * @param {Tech} options.tech + * A reference to the tech that owns this HTMLTrackElement. + * + * @param {TextTrack~Kind} [options.kind='subtitles'] + * A valid text track kind. + * + * @param {TextTrack~Mode} [options.mode='disabled'] + * A valid text track mode. + * + * @param {string} [options.id='vjs_track_' + Guid.newGUID()] + * A unique id for this TextTrack. + * + * @param {string} [options.label=''] + * The menu label for this track. + * + * @param {string} [options.language=''] + * A valid two character language code. + * + * @param {string} [options.srclang=''] + * A valid two character language code. An alternative, but deprioritized + * vesion of `options.language` + * + * @param {string} [options.src] + * A url to TextTrack cues. + * + * @param {boolean} [options.default] + * If this track should default to on or off. + */ constructor(options = {}) { super(); @@ -60,12 +82,20 @@ class HTMLTrackElement extends EventTarget { trackElement.label = track.label; trackElement.default = track.default; + /** + * @member {HTMLTrackElement~ReadyState} readyState + * The current ready state of the track element. + */ Object.defineProperty(trackElement, 'readyState', { get() { return readyState; } }); + /** + * @member {TextTrack} track + * The underlying TextTrack object. + */ Object.defineProperty(trackElement, 'track', { get() { return track; @@ -74,6 +104,10 @@ class HTMLTrackElement extends EventTarget { readyState = NONE; + /** + * @listens TextTrack#loadeddata + * @fires HTMLTrackElement#load + */ track.addEventListener('loadeddata', function() { readyState = LOADED; diff --git a/src/js/tracks/text-track-cue-list.js b/src/js/tracks/text-track-cue-list.js index eef9d559a0..dcd0a24b39 100644 --- a/src/js/tracks/text-track-cue-list.js +++ b/src/js/tracks/text-track-cue-list.js @@ -5,20 +5,36 @@ import * as browser from '../utils/browser.js'; import document from 'global/document'; /** - * A List of text track cues as defined in: - * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist + * @typedef {Object} TextTrackCue * - * interface TextTrackCueList { - * readonly attribute unsigned long length; - * getter TextTrackCue (unsigned long index); - * TextTrackCue? getCueById(DOMString id); - * }; + * @property {string} id + * The unique id for this text track cue * - * @param {Array} cues A list of cues to be initialized with - * @class TextTrackCueList + * @property {number} startTime + * The start time for this text track cue + * + * @property {number} endTime + * The end time for this text track cue + * + * @property {boolean} pauseOnExit + * Pause when the end time is reached if true. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcue} */ +/** + * A List of TextTrackCues. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist} + */ class TextTrackCueList { + + /** + * Create an instance of this class.. + * + * @param {Array} cues + * A list of cues to be initialized with + */ constructor(cues) { let list = this; // eslint-disable-line @@ -34,6 +50,10 @@ class TextTrackCueList { TextTrackCueList.prototype.setCues_.call(list, cues); + /** + * @member {number} length + * The current number of `TextTrackCue`s in the TextTrackCueList. + */ Object.defineProperty(list, 'length', { get() { return this.length_; @@ -46,10 +66,12 @@ class TextTrackCueList { } /** - * A setter for cues in this list + * A setter for cues in this list. Creates getters + * an an index for the cues. + * + * @param {Array} cues + * An array of cues to set * - * @param {Array} cues an array of cues - * @method setCues_ * @private */ setCues_(cues) { @@ -80,11 +102,13 @@ class TextTrackCueList { } /** - * Get a cue that is currently in the Cue list by id + * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id. + * + * @param {string} id + * The id of the cue that should be searched for. * - * @param {String} id - * @method getCueById - * @return {Object} a single cue + * @return {TextTrackCue|null} + * A single cue or null if none was found. */ getCueById(id) { let result = null; diff --git a/src/js/tracks/text-track-display.js b/src/js/tracks/text-track-display.js index 1b506de452..593a0eed1f 100644 --- a/src/js/tracks/text-track-display.js +++ b/src/js/tracks/text-track-display.js @@ -21,12 +21,18 @@ const fontMap = { }; /** - * Add cue HTML to display + * Construct an rgba color from a given hex color code. * - * @param {Number} color Hex number for color, like #f0e - * @param {Number} opacity Value for opacity,0.0 - 1.0 - * @return {RGBAColor} In the form 'rgba(255, 0, 0, 0.3)' - * @method constructColor + * @param {number} color + * Hex number for color, like #f0e. + * + * @param {number} opacity + * Value for opacity, 0.0 - 1.0. + * + * @return {string} + * The rgba color that was created, like 'rgba(255, 0, 0, 0.3)'. + * + * @private */ function constructColor(color, opacity) { return 'rgba(' + @@ -38,13 +44,17 @@ function constructColor(color, opacity) { } /** - * Try to update style - * Some style changes will throw an error, particularly in IE8. Those should be noops. + * Try to update the style of a DOM element. Some style changes will throw an error, + * particularly in IE8. Those should be noops. * - * @param {Element} el The element to be styles - * @param {CSSProperty} style The CSS property to be styled - * @param {CSSStyle} rule The actual style to be applied to the property - * @method tryUpdateStyle + * @param {Element} el + * The DOM element to be styled. + * + * @param {string} style + * The CSS property on the element that should be styled. + * + * @param {string} rule + * The style rule that should be applied to the property. */ function tryUpdateStyle(el, style, rule) { try { @@ -57,16 +67,24 @@ function tryUpdateStyle(el, style, rule) { } /** - * The component for displaying text track cues + * The component for displaying text track cues. * - * @param {Object} player Main Player - * @param {Object=} options Object of option names and values - * @param {Function=} ready Ready callback function * @extends Component - * @class TextTrackDisplay */ class TextTrackDisplay extends Component { + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + * + * @param {Component~ReadyCallback} [ready] + * The function to call when `TextTrackDisplay` is ready. + */ constructor(player, options, ready) { super(player, options, ready); @@ -123,9 +141,12 @@ class TextTrackDisplay extends Component { } /** - * Toggle display texttracks + * Turn display of {@link TextTrack}'s from the current state into the other state. + * There are only two states: + * - 'shown' + * - 'hidden' * - * @method toggleDisplay + * @listens Player#loadstart */ toggleDisplay() { if (this.player_.tech_ && this.player_.tech_.featuresNativeTextTracks) { @@ -136,10 +157,10 @@ class TextTrackDisplay extends Component { } /** - * Create the component's DOM element + * Create the {@link Component}'s DOM element. * * @return {Element} - * @method createEl + * The element that was created. */ createEl() { return super.createEl('div', { @@ -151,9 +172,7 @@ class TextTrackDisplay extends Component { } /** - * Clear display texttracks - * - * @method clearDisplay + * Clear all displayed {@link TextTrack}s. */ clearDisplay() { if (typeof window.WebVTT === 'function') { @@ -162,9 +181,11 @@ class TextTrackDisplay extends Component { } /** - * Update display texttracks + * Update the displayed TextTrack when a either a {@link Player#texttrackchange} or + * a {@link Player#fullscreenchange} is fired. * - * @method updateDisplay + * @listens Player#texttrackchange + * @listens Player#fullscreenchange */ updateDisplay() { const tracks = this.player_.textTracks(); @@ -210,10 +231,10 @@ class TextTrackDisplay extends Component { } /** - * Add texttrack to texttrack list + * Add an {@link Texttrack} to to the {@link Tech}s {@link TextTrackList}. * - * @param {TextTrackObject} track Texttrack object to be added to list - * @method updateForTrack + * @param {TextTrack} track + * Text track object to be added to the list. */ updateForTrack(track) { if (typeof window.WebVTT !== 'function' || !track.activeCues) { diff --git a/src/js/tracks/text-track-list-converter.js b/src/js/tracks/text-track-list-converter.js index 375e584e32..eff665d7b8 100644 --- a/src/js/tracks/text-track-list-converter.js +++ b/src/js/tracks/text-track-list-converter.js @@ -3,13 +3,18 @@ * based on a capture. * * @file text-track-list-converter.js + * @module text-track-list-converter */ /** - * Examine a single text track and return a JSON-compatible javascript - * object that represents the text track's state. - * @param track {TextTrackObject} the text track to query - * @return {Object} a serializable javascript representation of the + * Examine a single {@link TextTrack} and return a JSON-compatible javascript object that + * represents the {@link TextTrack}'s state. + * + * @param {TextTrack} track + * The text track to query. + * + * @return {Object} + * A serializable javascript representation of the TextTrack. * @private */ const trackToJson_ = function(track) { @@ -38,12 +43,16 @@ const trackToJson_ = function(track) { }; /** - * Examine a tech and return a JSON-compatible javascript array that - * represents the state of all text tracks currently configured. The - * return array is compatible with `jsonToTextTracks`. - * @param tech {tech} the tech object to query - * @return {Array} a serializable javascript representation of the - * @function textTracksToJson + * Examine a {@link Tech} and return a JSON-compatible javascript array that represents the + * state of all {@link TextTrack}s currently configured. The return array is compatible with + * {@link text-track-list-converter:jsonToTextTracks}. + * + * @param {Tech} tech + * The tech object to query + * + * @return {Array} + * A serializable javascript representation of the {@link Tech}s + * {@link TextTrackList}. */ const textTracksToJson = function(tech) { @@ -65,12 +74,15 @@ const textTracksToJson = function(tech) { }; /** - * Creates a set of remote text tracks on a tech based on an array of - * javascript text track representations. - * @param json {Array} an array of text track representation objects, - * like those that would be produced by `textTracksToJson` - * @param tech {tech} the tech to create text tracks on - * @function jsonToTextTracks + * Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript + * object {@link TextTrack} representations. + * + * @param {Array} json + * An array of `TextTrack` representation objects, like those that would be + * produced by `textTracksToJson`. + * + * @param {Tech} tech + * The `Tech` to create the `TextTrack`s on. */ const jsonToTextTracks = function(json, tech) { json.forEach(function(track) { diff --git a/src/js/tracks/text-track-list.js b/src/js/tracks/text-track-list.js index 58610d2c6c..60f94e426c 100644 --- a/src/js/tracks/text-track-list.js +++ b/src/js/tracks/text-track-list.js @@ -7,25 +7,19 @@ import * as browser from '../utils/browser.js'; import document from 'global/document'; /** - * A list of possible text tracks. All functionality is in the - * base class TrackList. The spec for TextTrackList is located at: - * @link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist + * The current list of {@link TextTrack} for a media file. * - * interface TextTrackList : EventTarget { - * readonly attribute unsigned long length; - * getter TextTrack (unsigned long index); - * TextTrack? getTrackById(DOMString id); - * - * attribute EventHandler onchange; - * attribute EventHandler onaddtrack; - * attribute EventHandler onremovetrack; - * }; - * - * @param {TextTrack[]} tracks A list of tracks to initialize the list with + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist} * @extends TrackList - * @class TextTrackList */ class TextTrackList extends TrackList { + + /** + * Create an instance of this class. + * + * @param {TextTrack[]} [tracks=[]] + * A list of `TextTrack` to instantiate the list with. + */ constructor(tracks = []) { let list; @@ -49,68 +43,25 @@ class TextTrackList extends TrackList { return list; } - addTrack_(track) { - super.addTrack_(track); - track.addEventListener('modechange', Fn.bind(this, function() { - this.trigger('change'); - })); - } - /** - * Remove TextTrack from TextTrackList - * NOTE: Be mindful of what is passed in as it may be a HTMLTrackElement + * Add a {@link TextTrack} to the `TextTrackList` * - * @param {TextTrack} rtrack - * @method removeTrack_ - * @private - */ - removeTrack_(rtrack) { - let track; - - for (let i = 0, l = this.length; i < l; i++) { - if (this[i] === rtrack) { - track = this[i]; - if (track.off) { - track.off(); - } - - this.tracks_.splice(i, 1); - - break; - } - } - - if (!track) { - return; - } - - this.trigger({ - track, - type: 'removetrack' - }); - } - - /** - * Get a TextTrack from TextTrackList by a tracks id + * @param {TextTrack} track + * The text track to add to the list. * - * @param {String} id - the id of the track to get - * @method getTrackById - * @return {TextTrack} + * @fires TrackList#addtrack * @private */ - getTrackById(id) { - let result = null; - - for (let i = 0, l = this.length; i < l; i++) { - const track = this[i]; - - if (track.id === id) { - result = track; - break; - } - } + addTrack_(track) { + super.addTrack_(track); - return result; + /** + * @listens TextTrack#modechange + * @fires TrackList#change + */ + track.addEventListener('modechange', Fn.bind(this, function() { + this.trigger('change'); + })); } } export default TextTrackList; diff --git a/src/js/tracks/text-track-settings.js b/src/js/tracks/text-track-settings.js index 8f7fc0c810..3964e78d1e 100644 --- a/src/js/tracks/text-track-settings.js +++ b/src/js/tracks/text-track-settings.js @@ -158,14 +158,20 @@ const selectConfigs = { selectConfigs.windowColor.options = selectConfigs.backgroundColor.options; /** - * Parses out option values. + * Get the actual value of an option. + * + * @param {string} value + * The value to get * - * @private - * @param {String} value * @param {Function} [parser] * Optional function to adjust the value. + * * @return {Mixed} - * Will be `undefined` if no value exists (or if given value is "none"). + * - Will be `undefined` if no value exists + * - Will be `undefined` if the given value is "none". + * - Will be the actual value otherwise. + * + * @private */ function parseOptionValue(value, parser) { if (parser) { @@ -180,10 +186,18 @@ function parseOptionValue(value, parser) { /** * Gets the value of the selected