diff --git a/src/js/base-styles.js b/src/js/base-styles.js index d117d37806..be6e302393 100644 --- a/src/js/base-styles.js +++ b/src/js/base-styles.js @@ -1,6 +1,8 @@ /** -* This code injects the required base styles in the head of the document. -*/ + * @file base-styles.js + * + * This code injects the required base styles in the head of the document. + */ import window from 'global/window'; import document from 'global/document'; diff --git a/src/js/big-play-button.js b/src/js/big-play-button.js index a19f36dfc3..1487f7c2d5 100644 --- a/src/js/big-play-button.js +++ b/src/js/big-play-button.js @@ -1,22 +1,41 @@ +/** + * @file big-play-button.js + */ import Button from './button.js'; import Component from './component.js'; -/* Big Play Button -================================================================================ */ +/ * Big Play Button +================================================================================ */ /** * Initial play button. Shows before the video has played. The hiding of the * big play button is done via CSS and player states. - * @param {Player|Object} player - * @param {Object=} options - * @class - * @constructor + * + * @param {Object} player Main Player + * @param {Object=} options Object of option names and values + * @extends Button + * @class BigPlayButton */ class BigPlayButton extends Button { + constructor(player, options) { + super(player, options); + } + + /** + * Allow sub components to stack CSS class names + * + * @return {String} The constructed class name + * @method buildCSSClass + */ buildCSSClass() { return 'vjs-big-play-button'; } + /** + * Handles click for play + * + * @method handleClick + */ handleClick() { this.player_.play(); } diff --git a/src/js/button.js b/src/js/button.js index f5c5b5ab9b..0dde67f56c 100644 --- a/src/js/button.js +++ b/src/js/button.js @@ -1,3 +1,6 @@ +/** + * @file button.js + */ import Component from './component'; import * as Dom from './utils/dom.js'; import * as Events from './utils/events.js'; @@ -5,12 +8,13 @@ import * as Fn from './utils/fn.js'; import document from 'global/document'; import assign from 'object.assign'; -/* Button - Base class for all buttons -================================================================================ */ +/ * Button - Base class for all buttons +================================================================================ */ /** * Base class for all buttons - * @param {Player|Object} player - * @param {Object=} options + * + * @param {Object} player Main Player + * @param {Object=} options Object of option names and values * @extends Component * @class Button */ @@ -27,6 +31,14 @@ class Button extends Component { this.on('blur', this.handleBlur); } + /** + * Create the component's DOM element + * + * @param {String=} type Element's node type. e.g. 'div' + * @param {Object=} props An object of element attributes that should be set on the element Tag name + * @return {Element} + * @method createEl + */ createEl(type='button', props={}) { // Add standard Aria and Tabindex info props = assign({ @@ -49,6 +61,13 @@ class Button extends Component { return el; } + /** + * Controls text - both request and localize + * + * @param {String} text Text for button + * @return {String} + * @method controlText + */ controlText(text) { if (!text) return this.controlText_ || 'Need Text'; @@ -58,19 +77,37 @@ class Button extends Component { return this; } + /** + * Allows sub components to stack CSS class names + * + * @return {String} + * @method buildCSSClass + */ buildCSSClass() { return `vjs-control vjs-button ${super.buildCSSClass()}`; } - // Click - Override with specific functionality for button + /** + * Handle Click - Override with specific functionality for button + * + * @method handleClick + */ handleClick() {} - // Focus - Add keyboard functionality to element + /** + * Handle Focus - Add keyboard functionality to element + * + * @method handleFocus + */ handleFocus() { Events.on(document, 'keydown', Fn.bind(this, this.handleKeyPress)); } - // KeyPress (document level) - Trigger click when keys are pressed + /** + * Handle KeyPress (document level) - Trigger click when keys are pressed + * + * @method handleKeyPress + */ handleKeyPress(event) { // Check for space bar (32) or enter (13) keys if (event.which === 32 || event.which === 13) { @@ -79,7 +116,11 @@ class Button extends Component { } } - // Blur - Remove keyboard triggers + /** + * Handle Blur - Remove keyboard triggers + * + * @method handleBlur + */ handleBlur() { Events.off(document, 'keydown', Fn.bind(this, this.handleKeyPress)); } diff --git a/src/js/component.js b/src/js/component.js index 7daa1d600f..a1666cfd83 100644 --- a/src/js/component.js +++ b/src/js/component.js @@ -1,6 +1,7 @@ /** - * @fileoverview Player Component - Base class for all UI objects + * @file component.js * + * Player Component - Base class for all UI objects */ import window from 'global/window'; @@ -16,31 +17,31 @@ import mergeOptions from './utils/merge-options.js'; /** * Base UI Component class - * * Components are embeddable UI objects that are represented by both a * javascript object and an element in the DOM. They can be children of other * components, and can have many children themselves. - * + * ```js * // adding a button to the player * var button = player.addChild('button'); * button.el(); // -> button element - * + * ``` + * ```html *
*
Button
*
- * + * ``` * Components are also event emitters. - * + * ```js * button.on('click', function(){ * console.log('Button Clicked!'); * }); - * * button.trigger('customevent'); + * ``` * * @param {Object} player Main Player - * @param {Object=} options - * @class - * @constructor + * @param {Object=} options Object of option names and values + * @param {Function=} ready Ready callback function + * @class Component */ class Component { @@ -105,6 +106,8 @@ class Component { /** * Dispose of the component and all child components + * + * @method dispose */ dispose() { this.trigger({ type: 'dispose', bubbles: false }); @@ -139,6 +142,7 @@ class Component { * Return the component's player * * @return {Player} + * @method player */ player() { return this.player_; @@ -146,14 +150,12 @@ class Component { /** * Deep merge of options objects - * * Whenever a property is an object on both options objects * the two properties will be merged using mergeOptions. - * * This is used for merging options for child components. We * want it to be easy to override individual options on a child * component without having to rewrite all the other default options. - * + * ```js * Parent.prototype.options_ = { * children: { * 'childOne': { 'foo': 'bar', 'asdf': 'fdsa' }, @@ -170,9 +172,9 @@ class Component { * } * * this.options(newOptions); - * + * ``` * RESULT - * + * ```js * { * children: { * 'childOne': { 'foo': 'baz', 'asdf': 'fdsa', 'abc': '123' }, @@ -181,9 +183,11 @@ class Component { * 'childFour': {} * } * } + * ``` * * @param {Object} obj Object of new option values * @return {Object} A NEW object of this.options_ and obj merged + * @method options */ options(obj) { log.warn('this.options() has been deprecated and will be moved to the constructor in 6.0'); @@ -198,10 +202,12 @@ class Component { /** * Get the component's DOM element - * + * ```js * var domEl = myComponent.el(); + * ``` * * @return {Element} + * @method el */ el() { return this.el_; @@ -213,6 +219,7 @@ class Component { * @param {String=} tagName Element's node type. e.g. 'div' * @param {Object=} attributes An object of element attributes that should be set on the element * @return {Element} + * @method createEl */ createEl(tagName, attributes) { return Dom.createEl(tagName, attributes); @@ -247,6 +254,7 @@ class Component { * Will either be the same as el() or a new element defined in createEl(). * * @return {Element} + * @method contentEl */ contentEl() { return this.contentEl_ || this.el_; @@ -254,10 +262,12 @@ class Component { /** * Get the component's ID - * + * ```js * var id = myComponent.id(); + * ``` * * @return {String} + * @method id */ id() { return this.id_; @@ -265,10 +275,12 @@ class Component { /** * Get the component's name. The name is often used to reference the component. - * + * ```js * var name = myComponent.name(); + * ``` * * @return {String} + * @method name */ name() { return this.name_; @@ -276,10 +288,12 @@ class Component { /** * Get an array of all child components - * + * ```js * var kids = myComponent.children(); + * ``` * * @return {Array} The children + * @method children */ children() { return this.children_; @@ -289,6 +303,7 @@ class Component { * Returns a child component with the provided ID * * @return {Component} + * @method getChildById */ getChildById(id) { return this.childIndex_[id]; @@ -298,6 +313,7 @@ class Component { * Returns a child component with the provided name * * @return {Component} + * @method getChild */ getChild(name) { return this.childNameIndex_[name]; @@ -305,7 +321,7 @@ class Component { /** * Adds a child component inside this component - * + * ```js * myComponent.el(); * // ->
* myComponent.children(); @@ -314,9 +330,9 @@ class Component { * var myButton = myComponent.addChild('MyButton'); * // ->
myButton
* // -> myButton === myComonent.children()[0]; - * + * ``` * Pass in options for child constructors and options for children of the child - * + * ```js * var myButton = myComponent.addChild('MyButton', { * text: 'Press Me', * children: { @@ -325,11 +341,12 @@ class Component { * } * } * }); + * ``` * * @param {String|Component} child The class name or instance of a child to add * @param {Object=} options Options, including options to be passed to children of the child. * @return {Component} The child component (created by this process if a string was used) - * @suppress {accessControls|checkRegExp|checkTypes|checkVars|const|constantProperty|deprecated|duplicate|es5Strict|fileoverviewTags|globalThis|invalidCasts|missingProperties|nonStandardJsDocs|strictModuleDepCheck|undefinedNames|undefinedVars|unknownDefines|uselessCode|visibility} + * @method addChild */ addChild(child, options={}) { let component; @@ -397,6 +414,7 @@ class Component { * child component's element from this component's element * * @param {Component} component Component to remove + * @method removeChild */ removeChild(component) { if (typeof component === 'string') { @@ -433,7 +451,7 @@ class Component { /** * Add and initialize default child components from options - * + * ```js * // when an instance of MyComponent is created, all children in options * // will be added to the instance by their name strings and options * MyComponent.prototype.options_.children = { @@ -441,8 +459,9 @@ class Component { * myChildOption: true * } * } - * + * ``` * // Or when creating the component + * ```js * var myComp = new MyComponent(player, { * children: { * myChildComponent: { @@ -450,10 +469,10 @@ class Component { * } * } * }); - * + * ``` * The children option can also be an Array of child names or * child options objects (that also include a 'name' key). - * + * ```js * var myComp = new MyComponent(player, { * children: [ * 'button', @@ -463,7 +482,9 @@ class Component { * } * ] * }); + * ``` * + * @method initChildren */ initChildren() { let children = this.options_.children; @@ -528,6 +549,7 @@ class Component { * Allows sub components to stack CSS class names * * @return {String} The constructed class name + * @method buildCSSClass */ buildCSSClass() { // Child classes can include a function that does: @@ -537,26 +559,24 @@ class Component { /** * Add an event listener to this component's element - * + * ```js * var myFunc = function(){ * var myComponent = this; * // Do something when the event is fired * }; * * myComponent.on('eventType', myFunc); - * + * ``` * The context of myFunc will be myComponent unless previously bound. - * * Alternatively, you can add a listener to another element or component. - * + * ```js * myComponent.on(otherElement, 'eventName', myFunc); * myComponent.on(otherComponent, 'eventName', myFunc); - * + * ``` * The benefit of using this over `VjsEvents.on(otherElement, 'eventName', myFunc)` * and `otherComponent.on('eventName', myFunc)` is that this way the listeners * will be automatically cleaned up when either component is disposed. * It will also bind myComponent as the context of myFunc. - * * **NOTE**: When using this on elements in the page other than window * and document (both permanent), if you remove the element from the DOM * you need to call `myComponent.trigger(el, 'dispose')` on it to clean up @@ -565,7 +585,8 @@ class Component { * @param {String|Component} first The event type or other component * @param {Function|String} second The event handler or event type * @param {Function} third The event handler - * @return {Component} self + * @return {Component} + * @method on */ on(first, second, third) { if (typeof first === 'string' || Array.isArray(first)) { @@ -613,23 +634,24 @@ class Component { /** * Remove an event listener from this component's element - * + * ```js * myComponent.off('eventType', myFunc); - * + * ``` * If myFunc is excluded, ALL listeners for the event type will be removed. * If eventType is excluded, ALL listeners will be removed from the component. - * * Alternatively you can use `off` to remove listeners that were added to other * elements or components using `myComponent.on(otherComponent...`. * In this case both the event type and listener function are REQUIRED. - * + * ```js * myComponent.off(otherElement, 'eventType', myFunc); * myComponent.off(otherComponent, 'eventType', myFunc); + * ``` * * @param {String=|Component} first The event type or other component * @param {Function=|String} second The listener function or event type * @param {Function=} third The listener for other component * @return {Component} + * @method off */ off(first, second, third) { if (!first || typeof first === 'string' || Array.isArray(first)) { @@ -660,19 +682,21 @@ class Component { /** * Add an event listener to be triggered only once and then removed - * + * ```js * myComponent.one('eventName', myFunc); - * + * ``` * Alternatively you can add a listener to another element or component * that will be triggered only once. - * + * ```js * myComponent.one(otherElement, 'eventName', myFunc); * myComponent.one(otherComponent, 'eventName', myFunc); + * ``` * * @param {String|Component} first The event type or other component * @param {Function|String} second The listener function or event type * @param {Function=} third The listener function for other component * @return {Component} + * @method one */ one(first, second, third) { if (typeof first === 'string' || Array.isArray(first)) { @@ -698,15 +722,17 @@ class Component { /** * Trigger an event on an element - * + * ```js * myComponent.trigger('eventName'); * myComponent.trigger({'type':'eventName'}); * myComponent.trigger('eventName', {data: 'some data'}); * myComponent.trigger({'type':'eventName'}, {data: 'some data'}); + * ``` * * @param {Event|Object|String} event A string (the type) or an event object with a type attribute * @param {Object} [hash] data hash to pass along with the event * @return {Component} self + * @method trigger */ trigger(event, hash) { Events.trigger(this.el_, event, hash); @@ -714,13 +740,13 @@ class Component { } /** - * Bind a listener to the component's ready state - * + * Bind a listener to the component's ready state. * Different from event listeners in that if the ready event has already happened * it will trigger the function immediately. * * @param {Function} fn Ready listener * @return {Component} + * @method ready */ ready(fn) { if (fn) { @@ -739,6 +765,7 @@ class Component { * Trigger the ready listeners * * @return {Component} + * @method triggerReady */ triggerReady() { this.isReady_ = true; @@ -766,6 +793,7 @@ class Component { * * @param {String} classToCheck Classname to check * @return {Component} + * @method hasClass */ hasClass(classToCheck) { return Dom.hasElClass(this.el_, classToCheck); @@ -776,6 +804,7 @@ class Component { * * @param {String} classToAdd Classname to add * @return {Component} + * @method addClass */ addClass(classToAdd) { Dom.addElClass(this.el_, classToAdd); @@ -783,10 +812,11 @@ class Component { } /** - * Remove a CSS class name from the component's element + * Remove and return a CSS class name from the component's element * * @param {String} classToRemove Classname to remove * @return {Component} + * @method removeClass */ removeClass(classToRemove) { Dom.removeElClass(this.el_, classToRemove); @@ -797,6 +827,7 @@ class Component { * Show the component element if hidden * * @return {Component} + * @method show */ show() { this.removeClass('vjs-hidden'); @@ -807,6 +838,7 @@ class Component { * Hide the component element if currently showing * * @return {Component} + * @method hide */ hide() { this.addClass('vjs-hidden'); @@ -819,6 +851,7 @@ class Component { * * @return {Component} * @private + * @method lockShowing */ lockShowing() { this.addClass('vjs-lock-showing'); @@ -831,6 +864,7 @@ class Component { * * @return {Component} * @private + * @method unlockShowing */ unlockShowing() { this.removeClass('vjs-lock-showing'); @@ -839,7 +873,6 @@ class Component { /** * Set or get the width of the component (CSS values) - * * Setting the video tag dimension values only works with values in pixels. * Percent values will not work. * Some percents can be used, but width()/height() will return the number + %, @@ -849,6 +882,7 @@ class Component { * @param {Boolean} skipListeners Skip the 'resize' event trigger * @return {Component} This component, when setting the width * @return {Number|String} The width, when getting + * @method width */ width(num, skipListeners) { return this.dimension('width', num, skipListeners); @@ -856,7 +890,6 @@ class Component { /** * Get or set the height of the component (CSS values) - * * Setting the video tag dimension values only works with values in pixels. * Percent values will not work. * Some percents can be used, but width()/height() will return the number + %, @@ -866,6 +899,7 @@ class Component { * @param {Boolean=} skipListeners Skip the resize event trigger * @return {Component} This component, when setting the height * @return {Number|String} The height, when getting + * @method height */ height(num, skipListeners) { return this.dimension('height', num, skipListeners); @@ -874,9 +908,10 @@ class Component { /** * Set both width and height at the same time * - * @param {Number|String} width - * @param {Number|String} height + * @param {Number|String} width Width of player + * @param {Number|String} height Height of player * @return {Component} The component + * @method dimensions */ dimensions(width, height) { // Skip resize listeners on width for optimization @@ -885,10 +920,8 @@ class Component { /** * Get or set width or height - * * This is the shared code for the width() and height() methods. * All for an integer, integer + 'px' or integer + '%'; - * * Known issue: Hidden elements officially have a width of 0. We're defaulting * to the style.width value and falling back to computedStyle which has the * hidden element issue. Info, but probably not an efficient fix: @@ -900,6 +933,7 @@ class Component { * @return {Component} The component if a dimension was set * @return {Number|String} The dimension if nothing was set * @private + * @method dimension */ dimension(widthOrHeight, num, skipListeners) { if (num !== undefined) { @@ -949,13 +983,13 @@ class Component { /** * Emit 'tap' events when touch events are supported - * * This is used to support toggling the controls through a tap on the video. - * * We're requiring them to be enabled because otherwise every component would * have this extra overhead unnecessarily, on mobile devices where extra * overhead is especially bad. + * * @private + * @method emitTapEvents */ emitTapEvents() { // Track the start time so we can determine how long the touch lasted @@ -992,7 +1026,7 @@ class Component { // So, if we moved only a small distance, this could still be a tap const xdiff = event.touches[0].pageX - firstTouch.pageX; const ydiff = event.touches[0].pageY - firstTouch.pageY; - const touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff); + const touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff); if (touchDistance > tapMovementThreshold) { couldBeTap = false; @@ -1032,12 +1066,10 @@ class Component { /** * Report user touch activity when touch events occur - * * User activity is used to determine when controls should show/hide. It's * relatively simple when it comes to mouse events, because any mouse event * should show the controls. So we capture mouse events that bubble up to the * player and report activity when that happens. - * * With touch events it isn't as easy. We can't rely on touch events at the * player level, because a tap (touchstart + touchend) on the video itself on * mobile devices is meant to turn controls off (and on). User activity is @@ -1045,13 +1077,13 @@ class Component { * turns the controls off, then the touchend event bubbles up to the player, * which if it reported user activity, would turn the controls right back on. * (We also don't want to completely block touch events from bubbling up) - * * Also a touchmove, touch+hold, and anything other than a tap is not supposed * to turn the controls back on on a mobile device. - * * Here we're setting the default component behavior to report user activity * whenever touch events happen, and this can be turned off by components that * want touch events to act differently. + * + * @method enableTouchActivity */ enableTouchActivity() { // Don't continue if the root player doesn't support reporting user activity @@ -1087,9 +1119,11 @@ class Component { /** * Creates timeout and sets up disposal automatically. + * * @param {Function} fn The function to run after the timeout. * @param {Number} timeout Number of ms to delay before executing specified function. * @return {Number} Returns the timeout ID + * @method setTimeout */ setTimeout(fn, timeout) { fn = Fn.bind(this, fn); @@ -1110,8 +1144,10 @@ class Component { /** * Clears a timeout and removes the associated dispose listener + * * @param {Number} timeoutId The id of the timeout to clear * @return {Number} Returns the timeout ID + * @method clearTimeout */ clearTimeout(timeoutId) { window.clearTimeout(timeoutId); @@ -1127,9 +1163,11 @@ class Component { /** * Creates an interval and sets up disposal automatically. + * * @param {Function} fn The function to run every N seconds. * @param {Number} interval Number of ms to delay before executing specified function. * @return {Number} Returns the interval ID + * @method setInterval */ setInterval(fn, interval) { fn = Fn.bind(this, fn); @@ -1149,8 +1187,10 @@ class Component { /** * Clears an interval and removes the associated dispose listener + * * @param {Number} intervalId The id of the interval to clear * @return {Number} Returns the interval ID + * @method clearInterval */ clearInterval(intervalId) { window.clearInterval(intervalId); @@ -1164,6 +1204,14 @@ class Component { return intervalId; } + /** + * Registers a component + * + * @param {String} name Name of the component to register + * @param {Object} comp The component to register + * @static + * @method registerComponent + */ static registerComponent(name, comp) { if (!Component.components_) { Component.components_ = {}; @@ -1173,6 +1221,14 @@ class Component { return comp; } + /** + * Gets a component by name + * + * @param {String} name Name of the component to get + * @return {Component} + * @static + * @method getComponent + */ static getComponent(name) { if (Component.components_ && Component.components_[name]) { return Component.components_[name]; @@ -1184,6 +1240,14 @@ class Component { } } + /** + * Sets up the constructor using the supplied init method + * or uses the init of the parent object + * + * @param {Object} props An object of properties + * @static + * @method extend + */ static extend(props) { props = props || {}; // Set up the constructor using the supplied init method diff --git a/src/js/control-bar/control-bar.js b/src/js/control-bar/control-bar.js index e1339aed93..fa8298d02b 100644 --- a/src/js/control-bar/control-bar.js +++ b/src/js/control-bar/control-bar.js @@ -1,3 +1,6 @@ +/** + * @file control-bar.js + */ import Component from '../component.js'; // Required children @@ -20,13 +23,18 @@ import CustomControlSpacer from './spacer-controls/custom-control-spacer.js'; /** * Container of main controls - * @param {Player|Object} player - * @param {Object=} options - * @class - * @constructor + * * @extends Component + * @class ControlBar */ class ControlBar extends Component { + + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { return super.createEl('div', { className: 'vjs-control-bar' diff --git a/src/js/control-bar/fullscreen-toggle.js b/src/js/control-bar/fullscreen-toggle.js index da287b1e69..81ac4f9e64 100644 --- a/src/js/control-bar/fullscreen-toggle.js +++ b/src/js/control-bar/fullscreen-toggle.js @@ -1,19 +1,32 @@ +/** + * @file fullscreen-toggle.js + */ import Button from '../button.js'; import Component from '../component.js'; /** * Toggle fullscreen video - * @param {Player|Object} player - * @param {Object=} options - * @class - * @extends vjs.Button + * + * @extends Button + * @class FullscreenToggle */ class FullscreenToggle extends Button { + /** + * Allow sub components to stack CSS class names + * + * @return {String} The constructed class name + * @method buildCSSClass + */ buildCSSClass() { return `vjs-fullscreen-control ${super.buildCSSClass()}`; } + /** + * Handles click for full screen + * + * @method handleClick + */ handleClick() { if (!this.player_.isFullscreen()) { this.player_.requestFullscreen(); diff --git a/src/js/control-bar/live-display.js b/src/js/control-bar/live-display.js index fb9cd58041..c79609b7fb 100644 --- a/src/js/control-bar/live-display.js +++ b/src/js/control-bar/live-display.js @@ -1,15 +1,24 @@ +/** + * @file live-display.js + */ import Component from '../component'; import * as Dom from '../utils/dom.js'; /** * Displays the live indicator * TODO - Future make it click to snap to live - * @param {Player|Object} player - * @param {Object=} options - * @constructor + * + * @extends Component + * @class LiveDisplay */ class LiveDisplay extends Component { + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { var el = super.createEl('div', { className: 'vjs-live-control vjs-control' diff --git a/src/js/control-bar/mute-toggle.js b/src/js/control-bar/mute-toggle.js index 10b489ec12..79b3bec223 100644 --- a/src/js/control-bar/mute-toggle.js +++ b/src/js/control-bar/mute-toggle.js @@ -1,13 +1,17 @@ +/** + * @file mute-toggle.js + */ import Button from '../button'; import Component from '../component'; import * as Dom from '../utils/dom.js'; /** - * A button component for muting the audio + * A button component for muting the audio * * @param {Player|Object} player * @param {Object=} options - * @constructor + * @extends Button + * @class MuteToggle */ class MuteToggle extends Button { @@ -30,14 +34,30 @@ class MuteToggle extends Button { }); } + /** + * Allow sub components to stack CSS class names + * + * @return {String} The constructed class name + * @method buildCSSClass + */ buildCSSClass() { return `vjs-mute-control ${super.buildCSSClass()}`; } + /** + * Handle click on mute + * + * @method handleClick + */ handleClick() { this.player_.muted( this.player_.muted() ? false : true ); } + /** + * Update volume + * + * @method update + */ update() { var vol = this.player_.volume(), level = 3; diff --git a/src/js/control-bar/play-toggle.js b/src/js/control-bar/play-toggle.js index ccc8480c11..5849d7808a 100644 --- a/src/js/control-bar/play-toggle.js +++ b/src/js/control-bar/play-toggle.js @@ -1,12 +1,16 @@ +/** + * @file play-toggle.js + */ import Button from '../button.js'; import Component from '../component.js'; /** * Button to toggle between play and pause + * * @param {Player|Object} player * @param {Object=} options - * @class - * @constructor + * @extends Button + * @class PlayToggle */ class PlayToggle extends Button { @@ -17,11 +21,21 @@ class PlayToggle extends Button { this.on(player, 'pause', this.handlePause); } + /** + * Allow sub components to stack CSS class names + * + * @return {String} The constructed class name + * @method buildCSSClass + */ buildCSSClass() { return `vjs-play-control ${super.buildCSSClass()}`; } - // handleClick - Toggle between play and pause + /** + * Handle click to toggle between play and pause + * + * @method handleClick + */ handleClick() { if (this.player_.paused()) { this.player_.play(); @@ -30,14 +44,22 @@ class PlayToggle extends Button { } } - // handlePlay - Add the vjs-playing class to the element so it can change appearance + /** + * Add the vjs-playing class to the element so it can change appearance + * + * @method handlePlay + */ handlePlay() { this.removeClass('vjs-paused'); this.addClass('vjs-playing'); this.controlText('Pause'); // change the button text to "Pause" } - // handlePause - Add the vjs-paused class to the element so it can change appearance + /** + * Add the vjs-paused class to the element so it can change appearance + * + * @method handlePause + */ handlePause() { this.removeClass('vjs-playing'); this.addClass('vjs-paused'); diff --git a/src/js/control-bar/playback-rate-menu/playback-rate-menu-button.js b/src/js/control-bar/playback-rate-menu/playback-rate-menu-button.js index 76a0fde6d3..c561b15cc2 100644 --- a/src/js/control-bar/playback-rate-menu/playback-rate-menu-button.js +++ b/src/js/control-bar/playback-rate-menu/playback-rate-menu-button.js @@ -1,3 +1,6 @@ +/** + * @file playback-rate-menu-button.js + */ import MenuButton from '../../menu/menu-button.js'; import Menu from '../../menu/menu.js'; import PlaybackRateMenuItem from './playback-rate-menu-item.js'; @@ -9,7 +12,8 @@ import * as Dom from '../../utils/dom.js'; * * @param {Player|Object} player * @param {Object=} options - * @constructor + * @extends MenuButton + * @class PlaybackRateMenuButton */ class PlaybackRateMenuButton extends MenuButton { @@ -23,6 +27,12 @@ class PlaybackRateMenuButton extends MenuButton { this.on(player, 'ratechange', this.updateLabel); } + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { let el = super.createEl(); @@ -36,11 +46,22 @@ class PlaybackRateMenuButton extends MenuButton { return el; } + /** + * Allow sub components to stack CSS class names + * + * @return {String} The constructed class name + * @method buildCSSClass + */ buildCSSClass() { return `vjs-playback-rate ${super.buildCSSClass()}`; } - // Menu creation + /** + * Create the playback rate menu + * + * @return {Menu} Menu object populated with items + * @method createMenu + */ createMenu() { let menu = new Menu(this.player()); let rates = this.playbackRates(); @@ -56,11 +77,21 @@ class PlaybackRateMenuButton extends MenuButton { return menu; } + /** + * Updates ARIA accessibility attributes + * + * @method updateARIAAttributes + */ updateARIAAttributes() { // Current playback rate this.el().setAttribute('aria-valuenow', this.player().playbackRate()); } + /** + * Handle menu item click + * + * @method handleClick + */ handleClick() { // select next rate option let currentRate = this.player().playbackRate(); @@ -77,10 +108,22 @@ class PlaybackRateMenuButton extends MenuButton { this.player().playbackRate(newRate); } + /** + * Get possible playback rates + * + * @return {Array} Possible playback rates + * @method playbackRates + */ playbackRates() { return this.options_['playbackRates'] || (this.options_.playerOptions && this.options_.playerOptions['playbackRates']); } + /** + * Get supported playback rates + * + * @return {Array} Supported playback rates + * @method playbackRateSupported + */ playbackRateSupported() { return this.player().tech && this.player().tech['featuresPlaybackRate'] @@ -91,6 +134,8 @@ class PlaybackRateMenuButton extends MenuButton { /** * Hide playback rate controls when they're no playback rate options to select + * + * @method updateVisibility */ updateVisibility() { if (this.playbackRateSupported()) { @@ -102,6 +147,8 @@ class PlaybackRateMenuButton extends MenuButton { /** * Update button label when rate changed + * + * @method updateLabel */ updateLabel() { if (this.playbackRateSupported()) { diff --git a/src/js/control-bar/playback-rate-menu/playback-rate-menu-item.js b/src/js/control-bar/playback-rate-menu/playback-rate-menu-item.js index 965b5a611d..614d8c1cdb 100644 --- a/src/js/control-bar/playback-rate-menu/playback-rate-menu-item.js +++ b/src/js/control-bar/playback-rate-menu/playback-rate-menu-item.js @@ -1,10 +1,16 @@ +/** + * @file playback-rate-menu-item.js + */ import MenuItem from '../../menu/menu-item.js'; import Component from '../../component.js'; /** * The specific menu item type for selecting a playback rate * - * @constructor + * @param {Player|Object} player + * @param {Object=} options + * @extends MenuItem + * @class PlaybackRateMenuItem */ class PlaybackRateMenuItem extends MenuItem { @@ -23,11 +29,21 @@ class PlaybackRateMenuItem extends MenuItem { this.on(player, 'ratechange', this.update); } + /** + * Handle click on menu item + * + * @method handleClick + */ handleClick() { super.handleClick(); this.player().playbackRate(this.rate); } + /** + * Update playback rate with selected rate + * + * @method update + */ update() { this.selected(this.player().playbackRate() === this.rate); } diff --git a/src/js/control-bar/progress-control/load-progress-bar.js b/src/js/control-bar/progress-control/load-progress-bar.js index 3ef1a1878a..ec20e8afff 100644 --- a/src/js/control-bar/progress-control/load-progress-bar.js +++ b/src/js/control-bar/progress-control/load-progress-bar.js @@ -1,3 +1,6 @@ +/** + * @file load-progress-bar.js + */ import Component from '../../component.js'; import * as Dom from '../../utils/dom.js'; @@ -6,7 +9,8 @@ import * as Dom from '../../utils/dom.js'; * * @param {Player|Object} player * @param {Object=} options - * @constructor + * @extends Component + * @class LoadProgressBar */ class LoadProgressBar extends Component { @@ -15,6 +19,12 @@ class LoadProgressBar extends Component { this.on(player, 'progress', this.update); } + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { return super.createEl('div', { className: 'vjs-load-progress', @@ -22,6 +32,11 @@ class LoadProgressBar extends Component { }); } + /** + * Update progress bar + * + * @method update + */ update() { let buffered = this.player_.buffered(); let duration = this.player_.duration(); diff --git a/src/js/control-bar/progress-control/play-progress-bar.js b/src/js/control-bar/progress-control/play-progress-bar.js index aaf656befd..7ac3aacecc 100644 --- a/src/js/control-bar/progress-control/play-progress-bar.js +++ b/src/js/control-bar/progress-control/play-progress-bar.js @@ -1,3 +1,6 @@ +/** + * @file play-progress-bar.js + */ import Component from '../../component.js'; /** @@ -5,10 +8,17 @@ import Component from '../../component.js'; * * @param {Player|Object} player * @param {Object=} options - * @constructor + * @extends Component + * @class PlayProgressBar */ class PlayProgressBar extends Component { + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { return super.createEl('div', { className: 'vjs-play-progress', diff --git a/src/js/control-bar/progress-control/progress-control.js b/src/js/control-bar/progress-control/progress-control.js index 1834d60bca..6eddb8ec13 100644 --- a/src/js/control-bar/progress-control/progress-control.js +++ b/src/js/control-bar/progress-control/progress-control.js @@ -1,3 +1,6 @@ +/** + * @file progress-control.js + */ import Component from '../../component.js'; import SeekBar from './seek-bar.js'; @@ -7,9 +10,17 @@ import SeekBar from './seek-bar.js'; * * @param {Player|Object} player * @param {Object=} options - * @constructor + * @extends Component + * @class ProgressControl */ class ProgressControl extends Component { + + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { return super.createEl('div', { className: 'vjs-progress-control vjs-control' diff --git a/src/js/control-bar/progress-control/seek-bar.js b/src/js/control-bar/progress-control/seek-bar.js index 068511a5d9..aa7e92b9a1 100644 --- a/src/js/control-bar/progress-control/seek-bar.js +++ b/src/js/control-bar/progress-control/seek-bar.js @@ -1,3 +1,6 @@ +/** + * @file seek-bar.js + */ import Slider from '../../slider/slider.js'; import Component from '../../component.js'; import LoadProgressBar from './load-progress-bar.js'; @@ -11,7 +14,8 @@ import roundFloat from '../../utils/round-float.js'; * * @param {Player|Object} player * @param {Object=} options - * @constructor + * @extends Slider + * @class SeekBar */ class SeekBar extends Slider { @@ -21,6 +25,12 @@ class SeekBar extends Slider { player.ready(Fn.bind(this, this.updateARIAAttributes)); } + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { return super.createEl('div', { className: 'vjs-progress-holder', @@ -28,6 +38,11 @@ class SeekBar extends Slider { }); } + /** + * Update ARIA accessibility attributes + * + * @method updateARIAAttributes + */ updateARIAAttributes() { // Allows for smooth scrubbing, when player can't keep up. let time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime(); @@ -35,11 +50,22 @@ class SeekBar extends Slider { this.el_.setAttribute('aria-valuetext', formatTime(time, this.player_.duration())); // human readable value of progress bar (time complete) } + /** + * Get percentage of video played + * + * @return {Number} Percentage played + * @method getPercent + */ getPercent() { let percent = this.player_.currentTime() / this.player_.duration(); return percent >= 1 ? 1 : percent; } + /** + * Handle mouse down on seek bar + * + * @method handleMouseDown + */ handleMouseDown(event) { super.handleMouseDown(event); @@ -49,6 +75,11 @@ class SeekBar extends Slider { this.player_.pause(); } + /** + * Handle mouse move on seek bar + * + * @method handleMouseMove + */ handleMouseMove(event) { let newTime = this.calculateDistance(event) * this.player_.duration(); @@ -59,6 +90,11 @@ class SeekBar extends Slider { this.player_.currentTime(newTime); } + /** + * Handle mouse up on seek bar + * + * @method handleMouseUp + */ handleMouseUp(event) { super.handleMouseUp(event); @@ -68,10 +104,20 @@ class SeekBar extends Slider { } } + /** + * Move more quickly fast forward for keyboard-only users + * + * @method stepForward + */ stepForward() { this.player_.currentTime(this.player_.currentTime() + 5); // more quickly fast forward for keyboard-only users } + /** + * Move more quickly rewind for keyboard-only users + * + * @method stepBack + */ stepBack() { this.player_.currentTime(this.player_.currentTime() - 5); // more quickly rewind for keyboard-only users } diff --git a/src/js/control-bar/spacer-controls/custom-control-spacer.js b/src/js/control-bar/spacer-controls/custom-control-spacer.js index 450f0fdc43..a258fab2b6 100644 --- a/src/js/control-bar/spacer-controls/custom-control-spacer.js +++ b/src/js/control-bar/spacer-controls/custom-control-spacer.js @@ -1,17 +1,33 @@ +/** + * @file custom-control-spacer.js + */ import Spacer from './spacer.js'; import Component from '../../component.js'; /** * Spacer specifically meant to be used as an insertion point for new plugins, etc. * - * @param {Player|Object} player - * @param {Obect=} options + * @extends Spacer + * @class CustomControlSpacer */ class CustomControlSpacer extends Spacer { + + /** + * Allow sub components to stack CSS class names + * + * @return {String} The constructed class name + * @method buildCSSClass + */ buildCSSClass() { return `vjs-custom-control-spacer ${super.buildCSSClass()}`; } + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { return super.createEl({ className: this.buildCSSClass() diff --git a/src/js/control-bar/spacer-controls/spacer.js b/src/js/control-bar/spacer-controls/spacer.js index 86bcc3acc0..012c8758d1 100644 --- a/src/js/control-bar/spacer-controls/spacer.js +++ b/src/js/control-bar/spacer-controls/spacer.js @@ -1,17 +1,34 @@ +/** + * @file spacer.js + */ import Component from '../../component.js'; /** * Just an empty spacer element that can be used as an append point for plugins, etc. * Also can be used to create space between elements when necessary. * - * @param {Player|Object} player - * @param {Object=} options + * @extends Component + * @class Spacer */ class Spacer extends Component { + + /** + * Allow sub components to stack CSS class names + * + * @return {String} The constructed class name + * @method buildCSSClass + */ buildCSSClass() { return `vjs-spacer ${super.buildCSSClass()}`; } + /** + * Create the component's DOM element + * + * @param {Object} props An object of properties + * @return {Element} + * @method createEl + */ createEl(props) { return super.createEl('div', { className: this.buildCSSClass() diff --git a/src/js/control-bar/text-track-controls/caption-settings-menu-item.js b/src/js/control-bar/text-track-controls/caption-settings-menu-item.js index 33f6f4c17a..5a48e42c98 100644 --- a/src/js/control-bar/text-track-controls/caption-settings-menu-item.js +++ b/src/js/control-bar/text-track-controls/caption-settings-menu-item.js @@ -1,7 +1,18 @@ +/** + * @file caption-settings-menu-item.js + */ import TextTrackMenuItem from './text-track-menu-item.js'; import Component from '../../component.js'; -class CaptionSettingsMenuItem extends TextTrackMenuItem { +/** + * The menu item for caption track settings menu + * + * @param {Player|Object} player + * @param {Object=} options + * @extends TextTrackMenuItem + * @class CaptionSettingsMenuItem + * / + class CaptionSettingsMenuItem extends TextTrackMenuItem { constructor(player, options) { options['track'] = { @@ -16,6 +27,11 @@ class CaptionSettingsMenuItem extends TextTrackMenuItem { this.addClass('vjs-texttrack-settings'); } + /** + * Handle click on menu item + * + * @method handleClick + */ handleClick() { this.player().getChild('textTrackSettings').show(); } diff --git a/src/js/control-bar/text-track-controls/captions-button.js b/src/js/control-bar/text-track-controls/captions-button.js index c016117b9e..1bf73a5ef1 100644 --- a/src/js/control-bar/text-track-controls/captions-button.js +++ b/src/js/control-bar/text-track-controls/captions-button.js @@ -1,3 +1,6 @@ +/** + * @file captions-button.js + */ import TextTrackButton from './text-track-button.js'; import Component from '../../component.js'; import CaptionSettingsMenuItem from './caption-settings-menu-item.js'; @@ -5,7 +8,11 @@ import CaptionSettingsMenuItem from './caption-settings-menu-item.js'; /** * The button component for toggling and selecting captions * - * @constructor + * @param {Object} player Player object + * @param {Object=} options Object of option names and values + * @param {Function=} ready Ready callback function + * @extends TextTrackButton + * @class CaptionsButton */ class CaptionsButton extends TextTrackButton { @@ -14,10 +21,21 @@ class CaptionsButton extends TextTrackButton { this.el_.setAttribute('aria-label','Captions Menu'); } + /** + * Allow sub components to stack CSS class names + * + * @return {String} The constructed class name + * @method buildCSSClass + */ buildCSSClass() { return `vjs-captions-button ${super.buildCSSClass()}`; } + /** + * Update caption menu items + * + * @method update + */ update() { let threshold = 2; super.update(); @@ -34,6 +52,12 @@ class CaptionsButton extends TextTrackButton { } } + /** + * Create caption menu items + * + * @return {Array} Array of menu items + * @method createItems + */ createItems() { let items = []; diff --git a/src/js/control-bar/text-track-controls/chapters-button.js b/src/js/control-bar/text-track-controls/chapters-button.js index cf9ac2fae0..46fe2011a5 100644 --- a/src/js/control-bar/text-track-controls/chapters-button.js +++ b/src/js/control-bar/text-track-controls/chapters-button.js @@ -1,3 +1,6 @@ +/** + * @file chapters-button.js + */ import TextTrackButton from './text-track-button.js'; import Component from '../../component.js'; import TextTrackMenuItem from './text-track-menu-item.js'; @@ -8,12 +11,16 @@ import * as Fn from '../../utils/fn.js'; import toTitleCase from '../../utils/to-title-case.js'; import window from 'global/window'; -// Chapters act much differently than other text tracks -// Cues are navigation vs. other tracks of alternative languages /** * The button component for toggling and selecting chapters + * Chapters act much differently than other text tracks + * Cues are navigation vs. other tracks of alternative languages * - * @constructor + * @param {Object} player Player object + * @param {Object=} options Object of option names and values + * @param {Function=} ready Ready callback function + * @extends TextTrackButton + * @class ChaptersButton */ class ChaptersButton extends TextTrackButton { @@ -22,11 +29,22 @@ class ChaptersButton extends TextTrackButton { this.el_.setAttribute('aria-label','Chapters Menu'); } + /** + * Allow sub components to stack CSS class names + * + * @return {String} The constructed class name + * @method buildCSSClass + */ buildCSSClass() { return `vjs-chapters-button ${super.buildCSSClass()}`; } - // Create a menu item for each text track + /** + * Create a menu item for each text track + * + * @return {Array} Array of menu items + * @method createItems + */ createItems() { let items = []; @@ -48,6 +66,12 @@ class ChaptersButton extends TextTrackButton { return items; } + /** + * Create menu from chapter buttons + * + * @return {Menu} Menu of chapter buttons + * @method createMenu + */ createMenu() { let tracks = this.player_.textTracks() || []; let chaptersTrack; diff --git a/src/js/control-bar/text-track-controls/chapters-track-menu-item.js b/src/js/control-bar/text-track-controls/chapters-track-menu-item.js index 0ac3d4d41a..40b717a0e4 100644 --- a/src/js/control-bar/text-track-controls/chapters-track-menu-item.js +++ b/src/js/control-bar/text-track-controls/chapters-track-menu-item.js @@ -1,9 +1,17 @@ +/** + * @file chapters-track-menu-item.js + */ import MenuItem from '../../menu/menu-item.js'; import Component from '../../component.js'; import * as Fn from '../../utils/fn.js'; /** - * @constructor + * The chapter track menu item + * + * @param {Player|Object} player + * @param {Object=} options + * @extends MenuItem + * @class ChaptersTrackMenuItem */ class ChaptersTrackMenuItem extends MenuItem { @@ -22,12 +30,22 @@ class ChaptersTrackMenuItem extends MenuItem { track.addEventListener('cuechange', Fn.bind(this, this.update)); } + /** + * Handle click on menu item + * + * @method handleClick + */ handleClick() { super.handleClick(); this.player_.currentTime(this.cue.startTime); this.update(this.cue.startTime); } + /** + * Update chapter menu item + * + * @method update + */ update() { let cue = this.cue; let currentTime = this.player_.currentTime(); diff --git a/src/js/control-bar/text-track-controls/off-text-track-menu-item.js b/src/js/control-bar/text-track-controls/off-text-track-menu-item.js index 21268f5abe..8238c42ab9 100644 --- a/src/js/control-bar/text-track-controls/off-text-track-menu-item.js +++ b/src/js/control-bar/text-track-controls/off-text-track-menu-item.js @@ -1,10 +1,16 @@ +/** + * @file off-text-track-menu-item.js + */ import TextTrackMenuItem from './text-track-menu-item.js'; import Component from '../../component.js'; /** * A special menu item for turning of a specific type of text track * - * @constructor + * @param {Player|Object} player + * @param {Object=} options + * @extends TextTrackMenuItem + * @class OffTextTrackMenuItem */ class OffTextTrackMenuItem extends TextTrackMenuItem { @@ -23,6 +29,12 @@ class OffTextTrackMenuItem extends TextTrackMenuItem { this.selected(true); } + /** + * Handle text track change + * + * @param {Object} event Event object + * @method handleTracksChange + */ handleTracksChange(event){ let tracks = this.player().textTracks(); let selected = true; diff --git a/src/js/control-bar/text-track-controls/subtitles-button.js b/src/js/control-bar/text-track-controls/subtitles-button.js index 285360cd1c..c56731496e 100644 --- a/src/js/control-bar/text-track-controls/subtitles-button.js +++ b/src/js/control-bar/text-track-controls/subtitles-button.js @@ -1,10 +1,17 @@ +/** + * @file subtitles-button.js + */ import TextTrackButton from './text-track-button.js'; import Component from '../../component.js'; /** * The button component for toggling and selecting subtitles * - * @constructor + * @param {Object} player Player object + * @param {Object=} options Object of option names and values + * @param {Function=} ready Ready callback function + * @extends TextTrackButton + * @class SubtitlesButton */ class SubtitlesButton extends TextTrackButton { @@ -13,6 +20,12 @@ class SubtitlesButton extends TextTrackButton { this.el_.setAttribute('aria-label','Subtitles Menu'); } + /** + * Allow sub components to stack CSS class names + * + * @return {String} The constructed class name + * @method buildCSSClass + */ buildCSSClass() { return `vjs-subtitles-button ${super.buildCSSClass()}`; } diff --git a/src/js/control-bar/text-track-controls/text-track-button.js b/src/js/control-bar/text-track-controls/text-track-button.js index 7f42520993..07dd39bcdd 100644 --- a/src/js/control-bar/text-track-controls/text-track-button.js +++ b/src/js/control-bar/text-track-controls/text-track-button.js @@ -1,3 +1,6 @@ +/** + * @file text-track-button.js + */ import MenuButton from '../../menu/menu-button.js'; import Component from '../../component.js'; import * as Fn from '../../utils/fn.js'; @@ -7,7 +10,10 @@ import OffTextTrackMenuItem from './off-text-track-menu-item.js'; /** * The base class for buttons that toggle specific text track types (e.g. subtitles) * - * @constructor + * @param {Player|Object} player + * @param {Object=} options + * @extends MenuButton + * @class TextTrackButton */ class TextTrackButton extends MenuButton { diff --git a/src/js/control-bar/text-track-controls/text-track-menu-item.js b/src/js/control-bar/text-track-controls/text-track-menu-item.js index b16b47a8c0..2fb10ba61f 100644 --- a/src/js/control-bar/text-track-controls/text-track-menu-item.js +++ b/src/js/control-bar/text-track-controls/text-track-menu-item.js @@ -1,3 +1,6 @@ +/** + * @file text-track-menu-item.js + */ import MenuItem from '../../menu/menu-item.js'; import Component from '../../component.js'; import * as Fn from '../../utils/fn.js'; @@ -7,7 +10,10 @@ import document from 'global/document'; /** * The specific menu item type for selecting a language within a text track kind * - * @constructor + * @param {Player|Object} player + * @param {Object=} options + * @extends MenuItem + * @class TextTrackMenuItem */ class TextTrackMenuItem extends MenuItem { @@ -58,6 +64,11 @@ class TextTrackMenuItem extends MenuItem { } } + /** + * Handle click on text track + * + * @method handleClick + */ handleClick(event) { let kind = this.track['kind']; let tracks = this.player_.textTracks(); @@ -81,6 +92,11 @@ class TextTrackMenuItem extends MenuItem { } } + /** + * Handle text track change + * + * @method handleTracksChange + */ handleTracksChange(event){ this.selected(this.track['mode'] === 'showing'); } diff --git a/src/js/control-bar/time-controls/current-time-display.js b/src/js/control-bar/time-controls/current-time-display.js index dc5317f409..823b87a4df 100644 --- a/src/js/control-bar/time-controls/current-time-display.js +++ b/src/js/control-bar/time-controls/current-time-display.js @@ -1,12 +1,17 @@ +/** + * @file current-time-display.js + */ import Component from '../../component.js'; import * as Dom from '../../utils/dom.js'; import formatTime from '../../utils/format-time.js'; /** * Displays the current time + * * @param {Player|Object} player * @param {Object=} options - * @constructor + * @extends Component + * @class CurrentTimeDisplay */ class CurrentTimeDisplay extends Component { @@ -16,6 +21,12 @@ class CurrentTimeDisplay extends Component { this.on(player, 'timeupdate', this.updateContent); } + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { let el = super.createEl('div', { className: 'vjs-current-time vjs-time-control vjs-control' @@ -31,6 +42,11 @@ class CurrentTimeDisplay extends Component { return el; } + /** + * Update current time display + * + * @method updateContent + */ updateContent() { // Allows for smooth scrubbing, when player can't keep up. let time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime(); diff --git a/src/js/control-bar/time-controls/duration-display.js b/src/js/control-bar/time-controls/duration-display.js index 708bb6df19..f30364b4c6 100644 --- a/src/js/control-bar/time-controls/duration-display.js +++ b/src/js/control-bar/time-controls/duration-display.js @@ -1,12 +1,17 @@ +/** + * @file duration-display.js + */ import Component from '../../component.js'; import * as Dom from '../../utils/dom.js'; import formatTime from '../../utils/format-time.js'; /** * Displays the duration + * * @param {Player|Object} player * @param {Object=} options - * @constructor + * @extends Component + * @class DurationDisplay */ class DurationDisplay extends Component { @@ -22,6 +27,12 @@ class DurationDisplay extends Component { this.on(player, 'loadedmetadata', this.updateContent); } + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { let el = super.createEl('div', { className: 'vjs-duration vjs-time-control vjs-control' @@ -37,6 +48,11 @@ class DurationDisplay extends Component { return el; } + /** + * Update duration time display + * + * @method updateContent + */ updateContent() { let duration = this.player_.duration(); if (duration) { diff --git a/src/js/control-bar/time-controls/remaining-time-display.js b/src/js/control-bar/time-controls/remaining-time-display.js index edb656405c..03c828d91a 100644 --- a/src/js/control-bar/time-controls/remaining-time-display.js +++ b/src/js/control-bar/time-controls/remaining-time-display.js @@ -1,12 +1,17 @@ +/** + * @file remaining-time-display.js + */ import Component from '../../component.js'; import * as Dom from '../../utils/dom.js'; import formatTime from '../../utils/format-time.js'; /** * Displays the time left in the video + * * @param {Player|Object} player * @param {Object=} options - * @constructor + * @extends Component + * @class RemainingTimeDisplay */ class RemainingTimeDisplay extends Component { @@ -16,6 +21,12 @@ class RemainingTimeDisplay extends Component { this.on(player, 'timeupdate', this.updateContent); } + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { let el = super.createEl('div', { className: 'vjs-remaining-time vjs-time-control vjs-control' @@ -31,6 +42,11 @@ class RemainingTimeDisplay extends Component { return el; } + /** + * Update remaining time display + * + * @method updateContent + */ updateContent() { if (this.player_.duration()) { const localizedText = this.localize('Remaining Time'); diff --git a/src/js/control-bar/time-controls/time-divider.js b/src/js/control-bar/time-controls/time-divider.js index 46d7ce142e..7ae6f416ef 100644 --- a/src/js/control-bar/time-controls/time-divider.js +++ b/src/js/control-bar/time-controls/time-divider.js @@ -1,16 +1,25 @@ +/** + * @file time-divider.js + */ import Component from '../../component.js'; /** - * The separator between the current time and duration - * + * The separator between the current time and duration. * Can be hidden if it's not needed in the design. * * @param {Player|Object} player * @param {Object=} options - * @constructor + * @extends Component + * @class TimeDivider */ class TimeDivider extends Component { + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { return super.createEl('div', { className: 'vjs-time-control vjs-time-divider', diff --git a/src/js/control-bar/volume-control/volume-bar.js b/src/js/control-bar/volume-control/volume-bar.js index 17e5548cab..6c08d1f1c5 100644 --- a/src/js/control-bar/volume-control/volume-bar.js +++ b/src/js/control-bar/volume-control/volume-bar.js @@ -1,3 +1,6 @@ +/** + * @file volume-bar.js + */ import Slider from '../../slider/slider.js'; import Component from '../../component.js'; import * as Fn from '../../utils/fn.js'; @@ -11,7 +14,8 @@ import VolumeLevel from './volume-level.js'; * * @param {Player|Object} player * @param {Object=} options - * @constructor + * @extends Slider + * @class VolumeBar */ class VolumeBar extends Slider { @@ -21,6 +25,12 @@ class VolumeBar extends Slider { player.ready(Fn.bind(this, this.updateARIAAttributes)); } + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { return super.createEl('div', { className: 'vjs-volume-bar', @@ -28,6 +38,11 @@ class VolumeBar extends Slider { }); } + /** + * Handle mouse move on volume bar + * + * @method handleMouseMove + */ handleMouseMove(event) { if (this.player_.muted()) { this.player_.muted(false); @@ -36,6 +51,12 @@ class VolumeBar extends Slider { this.player_.volume(this.calculateDistance(event)); } + /** + * Get percent of volume level + * + * @retun {Number} Volume level percent + * @method getPercent + */ getPercent() { if (this.player_.muted()) { return 0; @@ -44,14 +65,29 @@ class VolumeBar extends Slider { } } + /** + * Increase volume level for keyboard users + * + * @method stepForward + */ stepForward() { this.player_.volume(this.player_.volume() + 0.1); } + /** + * Decrease volume level for keyboard users + * + * @method stepBack + */ stepBack() { this.player_.volume(this.player_.volume() - 0.1); } + /** + * Update ARIA accessibility attributes + * + * @method updateARIAAttributes + */ updateARIAAttributes() { // Current value of volume bar as a percentage this.el_.setAttribute('aria-valuenow', roundFloat(this.player_.volume()*100, 2)); diff --git a/src/js/control-bar/volume-control/volume-control.js b/src/js/control-bar/volume-control/volume-control.js index bca50decc0..40c25f3072 100644 --- a/src/js/control-bar/volume-control/volume-control.js +++ b/src/js/control-bar/volume-control/volume-control.js @@ -1,3 +1,6 @@ +/** + * @file volume-control.js + */ import Component from '../../component.js'; // Required children @@ -8,7 +11,8 @@ import VolumeBar from './volume-bar.js'; * * @param {Player|Object} player * @param {Object=} options - * @constructor + * @extends Component + * @class VolumeControl */ class VolumeControl extends Component { @@ -28,6 +32,12 @@ class VolumeControl extends Component { }); } + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { return super.createEl('div', { className: 'vjs-volume-control vjs-control' diff --git a/src/js/control-bar/volume-control/volume-level.js b/src/js/control-bar/volume-control/volume-level.js index 8de8f92105..26a422694d 100644 --- a/src/js/control-bar/volume-control/volume-level.js +++ b/src/js/control-bar/volume-control/volume-level.js @@ -1,3 +1,6 @@ +/** + * @file volume-level.js + */ import Component from '../../component.js'; /** @@ -5,10 +8,17 @@ import Component from '../../component.js'; * * @param {Player|Object} player * @param {Object=} options - * @constructor + * @extends Component + * @class VolumeLevel */ class VolumeLevel extends Component { + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { return super.createEl('div', { className: 'vjs-volume-level', diff --git a/src/js/control-bar/volume-menu-button.js b/src/js/control-bar/volume-menu-button.js index a19c2cabf6..3fccafba66 100644 --- a/src/js/control-bar/volume-menu-button.js +++ b/src/js/control-bar/volume-menu-button.js @@ -1,3 +1,6 @@ +/** + * @file volume-menu-button.js + */ import Button from '../button.js'; import Component from '../component.js'; import Menu from '../menu/menu.js'; @@ -6,8 +9,12 @@ import MuteToggle from './mute-toggle.js'; import VolumeBar from './volume-control/volume-bar.js'; /** - * Menu button with a popup for showing the volume slider. - * @constructor + * Button for volume menu + * + * @param {Player|Object} player + * @param {Object=} options + * @extends MenuButton + * @class VolumeMenuButton */ class VolumeMenuButton extends MenuButton { @@ -31,10 +38,22 @@ class VolumeMenuButton extends MenuButton { this.addClass('vjs-menu-button'); } + /** + * Allow sub components to stack CSS class names + * + * @return {String} The constructed class name + * @method buildCSSClass + */ buildCSSClass() { return `vjs-volume-menu-button ${super.buildCSSClass()}`; } + /** + * Allow sub components to stack CSS class names + * + * @return {Menu} The volume menu button + * @method createMenu + */ createMenu() { let menu = new Menu(this.player_, { contentElType: 'div' @@ -56,6 +75,11 @@ class VolumeMenuButton extends MenuButton { return menu; } + /** + * Handle click on volume menu and calls super + * + * @method handleClick + */ handleClick() { MuteToggle.prototype.handleClick.call(this); super.handleClick(); diff --git a/src/js/error-display.js b/src/js/error-display.js index 177c0d6316..8fcf7206d4 100644 --- a/src/js/error-display.js +++ b/src/js/error-display.js @@ -1,11 +1,16 @@ +/** + * @file error-display.js + */ import Component from './component'; -import * as Dom from './utils/dom.js'; +import * as Dom from './utils/dom.js'; /** * Display that an error has occurred making the video unplayable - * @param {Player|Object} player - * @param {Object=} options - * @constructor + * + * @param {Object} player Main Player + * @param {Object=} options Object of option names and values + * @extends Component + * @class ErrorDisplay */ class ErrorDisplay extends Component { @@ -16,6 +21,12 @@ class ErrorDisplay extends Component { this.on(player, 'error', this.update); } + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { var el = super.createEl('div', { className: 'vjs-error-display' @@ -27,6 +38,11 @@ class ErrorDisplay extends Component { return el; } + /** + * Update the error message in localized language + * + * @method update + */ update() { if (this.player().error()) { this.contentEl_.innerHTML = this.localize(this.player().error().message); diff --git a/src/js/event-emitter.js b/src/js/event-emitter.js index 35c48c115e..f972995faf 100644 --- a/src/js/event-emitter.js +++ b/src/js/event-emitter.js @@ -1,3 +1,6 @@ +/** + * @file event-emitter.js + */ import * as Events from './utils/events.js'; var EventEmitter = function() {}; diff --git a/src/js/extends.js b/src/js/extends.js index be68a5a402..1046b5d98d 100644 --- a/src/js/extends.js +++ b/src/js/extends.js @@ -1,4 +1,6 @@ -/** +/* + * @file extends.js + * * A combination of node inherits and babel's inherits (after transpile). * Both work the same but node adds `super_` to the subClass * and Bable adds the superClass as __proto__. Both seem useful. @@ -23,18 +25,17 @@ const _inherits = function (subClass, superClass) { } }; -/** +/* * Function for subclassing using the same inheritance that * videojs uses internally - * - * ``` + * ```js * var Button = videojs.getComponent('Button'); - * + * ``` + * ```js * var MyButton = videojs.extends(Button, { * constructor: function(player, options) { * Button.call(this, player, options); * }, - * * onClick: function() { * // doSomething * } diff --git a/src/js/fullscreen-api.js b/src/js/fullscreen-api.js index c1de7332b2..b594541ab1 100644 --- a/src/js/fullscreen-api.js +++ b/src/js/fullscreen-api.js @@ -1,6 +1,9 @@ +/** + * @file fullscreen-api.js + */ import document from 'global/document'; -/** +/* * Store the browser-specific methods for the fullscreen API * @type {Object|undefined} * @private diff --git a/src/js/global-options.js b/src/js/global-options.js index 954c65e817..50d9ef4349 100644 --- a/src/js/global-options.js +++ b/src/js/global-options.js @@ -1,12 +1,16 @@ +/** + * @file global-options.js + */ import document from 'global/document'; import window from 'global/window'; let navigator = window.navigator; -/** +/* * Global Player instance options, surfaced from Player.prototype.options_ * options = Player.prototype.options_ * All options should use string keys so they avoid * renaming by closure compiler + * * @type {Object} */ export default { diff --git a/src/js/loading-spinner.js b/src/js/loading-spinner.js index aee2cb9c0c..2987665072 100644 --- a/src/js/loading-spinner.js +++ b/src/js/loading-spinner.js @@ -1,15 +1,23 @@ +/** + * @file loading-spinner.js + */ import Component from './component'; -/* Loading Spinner +/ * Loading Spinner ================================================================================ */ /** * Loading spinner for waiting events - * @param {Player|Object} player - * @param {Object=} options - * @class - * @constructor + * + * @extends Component + * @class LoadingSpinner */ class LoadingSpinner extends Component { + + /** + * Create the component's DOM element + * + * @method createEl + */ createEl() { return super.createEl('div', { className: 'vjs-loading-spinner' diff --git a/src/js/media-error.js b/src/js/media-error.js index e43ea10f45..20d4dc6b7e 100644 --- a/src/js/media-error.js +++ b/src/js/media-error.js @@ -1,7 +1,11 @@ +/** + * @file media-error.js + */ import assign from 'object.assign'; -/** +/* * Custom MediaError to mimic the HTML5 MediaError + * * @param {Number} code The media error code */ let MediaError = function(code){ @@ -19,29 +23,32 @@ let MediaError = function(code){ } }; -/** +/* * The error code that refers two one of the defined * MediaError types + * * @type {Number} */ MediaError.prototype.code = 0; -/** +/* * An optional message to be shown with the error. * Message is not part of the HTML5 video spec * but allows for more informative custom errors. + * * @type {String} */ MediaError.prototype.message = ''; -/** +/* * An optional status code that can be set by plugins * to allow even more detail about the error. * For example the HLS plugin might provide the specific * HTTP status code that was returned when the error * occurred, then allowing a custom error overlay * to display more information. - * @type {[type]} + * + * @type {Array} */ MediaError.prototype.status = null; diff --git a/src/js/menu/menu-button.js b/src/js/menu/menu-button.js index f12396e060..4abeb6dacc 100644 --- a/src/js/menu/menu-button.js +++ b/src/js/menu/menu-button.js @@ -1,3 +1,6 @@ +/** + * @file menu-button.js + */ import Button from '../button.js'; import Component from '../component.js'; import Menu from './menu.js'; @@ -7,9 +10,11 @@ import toTitleCase from '../utils/to-title-case.js'; /** * A button class with a popup menu + * * @param {Player|Object} player * @param {Object=} options - * @constructor + * @extends Button + * @class MenuButton */ class MenuButton extends Button { @@ -23,6 +28,11 @@ class MenuButton extends Button { this.el_.setAttribute('role', 'button'); } + /** + * Update menu + * + * @method update + */ update() { let menu = this.createMenu(); @@ -35,6 +45,7 @@ class MenuButton extends Button { /** * Track the state of the menu button + * * @type {Boolean} * @private */ @@ -47,6 +58,12 @@ class MenuButton extends Button { } } + /** + * Create menu + * + * @return {Menu} The constructed menu + * @method createMenu + */ createMenu() { var menu = new Menu(this.player_); @@ -73,33 +90,64 @@ class MenuButton extends Button { /** * Create the list of menu items. Specific to each subclass. + * + * @method createItems */ createItems(){} + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { return super.createEl('div', { className: this.buildCSSClass() }); } - /** @inheritDoc */ + /** + * Allow sub components to stack CSS class names + * + * @return {String} The constructed class name + * @method buildCSSClass + */ buildCSSClass() { return `vjs-menu-button ${super.buildCSSClass()}`; } - // Focus - Add keyboard functionality to element - // This function is not needed anymore. Instead, the keyboard functionality is handled by - // treating the button as triggering a submenu. When the button is pressed, the submenu - // appears. Pressing the button again makes the submenu disappear. + /** + * Focus - Add keyboard functionality to element + * This function is not needed anymore. Instead, the + * keyboard functionality is handled by + * treating the button as triggering a submenu. + * When the button is pressed, the submenu + * appears. Pressing the button again makes + * the submenu disappear. + * + * @method handleFocus + */ handleFocus() {} - // Can't turn off list display that we turned on with focus, because list would go away. + /** + * Can't turn off list display that we turned + * on with focus, because list would go away. + * + * @method handleBlur + */ handleBlur() {} + /** + * When you click the button it adds focus, which + * will show the menu indefinitely. + * So we'll remove focus when the mouse leaves the button. + * Focus is needed for tab navigation. + * Allow sub components to stack CSS class names + * + * @method handleClick + */ handleClick() { - // When you click the button it adds focus, which will show the menu indefinitely. - // So we'll remove focus when the mouse leaves the button. - // Focus is needed for tab navigation. this.one('mouseout', Fn.bind(this, function(){ this.menu.unlockShowing(); this.el_.blur(); @@ -111,6 +159,12 @@ class MenuButton extends Button { } } + /** + * Handle key press on menu + * + * @param {Object} Key press event + * @method handleKeyPress + */ handleKeyPress(event) { // Check for space bar (32) or enter (13) keys @@ -130,6 +184,11 @@ class MenuButton extends Button { } } + /** + * Makes changes based on button pressed + * + * @method pressButton + */ pressButton() { this.buttonPressed_ = true; this.menu.lockShowing(); @@ -139,6 +198,11 @@ class MenuButton extends Button { } } + /** + * Makes changes based on button unpressed + * + * @method unpressButton + */ unpressButton() { this.buttonPressed_ = false; this.menu.unlockShowing(); diff --git a/src/js/menu/menu-item.js b/src/js/menu/menu-item.js index b0b497a424..3368002ab3 100644 --- a/src/js/menu/menu-item.js +++ b/src/js/menu/menu-item.js @@ -1,3 +1,6 @@ +/** + * @file menu-item.js + */ import Button from '../button.js'; import Component from '../component.js'; import assign from 'object.assign'; @@ -7,8 +10,8 @@ import assign from 'object.assign'; * * @param {Player|Object} player * @param {Object=} options - * @class - * @constructor + * @extends Button + * @class MenuItem */ class MenuItem extends Button { @@ -17,7 +20,14 @@ class MenuItem extends Button { this.selected(options['selected']); } - /** @inheritDoc */ + /** + * Create the component's DOM element + * + * @param {String=} type Desc + * @param {Object=} props Desc + * @return {Element} + * @method createEl + */ createEl(type, props) { return super.createEl('li', assign({ className: 'vjs-menu-item', @@ -27,6 +37,8 @@ class MenuItem extends Button { /** * Handle a click on the menu item, and set it to selected + * + * @method handleClick */ handleClick() { this.selected(true); @@ -34,7 +46,9 @@ class MenuItem extends Button { /** * Set this menu item as selected or not + * * @param {Boolean} selected + * @method selected */ selected(selected) { if (selected) { diff --git a/src/js/menu/menu.js b/src/js/menu/menu.js index 6852351d19..7efaa060b9 100644 --- a/src/js/menu/menu.js +++ b/src/js/menu/menu.js @@ -1,24 +1,25 @@ +/** + * @file menu.js + */ import Component from '../component.js'; import * as Dom from '../utils/dom.js'; import * as Fn from '../utils/fn.js'; import * as Events from '../utils/events.js'; -/* Menu -================================================================================ */ /** * The Menu component is used to build pop up menus, including subtitle and * captions selection menus. * - * @param {Player|Object} player - * @param {Object=} options - * @class - * @constructor + * @extends Component + * @class Menu */ class Menu extends Component { /** * Add a menu item to the menu + * * @param {Object|String} component Component or component type to add + * @method addItem */ addItem(component) { this.addChild(component); @@ -27,6 +28,12 @@ class Menu extends Component { })); } + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { let contentElType = this.options_.contentElType || 'ul'; this.contentEl_ = Dom.createEl(contentElType, { diff --git a/src/js/player.js b/src/js/player.js index efc34d35ce..fccaa6438c 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -1,4 +1,7 @@ -// Subclasses Component +/** + * @file player.js + */ + // Subclasses Component import Component from './component.js'; import document from 'global/document'; @@ -34,23 +37,22 @@ import Html5 from './tech/html5.js'; /** * An instance of the `Player` class is created when any of the Video.js setup methods are used to initialize a video. - * * ```js * var myPlayer = videojs('example_video_1'); * ``` - * * In the following example, the `data-setup` attribute tells the Video.js library to create a player instance when the library is ready. - * * ```html * * ``` - * * After an instance has been created it can be accessed globally using `Video('example_video_1')`. * - * @class + * @param {Element} tag The original video tag used for configuring options + * @param {Object=} options Object of option names and values + * @param {Function=} ready Ready callback function * @extends Component + * @class Player */ class Player extends Component { @@ -133,11 +135,12 @@ class Player extends Component { // May be turned back on by HTML5 tech if nativeControlsForTouch is true tag.controls = false; - /** - * Store the internal state of scrubbing - * @private - * @return {Boolean} True if the user is scrubbing - */ + /* + * Store the internal state of scrubbing + * + * @private + * @return {Boolean} True if the user is scrubbing + */ this.scrubbing_ = false; this.el_ = this.createEl(); @@ -202,11 +205,13 @@ class Player extends Component { /** * Destroys the video player and does any necessary cleanup - * + * ```js * myPlayer.dispose(); - * + * ``` * This is especially helpful if you are dynamically adding and removing videos * to/from the DOM. + * + * @method dispose */ dispose() { this.trigger('dispose'); @@ -223,6 +228,12 @@ class Player extends Component { super.dispose(); } + /** + * Create the component's DOM element + * + * @return {Element} + * @method createEl + */ createEl() { let el = this.el_ = super.createEl('div'); let tag = this.tag; @@ -283,14 +294,36 @@ class Player extends Component { return el; } + /** + * Get/set player width + * + * @param {Number=} value Value for width + * @return {Number} Width when getting + * @method width + */ width(value) { return this.dimension('width', value); } + /** + * Get/set player height + * + * @param {Number=} value Value for height + * @return {Number} Height when getting + * @method height + */ height(value) { return this.dimension('height', value); } + /** + * Get/set dimension for player + * + * @param {String} dimension Either width or height + * @param {Number=} value Value for dimension + * @return {Component} + * @method dimension + */ dimension(dimension, value) { let privDimension = dimension + '_'; @@ -316,6 +349,12 @@ class Player extends Component { return this; } + /** + * Add/remove the vjs-fluid class + * + * @param {Boolean} bool Value of true adds the class, value of false removes the class + * @method fluid + */ fluid(bool) { if (bool === undefined) { return !!this.fluid_; @@ -330,6 +369,13 @@ class Player extends Component { } } + /** + * Get/Set the aspect ratio + * + * @param {String=} ratio Aspect ratio for player + * @return aspectRatio + * @method aspectRatio + */ aspectRatio(ratio) { if (ratio === undefined) { return this.aspectRatio_; @@ -337,7 +383,7 @@ class Player extends Component { // Check for width:height format if (!/^\d+\:\d+$/.test(ratio)) { - throw new Error('Improper value suplied for aspect ratio. The format should be width:height, for example 16:9.'); + throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.'); } this.aspectRatio_ = ratio; @@ -348,6 +394,11 @@ class Player extends Component { this.updateStyleEl_(); } + /** + * Update styles of the player element (height, width and aspect ratio) + * + * @method updateStyleEl_ + */ updateStyleEl_() { let width; let height; @@ -385,7 +436,7 @@ class Player extends Component { height = this.height_; } else { // Otherwise calculate the height from the ratio and the width - height = width * ratioMultiplier; + height = width * ratioMultiplier; } let idClass = this.id()+'-dimensions'; @@ -396,7 +447,7 @@ class Player extends Component { // Create the width/height CSS var css = `.${idClass} { width: ${width}px; height: ${height}px; }`; // Add the aspect ratio CSS for when using a fluid layout - css += `.${idClass}.vjs-fluid { padding-top: ${ratioMultiplier * 100}%; }`; + css += `.${idClass}.vjs-fluid { padding-top: ${ratioMultiplier * 100}%; }`; // Update the style el if (this.styleEl_.styleSheet){ @@ -410,6 +461,10 @@ class Player extends Component { * Load the Media Playback Technology (tech) * Load/Create an instance of playback technology including element and API methods * And append playback element in player div. + * + * @param {String} techName Name of the playback technology + * @param {String} source Video source + * @method loadTech */ loadTech(techName, source) { @@ -513,6 +568,11 @@ class Player extends Component { this.tech.ready(techReady); } + /** + * Unload playback technology + * + * @method unloadTech + */ unloadTech() { // Save the current text tracks so that we can reuse the same text tracks with the next tech this.textTracks_ = this.textTracks(); @@ -524,6 +584,11 @@ class Player extends Component { this.tech = false; } + /** + * Add playback technology listeners + * + * @method addTechControlsListeners + */ addTechControlsListeners() { // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do // trigger mousedown/up. @@ -546,6 +611,8 @@ class Player extends Component { /** * Remove the listeners used for click and tap controls. This is needed for * toggling to controls disabled, where a tap/touch should do nothing. + * + * @method removeTechControlsListeners */ removeTechControlsListeners() { // We don't want to just use `this.off()` because there might be other needed @@ -559,7 +626,9 @@ class Player extends Component { /** * Player waits for the tech to be ready + * * @private + * @method handleTechReady */ handleTechReady() { this.triggerReady(); @@ -576,7 +645,9 @@ class Player extends Component { /** * Fired when the native controls are used + * * @private + * @method handleTechUseNativeControls */ handleTechUseNativeControls() { this.usingNativeControls(true); @@ -584,6 +655,7 @@ class Player extends Component { /** * Fired when the user agent begins looking for media data + * * @event loadstart */ handleTechLoadStart() { @@ -607,6 +679,13 @@ class Player extends Component { } } + /** + * Add/remove the vjs-has-started class + * + * @param {Boolean} hasStarted The value of true adds the class the value of false remove the class + * @return {Boolean} Boolean value if has started + * @method hasStarted + */ hasStarted(hasStarted) { if (hasStarted !== undefined) { // only update if this is a new value @@ -627,6 +706,7 @@ class Player extends Component { /** * Fired whenever the media begins or resumes playback + * * @event play */ handleTechPlay() { @@ -643,6 +723,7 @@ class Player extends Component { /** * Fired whenever the media begins waiting + * * @event waiting */ handleTechWaiting() { @@ -653,6 +734,7 @@ class Player extends Component { /** * A handler for events that signal that waiting has ended * which is not consistent between browsers. See #1351 + * * @event canplay */ handleTechCanPlay() { @@ -663,6 +745,7 @@ class Player extends Component { /** * A handler for events that signal that waiting has ended * which is not consistent between browsers. See #1351 + * * @event canplaythrough */ handleTechCanPlayThrough() { @@ -673,6 +756,7 @@ class Player extends Component { /** * A handler for events that signal that waiting has ended * which is not consistent between browsers. See #1351 + * * @event playing */ handleTechPlaying() { @@ -682,6 +766,7 @@ class Player extends Component { /** * Fired whenever the player is jumping to a new time + * * @event seeking */ handleTechSeeking() { @@ -691,6 +776,7 @@ class Player extends Component { /** * Fired when the player has finished jumping to a new time + * * @event seeked */ handleTechSeeked() { @@ -700,7 +786,6 @@ class Player extends Component { /** * Fired the first time a video is played - * * Not part of the HLS spec, and we're not sure if this is the best * implementation yet, so use sparingly. If you don't have a reason to * prevent playback, use `myPlayer.one('play');` instead. @@ -720,6 +805,7 @@ class Player extends Component { /** * Fired whenever the media has been paused + * * @event pause */ handleTechPause() { @@ -730,6 +816,7 @@ class Player extends Component { /** * Fired while the user agent is downloading media data + * * @event progress */ handleTechProgress() { @@ -743,6 +830,7 @@ class Player extends Component { /** * Fired when the end of the media resource is reached (currentTime == duration) + * * @event ended */ handleTechEnded() { @@ -759,6 +847,7 @@ class Player extends Component { /** * Fired when the duration of the media resource is first known or changed + * * @event durationchange */ handleTechDurationChange() { @@ -768,6 +857,9 @@ class Player extends Component { /** * Handle a click on the media element to play/pause + * + * @param {Object=} event Event object + * @method handleTechClick */ handleTechClick(event) { // We're using mousedown to detect clicks thanks to Flash, but mousedown @@ -788,21 +880,38 @@ class Player extends Component { /** * Handle a tap on the media element. It will toggle the user * activity state, which hides and shows the controls. + * + * @method handleTechTap */ handleTechTap() { this.userActive(!this.userActive()); } + /** + * Handle touch to start + * + * @method handleTechTouchStart + */ handleTechTouchStart() { this.userWasActive = this.userActive(); } + /** + * Handle touch to move + * + * @method handleTechTouchMove + */ handleTechTouchMove() { if (this.userWasActive){ this.reportUserActivity(); } } + /** + * Handle touch to end + * + * @method handleTechTouchEnd + */ handleTechTouchEnd(event) { // Stop the mouse events from also happening event.preventDefault(); @@ -810,7 +919,9 @@ class Player extends Component { /** * Update the duration of the player using the tech + * * @private + * @method updateDuration */ updateDuration() { // Allows for caching value instead of asking player each time. @@ -833,6 +944,7 @@ class Player extends Component { /** * Fired when the player switches in or out of fullscreen mode + * * @event fullscreenchange */ handleFullscreenChange() { @@ -846,18 +958,26 @@ class Player extends Component { /** * native click events on the SWF aren't triggered on IE11, Win8.1RT * use stageclick events triggered from inside the SWF instead + * * @private + * @method handleStageClick */ handleStageClick() { this.reportUserActivity(); } + /** + * Handle Tech Fullscreen Change + * + * @method handleTechFullscreenChange + */ handleTechFullscreenChange() { this.trigger('fullscreenchange'); } /** * Fires when an error occurred during the loading of an audio/video + * * @event error */ handleTechError() { @@ -866,6 +986,7 @@ class Player extends Component { /** * Fires when the browser is intentionally not getting media data + * * @event suspend */ handleTechSuspend() { @@ -874,6 +995,7 @@ class Player extends Component { /** * Fires when the loading of an audio/video is aborted + * * @event abort */ handleTechAbort() { @@ -882,6 +1004,7 @@ class Player extends Component { /** * Fires when the current playlist is empty + * * @event emptied */ handleTechEmptied() { @@ -890,6 +1013,7 @@ class Player extends Component { /** * Fires when the browser is trying to get media data, but data is not available + * * @event stalled */ handleTechStalled() { @@ -898,6 +1022,7 @@ class Player extends Component { /** * Fires when the browser has loaded meta data for the audio/video + * * @event loadedmetadata */ handleTechLoadedMetaData() { @@ -906,6 +1031,7 @@ class Player extends Component { /** * Fires when the browser has loaded the current frame of the audio/video + * * @event loaddata */ handleTechLoadedData() { @@ -914,6 +1040,7 @@ class Player extends Component { /** * Fires when the current playback position has changed + * * @event timeupdate */ handleTechTimeUpdate() { @@ -922,6 +1049,7 @@ class Player extends Component { /** * Fires when the playing speed of the audio/video is changed + * * @event ratechange */ handleTechRateChange() { @@ -930,6 +1058,7 @@ class Player extends Component { /** * Fires when the volume has been changed + * * @event volumechange */ handleTechVolumeChange() { @@ -938,6 +1067,7 @@ class Player extends Component { /** * Fires when the text track has been changed + * * @event texttrackchange */ onTextTrackChange() { @@ -945,13 +1075,22 @@ class Player extends Component { } /** - * Object for cached values. + * Get object for cached values. + * + * @return {Object} + * @method getCache */ getCache() { return this.cache_; } - // Pass values to the playback tech + /** + * Pass values to the playback tech + * + * @param {String=} method Method + * @param {Object=} arg Argument + * @method techCall + */ techCall(method, arg) { // If it's not ready yet, call method when it is if (this.tech && !this.tech.isReady_) { @@ -970,7 +1109,13 @@ class Player extends Component { } } - // Get calls can't wait for the tech, and sometimes don't need to. + /** + * Get calls can't wait for the tech, and sometimes don't need to. + * + * @param {String} method Tech method + * @return {Method} + * @method techGet + */ techGet(method) { if (this.tech && this.tech.isReady_) { @@ -1001,10 +1146,12 @@ class Player extends Component { /** * start media playback - * + * ```js * myPlayer.play(); + * ``` * * @return {Player} self + * @method play */ play() { this.techCall('play'); @@ -1013,10 +1160,12 @@ class Player extends Component { /** * Pause the video playback - * + * ```js * myPlayer.pause(); + * ``` * * @return {Player} self + * @method pause */ pause() { this.techCall('pause'); @@ -1025,11 +1174,13 @@ class Player extends Component { /** * Check if the player is paused - * + * ```js * var isPaused = myPlayer.paused(); * var isPlaying = !myPlayer.paused(); + * ``` * * @return {Boolean} false if the media is currently playing, or true otherwise + * @method paused */ paused() { // The initial state of paused should be true (in Safari it's actually false) @@ -1037,12 +1188,14 @@ class Player extends Component { } /** - * Returns whether or not the user is "scrubbing". Scrubbing is when the user - * has clicked the progress bar handle and is dragging it along the progress bar. - * @param {Boolean} isScrubbing True/false the user is scrubbing - * @return {Boolean} The scrubbing status when getting - * @return {Object} The player when setting - */ + * Returns whether or not the user is "scrubbing". Scrubbing is when the user + * has clicked the progress bar handle and is dragging it along the progress bar. + * + * @param {Boolean} isScrubbing True/false the user is scrubbing + * @return {Boolean} The scrubbing status when getting + * @return {Object} The player when setting + * @method scrubbing + */ scrubbing(isScrubbing) { if (isScrubbing !== undefined) { this.scrubbing_ = !!isScrubbing; @@ -1061,16 +1214,17 @@ class Player extends Component { /** * Get or set the current time (in seconds) - * + * ```js * // get * var whereYouAt = myPlayer.currentTime(); - * * // set * myPlayer.currentTime(120); // 2 minutes into the video + * ``` * * @param {Number|String=} seconds The time to seek to * @return {Number} The time in seconds, when not setting * @return {Player} self, when the current time is set + * @method currentTime */ currentTime(seconds) { if (seconds !== undefined) { @@ -1091,14 +1245,16 @@ class Player extends Component { /** * Get the length in time of the video in seconds - * + * ```js * var lengthOfVideo = myPlayer.duration(); - * + * ``` * **NOTE**: The video must have started loading before the duration can be * known, and in the case of Flash, may not be known until the video starts * playing. * - * @return {Number} The duration of the video in seconds + * @param {Number} seconds Duration when setting + * @return {Number} The duration of the video in seconds when getting + * @method duration */ duration(seconds) { if (seconds !== undefined) { @@ -1118,11 +1274,13 @@ class Player extends Component { /** * Calculates how much time is left. - * + * ```js * var timeLeft = myPlayer.remainingTime(); - * + * ``` * Not a native video element function, but useful + * * @return {Number} The time remaining in seconds + * @method remainingTime */ remainingTime() { return this.duration() - this.currentTime(); @@ -1134,23 +1292,21 @@ class Player extends Component { /** * Get a TimeRange object with the times of the video that have been downloaded - * * If you just want the percent of the video that's been downloaded, * use bufferedPercent. - * + * ```js * // Number of different ranges of time have been buffered. Usually 1. * numberOfRanges = bufferedTimeRange.length, - * * // Time in seconds when the first range starts. Usually 0. * firstRangeStart = bufferedTimeRange.start(0), - * * // Time in seconds when the first range ends * firstRangeEnd = bufferedTimeRange.end(0), - * * // Length in seconds of the first time range * firstRangeLength = firstRangeEnd - firstRangeStart; + * ``` * * @return {Object} A mock TimeRange object (following HTML spec) + * @method buffered */ buffered() { var buffered = this.techGet('buffered'); @@ -1164,13 +1320,14 @@ class Player extends Component { /** * Get the percent (as a decimal) of the video that's been downloaded - * + * ```js * var howMuchIsDownloaded = myPlayer.bufferedPercent(); - * + * ``` * 0 means none, 1 means all. * (This method isn't in the HTML5 spec, but it's very convenient) * * @return {Number} A decimal between 0 and 1 representing the percent + * @method bufferedPercent */ bufferedPercent() { return bufferedPercent(this.buffered(), this.duration()); @@ -1178,9 +1335,10 @@ class Player extends Component { /** * Get the ending time of the last buffered time range - * * This is used in the progress bar to encapsulate all time ranges. + * * @return {Number} The end of the last buffered time range + * @method bufferedEnd */ bufferedEnd() { var buffered = this.buffered(), @@ -1196,18 +1354,18 @@ class Player extends Component { /** * Get or set the current volume of the media - * + * ```js * // get * var howLoudIsIt = myPlayer.volume(); - * * // set * myPlayer.volume(0.5); // Set volume to half - * + * ``` * 0 is off (muted), 1.0 is all the way up, 0.5 is half way. * * @param {Number} percentAsDecimal The new volume as a decimal percent - * @return {Number} The current volume, when getting - * @return {Player} self, when setting + * @return {Number} The current volume when getting + * @return {Player} self when setting + * @method volume */ volume(percentAsDecimal) { let vol; @@ -1228,16 +1386,17 @@ class Player extends Component { /** * Get the current muted state, or turn mute on or off - * + * ```js * // get * var isVolumeMuted = myPlayer.muted(); - * * // set * myPlayer.muted(true); // mute the volume + * ``` * * @param {Boolean=} muted True to mute, false to unmute - * @return {Boolean} True if mute is on, false if not, when getting - * @return {Player} self, when setting mute + * @return {Boolean} True if mute is on, false if not when getting + * @return {Player} self when setting mute + * @method muted */ muted(muted) { if (muted !== undefined) { @@ -1249,26 +1408,32 @@ class Player extends Component { // Check if current tech can support native fullscreen // (e.g. with built in controls like iOS, so not our flash swf) + /** + * Check to see if fullscreen is supported + * + * @return {Boolean} + * @method supportsFullScreen + */ supportsFullScreen() { return this.techGet('supportsFullScreen') || false; } /** * Check if the player is in fullscreen mode - * + * ```js * // get * var fullscreenOrNot = myPlayer.isFullscreen(); - * * // set * myPlayer.isFullscreen(true); // tell the player it's in fullscreen - * + * ``` * NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official * property and instead document.fullscreenElement is used. But isFullscreen is * still a valuable property for internal player workings. * * @param {Boolean=} isFS Update the player's fullscreen state - * @return {Boolean} true if fullscreen, false if not - * @return {Player} self, when setting + * @return {Boolean} true if fullscreen false if not when getting + * @return {Player} self when setting + * @method isFullscreen */ isFullscreen(isFS) { if (isFS !== undefined) { @@ -1280,7 +1445,12 @@ class Player extends Component { /** * Old naming for isFullscreen() - * @deprecated for lowercase 's' version + * + * @param {Boolean=} isFS Update the player's fullscreen state + * @return {Boolean} true if fullscreen false if not when getting + * @return {Player} self when setting + * @deprecated + * @method isFullScreen */ isFullScreen(isFS) { log.warn('player.isFullScreen() has been deprecated, use player.isFullscreen() with a lowercase "s")'); @@ -1289,9 +1459,9 @@ class Player extends Component { /** * Increase the size of the video to full screen - * + * ```js * myPlayer.requestFullscreen(); - * + * ``` * In some browsers, full screen is not supported natively, so it enters * "full window mode", where the video fills the browser window. * In browsers and devices that support native full screen, sometimes the @@ -1300,6 +1470,7 @@ class Player extends Component { * Safari. * * @return {Player} self + * @method requestFullscreen */ requestFullscreen() { var fsApi = FullscreenApi; @@ -1344,7 +1515,10 @@ class Player extends Component { /** * Old naming for requestFullscreen - * @deprecated for lower case 's' version + * + * @return {Boolean} true if fullscreen false if not when getting + * @deprecated + * @method requestFullScreen */ requestFullScreen() { log.warn('player.requestFullScreen() has been deprecated, use player.requestFullscreen() with a lowercase "s")'); @@ -1353,10 +1527,12 @@ class Player extends Component { /** * Return the video to its normal size after having been in full screen mode - * + * ```js * myPlayer.exitFullscreen(); + * ``` * * @return {Player} self + * @method exitFullscreen */ exitFullscreen() { var fsApi = FullscreenApi; @@ -1377,14 +1553,21 @@ class Player extends Component { /** * Old naming for exitFullscreen - * @deprecated for exitFullscreen + * + * @return {Player} self + * @deprecated + * @method cancelFullScreen */ cancelFullScreen() { log.warn('player.cancelFullScreen() has been deprecated, use player.exitFullscreen()'); return this.exitFullscreen(); } - // When fullscreen isn't supported we can stretch the video container to as wide as the browser will let us. + /** + * When fullscreen isn't supported we can stretch the video container to as wide as the browser will let us. + * + * @method enterFullWindow + */ enterFullWindow() { this.isFullWindow = true; @@ -1403,6 +1586,12 @@ class Player extends Component { this.trigger('enterFullWindow'); } + /** + * Check for call to either exit full window or full screen on ESC key + * + * @param {String} event Event to check for key press + * @method fullWindowOnEscKey + */ fullWindowOnEscKey(event) { if (event.keyCode === 27) { if (this.isFullscreen() === true) { @@ -1413,6 +1602,11 @@ class Player extends Component { } } + /** + * Exit full window + * + * @method exitFullWindow + */ exitFullWindow() { this.isFullWindow = false; Events.off(document, 'keydown', this.fullWindowOnEscKey); @@ -1428,6 +1622,13 @@ class Player extends Component { this.trigger('exitFullWindow'); } + /** + * Select source based on tech order + * + * @param {Array} sources The sources for a media asset + * @return {Object|Boolean} Object of source and tech order, otherwise false + * @method selectSource + */ selectSource(sources) { // Loop through each playback technology in the options order for (var i=0,j=this.options_['techOrder'];i select'), fontPercent); } + /** + * Restore texttrack settings + * + * @method restoreSettings + */ restoreSettings() { let [err, values] = safeParseTuple(window.localStorage.getItem('vjs-text-track-settings')); @@ -121,6 +173,11 @@ class TextTrackSettings extends Component { } } + /** + * Save texttrack settings to local storage + * + * @method saveSettings + */ saveSettings() { if (!this.options_.persistTextTrackSettings) { return; @@ -136,6 +193,11 @@ class TextTrackSettings extends Component { } catch (e) {} } + /** + * Update display of texttrack settings + * + * @method updateDisplay + */ updateDisplay() { let ttDisplay = this.player_.getChild('textTrackDisplay'); if (ttDisplay) { diff --git a/src/js/tracks/text-track.js b/src/js/tracks/text-track.js index 3779791b9d..c18ad4b646 100644 --- a/src/js/tracks/text-track.js +++ b/src/js/tracks/text-track.js @@ -1,3 +1,6 @@ +/** + * @file text-track.js + */ import TextTrackCueList from './text-track-cue-list'; import * as Fn from '../utils/fn.js'; import * as Guid from '../utils/guid.js'; @@ -225,8 +228,8 @@ TextTrack.prototype.removeCue = function(removeCue) { }; /* - * Downloading stuff happens below this point - */ +* Downloading stuff happens below this point +*/ var parseCues = function(srcContent, track) { if (typeof window['WebVTT'] !== 'function') { //try again a bit later diff --git a/src/js/utils/browser.js b/src/js/utils/browser.js index 3b905dcd17..90a6f7deb1 100644 --- a/src/js/utils/browser.js +++ b/src/js/utils/browser.js @@ -1,10 +1,14 @@ +/** + * @file browser.js + */ import document from 'global/document'; import window from 'global/window'; const USER_AGENT = window.navigator.userAgent; -/** +/* * Device is an iPhone + * * @type {Boolean} * @constant * @private diff --git a/src/js/utils/buffer.js b/src/js/utils/buffer.js index 81accf9960..063a9ec95c 100644 --- a/src/js/utils/buffer.js +++ b/src/js/utils/buffer.js @@ -1,11 +1,16 @@ +/** + * @file buffer.js + */ import { createTimeRange } from './time-ranges.js'; /** * Compute how much your video has been buffered + * * @param {Object} Buffered object * @param {Number} Total duration * @return {Number} Percent buffered of the total duration * @private + * @function bufferedPercent */ export function bufferedPercent(buffered, duration) { var bufferedDuration = 0, diff --git a/src/js/utils/dom.js b/src/js/utils/dom.js index 8a506d717e..43cb2ac9de 100644 --- a/src/js/utils/dom.js +++ b/src/js/utils/dom.js @@ -1,13 +1,18 @@ +/** + * @file dom.js + */ import document from 'global/document'; import window from 'global/window'; -import * as Guid from './guid.js'; +import * as Guid from './guid.js'; import roundFloat from './round-float.js'; /** * Shorthand for document.getElementById() * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs. + * * @param {String} id Element ID * @return {Element} Element with supplied ID + * @function getEl */ export function getEl(id){ if (id.indexOf('#') === 0) { @@ -19,9 +24,11 @@ export function getEl(id){ /** * Creates an element and applies properties. + * * @param {String=} tagName Name of tag to be created. * @param {Object=} properties Element properties to be applied. * @return {Element} + * @function createEl */ export function createEl(tagName='div', properties={}){ let el = document.createElement(tagName); @@ -32,10 +39,10 @@ export function createEl(tagName='div', properties={}){ // Not remembering why we were checking for dash // but using setAttribute means you have to use getAttribute - // The check for dash checks for the aria-* attributes, like aria-label, aria-valuemin. + // The check for dash checks for the aria- * attributes, like aria-label, aria-valuemin. // The additional check for "role" is because the default method for adding attributes does not // add the attribute "role". My guess is because it's not a valid attribute in some namespaces, although - // browsers handle the attribute just fine. The W3C allows for aria-* attributes to be used in pre-HTML5 docs. + // browsers handle the attribute just fine. The W3C allows for aria- * attributes to be used in pre-HTML5 docs. // http://www.w3.org/TR/wai-aria-primer/#ariahtml. Using setAttribute gets around this problem. if (propName.indexOf('aria-') !== -1 || propName === 'role') { el.setAttribute(propName, val); @@ -49,9 +56,11 @@ export function createEl(tagName='div', properties={}){ /** * Insert an element as the first child node of another + * * @param {Element} child Element to insert - * @param {[type]} parent Element to insert child into + * @param {Element} parent Element to insert child into * @private + * @function insertElFirst */ export function insertElFirst(child, parent){ if (parent.firstChild) { @@ -65,13 +74,15 @@ export function insertElFirst(child, parent){ * Element Data Store. Allows for binding data to an element without putting it directly on the element. * Ex. Event listeners are stored here. * (also from jsninja.com, slightly modified and updated for closure compiler) + * * @type {Object} * @private */ const elData = {}; -/** +/* * Unique attribute name to store an element's guid in + * * @type {String} * @constant * @private @@ -80,8 +91,10 @@ const elIdAttr = 'vdata' + (new Date()).getTime(); /** * Returns the cache object where data for an element is stored + * * @param {Element} el Element to store data for. * @return {Object} + * @function getElData */ export function getElData(el) { let id = el[elIdAttr]; @@ -99,9 +112,11 @@ export function getElData(el) { /** * Returns whether or not an element has cached data + * * @param {Element} el A dom element * @return {Boolean} * @private + * @function hasElData */ export function hasElData(el) { const id = el[elIdAttr]; @@ -115,8 +130,10 @@ export function hasElData(el) { /** * Delete data for the element from the cache and the guid attr from getElementById + * * @param {Element} el Remove data for an element * @private + * @function removeElData */ export function removeElData(el) { let id = el[elIdAttr]; @@ -143,8 +160,10 @@ export function removeElData(el) { /** * Check if an element has a CSS class + * * @param {Element} element Element to check * @param {String} classToCheck Classname to check + * @function hasElClass */ export function hasElClass(element, classToCheck) { return ((' ' + element.className + ' ').indexOf(' ' + classToCheck + ' ') !== -1); @@ -152,8 +171,10 @@ export function hasElClass(element, classToCheck) { /** * Add a CSS class name to an element + * * @param {Element} element Element to add class name to * @param {String} classToAdd Classname to add + * @function addElClass */ export function addElClass(element, classToAdd) { if (!hasElClass(element, classToAdd)) { @@ -163,8 +184,10 @@ export function addElClass(element, classToAdd) { /** * Remove a CSS class name from an element + * * @param {Element} element Element to remove from class name - * @param {String} classToAdd Classname to remove + * @param {String} classToRemove Classname to remove + * @function removeElClass */ export function removeElClass(element, classToRemove) { if (!hasElClass(element, classToRemove)) {return;} @@ -183,9 +206,11 @@ export function removeElClass(element, classToRemove) { /** * Apply attributes to an HTML element. + * * @param {Element} el Target element. * @param {Object=} attributes Element attributes to be applied. * @private + * @function setElAttributes */ export function setElAttributes(el, attributes) { Object.getOwnPropertyNames(attributes).forEach(function(attrName){ @@ -204,9 +229,11 @@ export function setElAttributes(el, attributes) { * Attributes are not the same as properties. They're defined on the tag * or with setAttribute (which shouldn't be used with HTML) * This will return true or false for boolean attributes. + * * @param {Element} tag Element from which to get tag attributes * @return {Object} * @private + * @function getElAttributes */ export function getElAttributes(tag) { var obj, knownBooleans, attrs, attrName, attrVal; @@ -241,7 +268,12 @@ export function getElAttributes(tag) { return obj; } -// Attempt to block the ability to select text while dragging controls +/** + * Attempt to block the ability to select text while dragging controls + * + * @return {Boolean} + * @method blockTextSelection + */ export function blockTextSelection() { document.body.focus(); document.onselectstart = function() { @@ -249,15 +281,27 @@ export function blockTextSelection() { }; } -// Turn off text selection blocking +/** + * Turn off text selection blocking + * + * @return {Boolean} + * @method unblockTextSelection + */ export function unblockTextSelection() { document.onselectstart = function() { return true; }; } -// Offset Left -// getBoundingClientRect technique from John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/ +/** + * Offset Left + * getBoundingClientRect technique from + * John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/ + * + * @param {Element} el Element from which to get offset + * @return {Object=} + * @method findElPosition + */ export function findElPosition(el) { let box; diff --git a/src/js/utils/events.js b/src/js/utils/events.js index c4357c047c..7a0993c5d0 100644 --- a/src/js/utils/events.js +++ b/src/js/utils/events.js @@ -1,12 +1,14 @@ /** - * @fileoverview Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/) + * @file events.js + * + * Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/) * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible) * This should work very similarly to jQuery's events, however it's based off the book version which isn't as * robust as jquery's, so there's probably some differences. */ -import * as Dom from './dom.js'; -import * as Guid from './guid.js'; +import * as Dom from './dom.js'; +import * as Guid from './guid.js'; import window from 'global/window'; import document from 'global/document'; @@ -15,9 +17,11 @@ import document from 'global/document'; * It stores the handler function in a separate cache object * and adds a generic handler to the element's event, * along with a unique id (guid) to the element. + * * @param {Element|Object} elem Element or object to bind listeners to * @param {String|Array} type Type of event to bind to. * @param {Function} fn Event listener. + * @method on */ export function on(elem, type, fn){ if (Array.isArray(type)) { @@ -71,9 +75,11 @@ export function on(elem, type, fn){ /** * Removes event listeners from an element + * * @param {Element|Object} elem Object to remove listeners from * @param {String|Array=} type Type of listener to remove. Don't include to remove all events from element. * @param {Function} fn Specific listener to remove. Don't include to remove listeners for an event type. + * @method off */ export function off(elem, type, fn) { // Don't want to add a cache object through getElData if not needed @@ -125,9 +131,12 @@ export function off(elem, type, fn) { /** * Trigger an event for an element + * * @param {Element|Object} elem Element to trigger an event on * @param {Event|Object|String} event A string (the type) or an event object with a type attribute * @param {Object} [hash] data hash to pass along with the event + * @return {Boolean=} Returned only if default was prevented + * @method trigger */ export function trigger(elem, event, hash) { // Fetches element data and a reference to the parent (for bubbling). @@ -178,9 +187,11 @@ export function trigger(elem, event, hash) { /** * Trigger a listener only once for an event + * * @param {Element|Object} elem Element or object to - * @param {String|Array} type - * @param {Function} fn + * @param {String|Array} type Name/type of event + * @param {Function} fn Event handler function + * @method one */ export function one(elem, type, fn) { if (Array.isArray(type)) { @@ -197,9 +208,11 @@ export function one(elem, type, fn) { /** * Fix a native event to have standard property values + * * @param {Object} event Event object to fix * @return {Object} * @private + * @method fixEvent */ export function fixEvent(event) { @@ -305,9 +318,11 @@ export function fixEvent(event) { /** * Clean up the listener cache and dispatchers +* * @param {Element|Object} elem Element to clean up * @param {String} type Type of event to clean up * @private + * @method _cleanUpEvents */ function _cleanUpEvents(elem, type) { var data = Dom.getElData(elem); @@ -341,11 +356,13 @@ function _cleanUpEvents(elem, type) { /** * Loops through an array of event types and calls the requested method for each type. + * * @param {Function} fn The event method we want to use. * @param {Element|Object} elem Element or object to bind listeners to * @param {String} type Type of event to bind to. * @param {Function} callback Event listener. * @private + * @function _handleMultipleEvents */ function _handleMultipleEvents(fn, elem, types, callback) { types.forEach(function(type) { diff --git a/src/js/utils/fn.js b/src/js/utils/fn.js index 08656c9bb5..69bbe83ad8 100644 --- a/src/js/utils/fn.js +++ b/src/js/utils/fn.js @@ -1,13 +1,18 @@ +/** + * @file fn.js + */ import { newGUID } from './guid.js'; /** * Bind (a.k.a proxy or Context). A simple method for changing the context of a function - It also stores a unique id on the function so it can be easily removed from events + * It also stores a unique id on the function so it can be easily removed from events + * * @param {*} context The object to bind as scope * @param {Function} fn The function to be bound to a scope * @param {Number=} uid An optional unique ID for the function to be set * @return {Function} * @private + * @method bind */ export const bind = function(context, fn, uid) { // Make sure the function has a unique ID diff --git a/src/js/utils/format-time.js b/src/js/utils/format-time.js index 64a0fb9676..8b70bfb6b7 100644 --- a/src/js/utils/format-time.js +++ b/src/js/utils/format-time.js @@ -1,11 +1,15 @@ /** + * @file format-time.js + * * Format seconds as a time string, H:MM:SS or M:SS * Supplying a guide (in seconds) will force a number of leading zeros * to cover the length of the guide + * * @param {Number} seconds Number of seconds to be turned into a string * @param {Number} guide Number (in seconds) to model the string after * @return {String} Time formatted as H:MM:SS or M:SS * @private + * @function formatTime */ function formatTime(seconds, guide=seconds) { let s = Math.floor(seconds % 60); diff --git a/src/js/utils/guid.js b/src/js/utils/guid.js index bdeb7eb818..e832e7088b 100644 --- a/src/js/utils/guid.js +++ b/src/js/utils/guid.js @@ -1,4 +1,6 @@ /** + * @file guid.js + * * Unique ID for an element or function * @type {Number} * @private @@ -7,6 +9,9 @@ let _guid = 1; /** * Get the next unique ID + * + * @return {String} + * @function newGUID */ export function newGUID() { return _guid++; diff --git a/src/js/utils/log.js b/src/js/utils/log.js index 551397dae7..f82466eb7d 100644 --- a/src/js/utils/log.js +++ b/src/js/utils/log.js @@ -1,3 +1,6 @@ +/** + * @file log.js + */ import window from 'global/window'; /** @@ -31,8 +34,9 @@ log.warn = function(){ * Log messages to the console and history based on the type of message * * @param {String} type The type of message, or `null` for `log` - * @param {[type]} args The args to be passed to the log + * @param {Object} args The args to be passed to the log * @private + * @method _logType */ function _logType(type, args){ // convert args to an array to get array functions diff --git a/src/js/utils/merge-options.js b/src/js/utils/merge-options.js index 34b517bd09..6a3a114413 100644 --- a/src/js/utils/merge-options.js +++ b/src/js/utils/merge-options.js @@ -1,3 +1,6 @@ +/** + * @file merge-options.js + */ import merge from 'lodash-compat/object/merge'; function isPlain(obj) { @@ -8,13 +11,13 @@ function isPlain(obj) { } /** - * Merge two options objects, recursively merging **only** plain object + * Merge two options objects, recursively merging **only* * plain object * properties. Previously `deepMerge`. * * @param {Object} object The destination object * @param {...Object} source One or more objects to merge into the first - * * @returns {Object} The updated first object + * @function mergeOptions */ export default function mergeOptions(object={}) { diff --git a/src/js/utils/round-float.js b/src/js/utils/round-float.js index 19d81f3e77..177cc692f4 100644 --- a/src/js/utils/round-float.js +++ b/src/js/utils/round-float.js @@ -1,9 +1,13 @@ /** + * @file round-float.js + * * Should round off a number to a decimal place + * * @param {Number} num Number to round * @param {Number} dec Number of decimal places to round to * @return {Number} Rounded number * @private + * @method roundFloat */ const roundFloat = function(num, dec=0) { return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec); diff --git a/src/js/utils/time-ranges.js b/src/js/utils/time-ranges.js index 009ea1bc88..174c06c2f3 100644 --- a/src/js/utils/time-ranges.js +++ b/src/js/utils/time-ranges.js @@ -1,12 +1,16 @@ /** + * @file time-ranges.js + * * Should create a fake TimeRange object * Mimics an HTML5 time range instance, which has functions that * return the start and end times for a range * TimeRanges are returned by the buffered() method + * * @param {Number} start Start time in seconds * @param {Number} end End time in seconds * @return {Object} Fake TimeRange object * @private + * @method createTimeRange */ export function createTimeRange(start, end){ if (start === undefined && end === undefined) { diff --git a/src/js/utils/to-title-case.js b/src/js/utils/to-title-case.js index 5b159fd4aa..f3984f8190 100644 --- a/src/js/utils/to-title-case.js +++ b/src/js/utils/to-title-case.js @@ -1,8 +1,12 @@ /** + * @file to-title-case.js + * * Uppercase the first letter of a string + * * @param {String} string String to be uppercased * @return {String} * @private + * @method toTitleCase */ function toTitleCase(string){ return string.charAt(0).toUpperCase() + string.slice(1); diff --git a/src/js/utils/url.js b/src/js/utils/url.js index 701dcd7cde..74e139d64e 100644 --- a/src/js/utils/url.js +++ b/src/js/utils/url.js @@ -1,9 +1,14 @@ +/** + * @file url.js + */ import document from 'global/document'; /** * Resolve and parse the elements of a URL + * * @param {String} url The url to parse * @return {Object} An object of url details + * @method parseUrl */ export const parseUrl = function(url) { const props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host']; @@ -53,9 +58,11 @@ export const parseUrl = function(url) { /** * Get absolute version of relative URL. Used to tell flash correct URL. * http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue + * * @param {String} url URL to make absolute * @return {String} Absolute URL * @private + * @method getAbsoluteURL */ export const getAbsoluteURL = function(url){ // Check if absolute URL @@ -74,6 +81,7 @@ export const getAbsoluteURL = function(url){ * * @param {String} path The fileName path like '/path/to/file.mp4' * @returns {String} The extension in lower case or an empty string if no extension could be found. + * @method getFileExtension */ export const getFileExtension = function(path) { if(typeof path === 'string'){ diff --git a/src/js/video.js b/src/js/video.js index 38142566a3..1bd2e93e5e 100644 --- a/src/js/video.js +++ b/src/js/video.js @@ -1,3 +1,6 @@ +/** + * @file video.js + */ import document from 'global/document'; import * as setup from './setup'; import Component from './component'; @@ -27,16 +30,17 @@ if (typeof HTMLVideoElement === 'undefined') { /** * Doubles as the main function for users to create a player instance and also * the main library object. - * * The `videojs` function can be used to initialize or retrieve a player. - * + * ```js * var myPlayer = videojs('my_video_id'); + * ``` * * @param {String|Element} id Video element or video element ID * @param {Object=} options Optional options object for config/settings * @param {Function=} ready Optional ready callback - * @return {Player} A player instance - * @namespace + * @return {Player} A player instance + * @mixes videojs + * @method videojs */ var videojs = function(id, options, ready){ var tag; // Element of ID @@ -88,8 +92,9 @@ var videojs = function(id, options, ready){ // You have to wait at least once in case this script is loaded after your video in the DOM (weird behavior only with minified version) setup.autoSetupTimeout(1, videojs); -/** +/* * Current software version (semver) + * * @type {String} */ videojs.VERSION = '__VERSION__'; @@ -97,22 +102,26 @@ videojs.VERSION = '__VERSION__'; /** * Get the global options object * - * @returns {Object} The global options object + * @return {Object} The global options object + * @mixes videojs + * @method getGlobalOptions */ videojs.getGlobalOptions = () => globalOptions; /** * Set options that will apply to every player - * + * ```js * videojs.setGlobalOptions({ * autoplay: true * }); * // -> all players will autoplay by default - * + * ``` * NOTE: This will do a deep merge with the new options, * not overwrite the entire global options object. * - * @returns {Object} The updated global options object + * @return {Object} The updated global options object + * @mixes videojs + * @method setGlobalOptions */ videojs.setGlobalOptions = function(newOptions) { return mergeOptions(globalOptions, newOptions); @@ -121,7 +130,9 @@ videojs.setGlobalOptions = function(newOptions) { /** * Get an object with the currently created players, keyed by player ID * - * @returns {Object} The created players + * @return {Object} The created players + * @mixes videojs + * @method getPlayers */ videojs.getPlayers = function() { return Player.players; @@ -129,47 +140,49 @@ videojs.getPlayers = function() { /** * Get a component class object by name - * + * ```js * var VjsButton = videojs.getComponent('Button'); - * * // Create a new instance of the component * var myButton = new VjsButton(myPlayer); + * ``` * + * @return {Component} Component identified by name + * @mixes videojs + * @method getComponent */ videojs.getComponent = Component.getComponent; /** * Register a component so it can referred to by name - * * Used when adding to other * components, either through addChild * `component.addChild('myComponent')` * or through default children options * `{ children: ['myComponent'] }`. - * + * ```js * // Get a component to subclass * var VjsButton = videojs.getComponent('Button'); - * * // Subclass the component (see 'extends' doc for more info) * var MySpecialButton = videojs.extends(VjsButton, {}); - * * // Register the new component * VjsButton.registerComponent('MySepcialButton', MySepcialButton); - * * // (optionally) add the new component as a default player child * myPlayer.addChild('MySepcialButton'); - * + * ``` * NOTE: You could also just initialize the component before adding. * `component.addChild(new MyComponent());` * * @param {String} The class name of the component * @param {Component} The component class - * @returns {Component} The newly registered component + * @return {Component} The newly registered component + * @mixes videojs + * @method registerComponent */ videojs.registerComponent = Component.registerComponent; -/** +/* * A suite of browser and device tests + * * @type {Object} */ videojs.browser = browser; @@ -177,18 +190,16 @@ videojs.browser = browser; /** * Subclass an existing class * Mimics ES6 subclassing with the `extends` keyword - * + * ```js * // Create a basic javascript 'class' * function MyClass(name){ * // Set a property at initialization * this.myName = name; * } - * * // Create an instance method * MyClass.prototype.sayMyName = function(){ * alert(this.myName); * }; - * * // Subclass the exisitng class and change the name * // when initializing * var MySubClass = videojs.extends(MyClass, { @@ -197,16 +208,17 @@ videojs.browser = browser; * MyClass.call(this, name) * } * }); - * * // Create an instance of the new sub class * var myInstance = new MySubClass('John'); * myInstance.sayMyName(); // -> should alert "John" + * ``` * * @param {Function} The Class to subclass * @param {Object} An object including instace methods for the new class * Optionally including a `constructor` function - * - * @returns {Function} The newly created subclass + * @return {Function} The newly created subclass + * @mixes videojs + * @method extends */ videojs.extends = extendsFn; @@ -215,7 +227,7 @@ videojs.extends = extendsFn; * Performs a deep merge like lodash.merge but **only merges plain objects** * (not arrays, elements, anything else) * Other values will be copied directly from the second object. - * + * ```js * var defaultOptions = { * foo: true, * bar: { @@ -229,29 +241,29 @@ videojs.extends = extendsFn; * b: [4,5,6] * } * }; - * * var result = videojs.mergeOptions(defaultOptions, newOptions); * // result.foo = false; * // result.bar.a = true; * // result.bar.b = [4,5,6]; + * ``` * * @param {Object} The options object whose values will be overriden * @param {Object} The options object with values to override the first * @param {Object} Any number of additional options objects * - * @returns {Object} a new object with the merged values + * @return {Object} a new object with the merged values + * @mixes videojs + * @method mergeOptions */ videojs.mergeOptions = mergeOptions; /** * Create a Video.js player plugin - * * Plugins are only initialized when options for the plugin are included * in the player options, or the plugin function on the player instance is * called. - * * **See the plugin guide in the docs for a more detailed example** - * + * ```js * // Make a plugin that alerts when the player plays * videojs.plugin('myPlugin', function(myPluginOptions) { * myPluginOptions = myPluginOptions || {}; @@ -263,9 +275,7 @@ videojs.mergeOptions = mergeOptions; * alert(alertText); * }); * }); - * * // USAGE EXAMPLES - * * // EXAMPLE 1: New player with plugin options, call plugin immediately * var player1 = videojs('idOne', { * myPlugin: { @@ -274,7 +284,6 @@ videojs.mergeOptions = mergeOptions; * }); * // Click play * // --> Should alert 'Custom text!' - * * // EXAMPLE 3: New player, initialize plugin later * var player3 = videojs('idThree'); * // Click play @@ -286,21 +295,26 @@ videojs.mergeOptions = mergeOptions; * }); * // Click play * // --> Should alert 'Plugin added later!' + * ``` * * @param {String} The plugin name * @param {Function} The plugin function that will be called with options + * @mixes videojs + * @method plugin */ videojs.plugin = plugin; /** * Adding languages so that they're available to all players. - * + * ```js * videojs.addLanguage('es', { 'Hello': 'Hola' }); + * ``` * * @param {String} code The language code or dictionary property * @param {Object} data The data values to be translated - * * @return {Object} The resulting language dictionary object + * @mixes videojs + * @method addLanguage */ videojs.addLanguage = function(code, data){ code = ('' + code).toLowerCase(); @@ -324,7 +338,7 @@ videojs.addLanguage = function(code, data){ // assign(module.exports[name], component); // }); -/** +/* * Custom Universal Module Definition (UMD) * * Video.js will never be a non-browser lib so we can simplify UMD a bunch and diff --git a/src/js/xhr.js b/src/js/xhr.js index 0c0a287ca9..7aac4897dc 100644 --- a/src/js/xhr.js +++ b/src/js/xhr.js @@ -1,13 +1,14 @@ -import * as Url from './utils/url.js'; +/** + * @file xhr.js + */ +import * as Url from './utils/url.js'; import log from './utils/log.js'; import mergeOptions from './utils/merge-options.js'; import window from 'global/window'; -/** +/* * Simple http request for retrieving external files (e.g. text tracks) - * * ##### Example - * * // using url string * videojs.xhr('http://example.com/myfile.vtt', function(error, response, responseBody){}); * @@ -23,15 +24,15 @@ import window from 'global/window'; * // successful, do something with the response * } * }); - * - * + * ///////////// * API is modeled after the Raynos/xhr, which we hope to use after * getting browserify implemented. * https://github.com/Raynos/xhr/blob/master/index.js * * @param {Object|String} options Options block or URL string * @param {Function} callback The callback function - * @returns {Object} The request + * @return {Object} The request + * @method xhr */ var xhr = function(options, callback){ let abortTimeout; @@ -46,7 +47,7 @@ var xhr = function(options, callback){ // Merge with default options mergeOptions({ method: 'GET', - timeout: 45 * 1000 + timeout: 45 * 1000 }, options); callback = callback || function(){};