myButton
+ * console.log(myComponent.children());
+ * // -> myButton === myComponent.children()[0];
* ```
*
- * @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.
- * @param {Number} index into our children array to attempt to add the child
- * @return {Component} The child component (created by this process if a string was used)
- * @method addChild
+ * Pass in options for child constructors and options for children of the child.
+ * ```js
+ * var player = videojs('some-vid-id');
+ * var Component = videojs.getComponent('Component');
+ * var myComponent = new Component(player);
+ * var myButton = myComponent.addChild('MyButton', {
+ * text: 'Press Me',
+ * buttonChildExample: {
+ * buttonChildOption: true
+ * }
+ * });
+ * ```
+ *
+ * @param {string|Component} child
+ * The name or instance of a child to add.
+ *
+ * @param {Object} [options={}]
+ * The key/value store of options that will get passed to children of
+ * the child.
+ *
+ * @param {number} [index=this.children_.length]
+ * The index to attempt to add a child into.
+ *
+ * @return {Component}
+ * The `Component` that gets added as a child. When using a string the
+ * `Component` will get created by this process.
*/
addChild(child, options = {}, index = this.children_.length) {
let component;
@@ -351,14 +429,18 @@ class Component {
if (typeof child === 'string') {
componentName = toTitleCase(child);
- // Options can also be specified as a boolean, so convert to an empty object if false.
+ // Options can also be specified as a boolean,
+ // so convert to an empty object if false.
if (!options) {
options = {};
}
// Same as above, but true is deprecated so show a warning.
if (options === true) {
- log.warn('Initializing a child component with `true` is deprecated. Children should be defined in an array when possible, but if necessary use an object instead of `true`.');
+ log.warn('Initializing a child component with `true` is deprecated.' +
+ 'Children should be defined in an array when possible, ' +
+ 'but if necessary use an object instead of `true`.'
+ );
options = {};
}
@@ -418,11 +500,11 @@ class Component {
}
/**
- * Remove a child component from this component's list of children, and the
- * child component's element from this component's element
+ * Remove a child `Component` from this `Component`s list of children. Also removes
+ * the child `Component`s element from this `Component`s element.
*
- * @param {Component} component Component to remove
- * @method removeChild
+ * @param {Component} component
+ * The child `Component` to remove.
*/
removeChild(component) {
if (typeof component === 'string') {
@@ -458,50 +540,49 @@ 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: [
- * 'myChildComponent'
- * ],
- * myChildComponent: {
- * myChildOption: true
- * }
- * };
+ * Add and initialize default child `Component`s based upon options.
*
- * // Or when creating the component
- * var myComp = new MyComponent(player, {
- * children: [
- * 'myChildComponent'
- * ],
- * myChildComponent: {
- * myChildOption: true
- * }
- * });
- * ```
- * The children option can also be an array of
- * child options objects (that also include a 'name' key).
- * This can be used if you have two child components of the
- * same type that need different options.
+ * Example.
* ```js
- * var myComp = new MyComponent(player, {
- * children: [
- * 'button',
- * {
- * name: 'button',
- * someOtherOption: true
- * },
- * {
- * name: 'button',
- * someOtherOption: false
- * }
- * ]
- * });
+ * var MyComponent = videojs.extend(videojs.getComponent('Component'));
+ * // 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: [
+ * 'myChildComponent'
+ * ],
+ * myChildComponent: {
+ * myChildOption: true
+ * }
+ * };
+ *
+ * // Or when creating the component
+ * var player = videojs('some-player-id');
+ * var myComp = new MyComponent(player, {
+ * children: [
+ * 'myChildComponent'
+ * ],
+ * myChildComponent: {
+ * myChildOption: true
+ * }
+ * });
* ```
*
- * @method initChildren
+ * The children option can also be an array of child options objects
+ * (that also include a 'name' key). This will get used if you have two child
+ * components of the same type that need different options.
+ * ```js
+ * // MyComponent is from the above example
+ * var myComp = new MyComponent(player, {
+ * children: ['button', {
+ * name: 'button',
+ * someOtherOption: true
+ * }, {
+ * name: 'button',
+ * someOtherOption: false
+ * }]
+ * });
+ * ```
*/
initChildren() {
const children = this.options_.children;
@@ -533,7 +614,8 @@ class Component {
opts = {};
}
- // We also want to pass the original player options to each component as well so they don't need to
+ // We also want to pass the original player options
+ // to each component as well so they don't need to
// reach back into the player for options later.
opts.playerOptions = this.options_.playerOptions;
@@ -598,10 +680,12 @@ class Component {
}
/**
- * Allows sub components to stack CSS class names
+ * Builds the default DOM class name. Should be overriden by sub-components.
*
- * @return {String} The constructed class name
- * @method buildCSSClass
+ * @return {string}
+ * The DOM class name for this object.
+ *
+ * @abstract
*/
buildCSSClass() {
// Child classes can include a function that does:
@@ -610,35 +694,63 @@ 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
- * };
+ * Add an `event listener` to this `Component`s element.
*
- * 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
- * references to it and allow the browser to garbage collect it.
+ * var player = videojs('some-player-id');
+ * var Component = videojs.getComponent('Component');
+ * var myComponent = new Component(player);
+ * var myFunc = function() {
+ * var myComponent = this;
+ * console.log('myFunc called');
+ * };
+ *
+ * myComponent.on('eventType', myFunc);
+ * myComponent.trigger('eventType');
+ * // logs 'myFunc called'
+ * ```
+ *
+ * The context of `myFunc` will be `myComponent` unless it is bound. You can add
+ * a listener to another element or component.
+ * ```js
+ * var otherComponent = new Component(player);
+ *
+ * // myComponent/myFunc is from the above example
+ * myComponent.on(otherComponent.el(), 'eventName', myFunc);
+ * myComponent.on(otherComponent, 'eventName', myFunc);
+ *
+ * otherComponent.trigger('eventName');
+ * // logs 'myFunc called' twice
+ * ```
+ *
+ * The benefit of using this over the following:
+ * - `VjsEvents.on(otherElement, 'eventName', myFunc)`
+ * - `otherComponent.on('eventName', myFunc)`
+ * Is that the listeners will get cleaned up when either component gets disposed.
+ * It will also bind `myComponent` as the context of `myFunc`.
+ * > NOTE: If you remove the element from the DOM that has used `on` you need to
+ * clean up references using:
+ *
+ * `myComponent.trigger(el, 'dispose')`
+ *
+ * This will also allow the browser to garbage collect it. In special
+ * cases such as with `window` and `document`, which are both permanent,
+ * this is not necessary.
+ *
+ * @param {string|Component|string[]} [first]
+ * The event name, and array of event names, or another `Component`.
+ *
+ * @param {EventTarget~EventListener|string|string[]} [second]
+ * The listener function, an event name, or an Array of events names.
+ *
+ * @param {EventTarget~EventListener} [third]
+ * The event handler if `first` is a `Component` and `second` is an event name
+ * or an Array of event names.
*
- * @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}
- * @method on
+ * Returns itself; method can be chained.
+ *
+ * @listens Component#dispose
*/
on(first, second, third) {
if (typeof first === 'string' || Array.isArray(first)) {
@@ -685,25 +797,60 @@ class Component {
}
/**
- * Remove an event listener from this component's element
+ * 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);
+ * var player = videojs('some-player-id');
+ * var Component = videojs.getComponent('Component');
+ * var myComponent = new Component(player);
+ * var myFunc = function() {
+ * var myComponent = this;
+ * console.log('myFunc called');
+ * };
+ * myComponent.on('eventType', myFunc);
+ * myComponent.trigger('eventType');
+ * // logs 'myFunc called'
+ *
+ * myComponent.off('eventType', myFunc);
+ * myComponent.trigger('eventType');
+ * // does nothing
* ```
*
- * @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
+ * If myFunc gets excluded, ALL listeners for the event type will get removed. If
+ * eventType gets excluded, ALL listeners will get removed from the component.
+ * You can use `off` to remove listeners that get added to other elements or
+ * components using:
+ *
+ * `myComponent.on(otherComponent...`
+ *
+ * In this case both the event type and listener function are **REQUIRED**.
+ *
+ * ```js
+ * var otherComponent = new Component(player);
+ *
+ * // myComponent/myFunc is from the above example
+ * myComponent.on(otherComponent.el(), 'eventName', myFunc);
+ * myComponent.on(otherComponent, 'eventName', myFunc);
+ *
+ * otherComponent.trigger('eventName');
+ * // logs 'myFunc called' twice
+ * myComponent.off(ootherComponent.el(), 'eventName', myFunc);
+ * myComponent.off(otherComponent, 'eventName', myFunc);
+ * otherComponent.trigger('eventName');
+ * // does nothing
+ * ```
+ *
+ * @param {string|Component|string[]} [first]
+ * The event name, and array of event names, or another `Component`.
+ *
+ * @param {EventTarget~EventListener|string|string[]} [second]
+ * The listener function, an event name, or an Array of events names.
+ *
+ * @param {EventTarget~EventListener} [third]
+ * The event handler if `first` is a `Component` and `second` is an event name
+ * or an Array of event names.
+ *
* @return {Component}
- * @method off
+ * Returns itself; method can be chained.
*/
off(first, second, third) {
if (!first || typeof first === 'string' || Array.isArray(first)) {
@@ -733,22 +880,52 @@ class Component {
}
/**
- * Add an event listener to be triggered only once and then removed
+ * Add an event listener that gets triggered only once and then gets 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);
+ * var player = videojs('some-player-id');
+ * var Component = videojs.getComponent('Component');
+ * var myComponent = new Component(player);
+ * var myFunc = function() {
+ * var myComponent = this;
+ * console.log('myFunc called');
+ * };
+ * myComponent.one('eventName', myFunc);
+ * myComponent.trigger('eventName');
+ * // logs 'myFunc called'
+ *
+ * myComponent.trigger('eventName');
+ * // does nothing
+ *
* ```
*
- * @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
+ * You can also add a listener to another element or component that will get
+ * triggered only once.
+ * ```js
+ * var otherComponent = new Component(player);
+ *
+ * // myComponent/myFunc is from the above example
+ * myComponent.one(otherComponent.el(), 'eventName', myFunc);
+ * myComponent.one(otherComponent, 'eventName', myFunc);
+ *
+ * otherComponent.trigger('eventName');
+ * // logs 'myFunc called' twice
+ *
+ * otherComponent.trigger('eventName');
+ * // does nothing
+ * ```
+ *
+ * @param {string|Component|string[]} [first]
+ * The event name, and array of event names, or another `Component`.
+ *
+ * @param {EventTarget~EventListener|string|string[]} [second]
+ * The listener function, an event name, or an Array of events names.
+ *
+ * @param {EventTarget~EventListener} [third]
+ * The event handler if `first` is a `Component` and `second` is an event name
+ * or an Array of event names.
+ *
* @return {Component}
- * @method one
+ * Returns itself; method can be chained.
*/
one(first, second, third) {
if (typeof first === 'string' || Array.isArray(first)) {
@@ -773,18 +950,40 @@ class Component {
}
/**
- * Trigger an event on an element
+ * 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'});
+ * var player = videojs('some-player-id');
+ * var Component = videojs.getComponent('Component');
+ * var myComponent = new Component(player);
+ * var myFunc = function(data) {
+ * var myComponent = this;
+ * console.log('myFunc called');
+ * console.log(data);
+ * };
+ * myComponent.one('eventName', myFunc);
+ * myComponent.trigger('eventName');
+ * // logs 'myFunc called' and 'undefined'
+ *
+ * myComponent.trigger({'type':'eventName'});
+ * // logs 'myFunc called' and 'undefined'
+ *
+ * myComponent.trigger('eventName', {data: 'some data'});
+ * // logs 'myFunc called' and "{data: 'some data'}"
+ *
+ * myComponent.trigger({'type':'eventName'}, {data: 'some data'});
+ * // logs 'myFunc called' and "{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
+ * @param {EventTarget~Event|Object|string} event
+ * The event name, and Event, or an event-like object with a type attribute
+ * set to the event name.
+ *
+ * @param {Object} [hash]
+ * Data hash to pass along with the event
+ *
+ * @return {Component}
+ * Returns itself; method can be chained.
*/
trigger(event, hash) {
Events.trigger(this.el_, event, hash);
@@ -792,14 +991,17 @@ class Component {
}
/**
- * 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.
+ * Bind a listener to the component's ready state. If the ready event has already
+ * happened it will trigger the function immediately.
+ *
+ * @param {Component~ReadyCallback} fn
+ * A function to call when ready is triggered.
+ *
+ * @param {boolean} [sync=false]
+ * Execute the listener synchronously if `Component` is ready.
*
- * @param {Function} fn Ready listener
- * @param {Boolean} sync Exec the listener synchronously if component is ready
* @return {Component}
- * @method ready
+ * Returns itself; method can be chained.
*/
ready(fn, sync = false) {
if (fn) {
@@ -819,10 +1021,9 @@ class Component {
}
/**
- * Trigger the ready listeners
+ * Trigger all the ready listeners for this `Component`.
*
- * @return {Component}
- * @method triggerReady
+ * @fires Component#ready
*/
triggerReady() {
this.isReady_ = true;
@@ -841,67 +1042,82 @@ class Component {
}
// Allow for using event listeners also
+ /**
+ * Triggered when a `Component` is ready.
+ *
+ * @event Component#ready
+ * @type {EventTarget~Event}
+ */
this.trigger('ready');
}, 1);
}
/**
- * Finds a single DOM element matching `selector` within the component's
- * `contentEl` or another custom context.
+ * Find a single DOM element matching a `selector`. This can be within the `Component`s
+ * `contentEl()` or another custom context.
*
- * @method $
- * @param {String} selector
- * A valid CSS selector, which will be passed to `querySelector`.
+ * @param {string} selector
+ * A valid CSS selector, which will be passed to `querySelector`.
*
- * @param {Element|String} [context=document]
- * A DOM element within which to query. Can also be a selector
- * string in which case the first matching element will be used
- * as context. If missing (or no element matches selector), falls
- * back to `document`.
+ * @param {Element|string} [context=this.contentEl()]
+ * A DOM element within which to query. Can also be a selector string in
+ * which case the first matching element will get used as context. If
+ * missing `this.contentEl()` gets used. If `this.contentEl()` returns
+ * nothing it falls back to `document`.
*
* @return {Element|null}
+ * the dom element that was found, or null
+ *
+ * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
*/
$(selector, context) {
return Dom.$(selector, context || this.contentEl());
}
/**
- * Finds a all DOM elements matching `selector` within the component's
- * `contentEl` or another custom context.
+ * Finds all DOM element matching a `selector`. This can be within the `Component`s
+ * `contentEl()` or another custom context.
*
- * @method $$
- * @param {String} selector
- * A valid CSS selector, which will be passed to `querySelectorAll`.
+ * @param {string} selector
+ * A valid CSS selector, which will be passed to `querySelectorAll`.
*
- * @param {Element|String} [context=document]
- * A DOM element within which to query. Can also be a selector
- * string in which case the first matching element will be used
- * as context. If missing (or no element matches selector), falls
- * back to `document`.
+ * @param {Element|string} [context=this.contentEl()]
+ * A DOM element within which to query. Can also be a selector string in
+ * which case the first matching element will get used as context. If
+ * missing `this.contentEl()` gets used. If `this.contentEl()` returns
+ * nothing it falls back to `document`.
*
* @return {NodeList}
+ * a list of dom elements that were found
+ *
+ * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
*/
$$(selector, context) {
return Dom.$$(selector, context || this.contentEl());
}
/**
- * Check if a component's element has a CSS class name
+ * Check if a component's element has a CSS class name.
*
- * @param {String} classToCheck Classname to check
- * @return {Component}
- * @method hasClass
+ * @param {string} classToCheck
+ * CSS class name to check.
+ *
+ * @return {boolean}
+ * - True if the `Component` has the class.
+ * - False if the `Component` does not have the class`
*/
hasClass(classToCheck) {
return Dom.hasElClass(this.el_, classToCheck);
}
/**
- * Add a CSS class name to the component's element
+ * Add a CSS class name to the `Component`s element.
+ *
+ * @param {string} classToAdd
+ * CSS class name to add
*
- * @param {String} classToAdd Classname to add
* @return {Component}
- * @method addClass
+ * Returns itself; method can be chained.
*/
addClass(classToAdd) {
Dom.addElClass(this.el_, classToAdd);
@@ -909,11 +1125,13 @@ class Component {
}
/**
- * Remove a CSS class name from the component's element
+ * Remove a CSS class name from the `Component`s element.
+ *
+ * @param {string} classToRemove
+ * CSS class name to remove
*
- * @param {String} classToRemove Classname to remove
* @return {Component}
- * @method removeClass
+ * Returns itself; method can be chained.
*/
removeClass(classToRemove) {
Dom.removeElClass(this.el_, classToRemove);
@@ -921,16 +1139,18 @@ class Component {
}
/**
- * Add or remove a CSS class name from the component's element
+ * Add or remove a CSS class name from the component's element.
+ * - `classToToggle` gets added when {@link Component#hasClass} would return false.
+ * - `classToToggle` gets removed when {@link Component#hasClass} would return true.
*
- * @param {String} classToToggle
- * @param {Boolean|Function} [predicate]
- * Can be a function that returns a Boolean. If `true`, the class
- * will be added; if `false`, the class will be removed. If not
- * given, the class will be added if not present and vice versa.
+ * @param {string} classToToggle
+ * The class to add or remove based on (@link Component#hasClass}
+ *
+ * @param {boolean|Dom~predicate} [predicate]
+ * An {@link Dom~predicate} function or a boolean
*
* @return {Component}
- * @method toggleClass
+ * Returns itself; method can be chained.
*/
toggleClass(classToToggle, predicate) {
Dom.toggleElClass(this.el_, classToToggle, predicate);
@@ -938,10 +1158,11 @@ class Component {
}
/**
- * Show the component element if hidden
+ * Show the `Component`s element if it is hidden by removing the
+ * 'vjs-hidden' class name from it.
*
* @return {Component}
- * @method show
+ * Returns itself; method can be chained.
*/
show() {
this.removeClass('vjs-hidden');
@@ -949,10 +1170,11 @@ class Component {
}
/**
- * Hide the component element if currently showing
+ * Hide the `Component`s element if it is currently showing by adding the
+ * 'vjs-hidden` class name to it.
*
* @return {Component}
- * @method hide
+ * Returns itself; method can be chained.
*/
hide() {
this.addClass('vjs-hidden');
@@ -960,12 +1182,13 @@ class Component {
}
/**
- * Lock an item in its visible state
- * To be used with fadeIn/fadeOut.
+ * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing'
+ * class name to it. Used during fadeIn/fadeOut.
*
* @return {Component}
+ * Returns itself; method can be chained.
+ *
* @private
- * @method lockShowing
*/
lockShowing() {
this.addClass('vjs-lock-showing');
@@ -973,12 +1196,13 @@ class Component {
}
/**
- * Unlock an item to be hidden
- * To be used with fadeIn/fadeOut.
+ * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing'
+ * class name from it. Used during fadeIn/fadeOut.
*
* @return {Component}
+ * Returns itself; method can be chained.
+ *
* @private
- * @method unlockShowing
*/
unlockShowing() {
this.removeClass('vjs-lock-showing');
@@ -986,23 +1210,37 @@ class Component {
}
/**
- * Get the value of an attribute on the component's element
+ * Get the value of an attribute on the `Component`s element.
*
- * @param {String} attribute Attribute to get
- * @return {String}
- * @method getAttribute
+ * @param {string} attribute
+ * Name of the attribute to get the value from.
+ *
+ * @return {string|null}
+ * - The value of the attribute that was asked for.
+ * - Can be an empty string on some browsers if the attribute does not exist
+ * or has no value
+ * - Most browsers will return null if the attibute does not exist or has
+ * no value.
+ *
+ * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute}
*/
getAttribute(attribute) {
return Dom.getAttribute(this.el_, attribute);
}
/**
- * Set the value of an attribute on the component's element
+ * Set the value of an attribute on the `Component`'s element
+ *
+ * @param {string} attribute
+ * Name of the attribute to set.
+ *
+ * @param {string} value
+ * Value to set the attribute to.
*
- * @param {String} attribute Attribute to set
- * @param {String} value Value to set the attribute to
* @return {Component}
- * @method setAttribute
+ * Returns itself; method can be chained.
+ *
+ * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute}
*/
setAttribute(attribute, value) {
Dom.setAttribute(this.el_, attribute, value);
@@ -1010,11 +1248,15 @@ class Component {
}
/**
- * Remove an attribute from the component's element
+ * Remove an attribute from the `Component`s element.
+ *
+ * @param {string} attribute
+ * Name of the attribute to remove.
*
- * @param {String} attribute Attribute to remove
* @return {Component}
- * @method removeAttribute
+ * Returns itself; method can be chained.
+ *
+ * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute}
*/
removeAttribute(attribute) {
Dom.removeAttribute(this.el_, attribute);
@@ -1022,46 +1264,54 @@ 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 + %,
- * not the actual computed width/height.
+ * Get or set the width of the component based upon the CSS styles.
+ * See {@link Component#dimension} for more detailed information.
*
- * @param {Number|String=} num Optional width number
- * @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
+ * @param {number|string} [num]
+ * The width that you want to set postfixed with '%', 'px' or nothing.
+ *
+ * @param {boolean} [skipListeners]
+ * Skip the resize event trigger
+ *
+ * @return {Component|number|string}
+ * - The width when getting, zero if there is no width. Can be a string
+ * postpixed with '%' or 'px'.
+ * - Returns itself when setting; method can be chained.
*/
width(num, skipListeners) {
return this.dimension('width', num, skipListeners);
}
/**
- * 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 + %,
- * not the actual computed width/height.
+ * Get or set the height of the component based upon the CSS styles.
+ * See {@link Component#dimension} for more detailed information.
*
- * @param {Number|String=} num New component height
- * @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
+ * @param {number|string} [num]
+ * The height that you want to set postfixed with '%', 'px' or nothing.
+ *
+ * @param {boolean} [skipListeners]
+ * Skip the resize event trigger
+ *
+ * @return {Component|number|string}
+ * - The width when getting, zero if there is no width. Can be a string
+ * postpixed with '%' or 'px'.
+ * - Returns itself when setting; method can be chained.
*/
height(num, skipListeners) {
return this.dimension('height', num, skipListeners);
}
/**
- * Set both width and height at the same time
+ * Set both the width and height of the `Component` element at the same time.
*
- * @param {Number|String} width Width of player
- * @param {Number|String} height Height of player
- * @return {Component} The component
- * @method dimensions
+ * @param {number|string} width
+ * Width to set the `Component`s element to.
+ *
+ * @param {number|string} height
+ * Height to set the `Component`s element to.
+ *
+ * @return {Component}
+ * Returns itself; method can be chained.
*/
dimensions(width, height) {
// Skip resize listeners on width for optimization
@@ -1069,21 +1319,33 @@ 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:
- * http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/
+ * Get or set width or height of the `Component` element. This is the shared code
+ * for the {@link Component#width} and {@link Component#height}.
*
- * @param {String} widthOrHeight 'width' or 'height'
- * @param {Number|String=} num New dimension
- * @param {Boolean=} skipListeners Skip resize event trigger
- * @return {Component} The component if a dimension was set
- * @return {Number|String} The dimension if nothing was set
- * @private
- * @method dimension
+ * Things to know:
+ * - If the width or height in an number this will return the number postfixed with 'px'.
+ * - If the width/height is a percent this will return the percent postfixed with '%'
+ * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function
+ * defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`.
+ * See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/}
+ * for more information
+ * - If you want the computed style of the component, use {@link Component#currentWidth}
+ * and {@link {Component#currentHeight}
+ *
+ * @fires Component#resize
+ *
+ * @param {string} widthOrHeight
+ 8 'width' or 'height'
+ *
+ * @param {number|string} [num]
+ 8 New dimension
+ *
+ * @param {boolean} [skipListeners]
+ * Skip resize event trigger
+ *
+ * @return {Component}
+ * - the dimension when getting or 0 if unset
+ * - Returns itself when setting; method can be chained.
*/
dimension(widthOrHeight, num, skipListeners) {
if (num !== undefined) {
@@ -1103,6 +1365,12 @@ class Component {
// skipListeners allows us to avoid triggering the resize event when setting both width and height
if (!skipListeners) {
+ /**
+ * Triggered when a component is resized.
+ *
+ * @event Component#resize
+ * @type {EventTarget~Event}
+ */
this.trigger('resize');
}
@@ -1132,10 +1400,15 @@ class Component {
}
/**
- * Get width or height of computed style
- * @param {String} widthOrHeight 'width' or 'height'
- * @return {Number|Boolean} The bolean false if nothing was set
- * @method currentDimension
+ * Get the width or the height of the `Component` elements computed style. Uses
+ * `window.getComputedStyle`.
+ *
+ * @param {string} widthOrHeight
+ * A string containing 'width' or 'height'. Whichever one you want to get.
+ *
+ * @return {number}
+ * The dimension that gets asked for or 0 if nothing was set
+ * for that dimension.
*/
currentDimension(widthOrHeight) {
let computedWidthOrHeight = 0;
@@ -1166,9 +1439,24 @@ class Component {
}
/**
- * Get an object which contains width and height values of computed style
- * @return {Object} The dimensions of element
- * @method currentDimensions
+ * An object that contains width and height values of the `Component`s
+ * computed style. Uses `window.getComputedStyle`.
+ *
+ * @typedef {Object} Component~DimensionObject
+ *
+ * @property {number} width
+ * The width of the `Component`s computed style.
+ *
+ * @property {number} height
+ * The height of the `Component`s computed style.
+ */
+
+ /**
+ * Get an object that contains width and height values of the `Component`s
+ * computed style.
+ *
+ * @return {Component~DimensionObject}
+ * The dimensions of the components element
*/
currentDimensions() {
return {
@@ -1178,32 +1466,38 @@ class Component {
}
/**
- * Get width of computed style
- * @return {Integer}
- * @method currentWidth
+ * Get the width of the `Component`s computed style. Uses `window.getComputedStyle`.
+ *
+ * @return {number} width
+ * The width of the `Component`s computed style.
*/
currentWidth() {
return this.currentDimension('width');
}
/**
- * Get height of computed style
- * @return {Integer}
- * @method currentHeight
+ * Get the height of the `Component`s computed style. Uses `window.getComputedStyle`.
+ *
+ * @return {number} height
+ * The height of the `Component`s computed style.
*/
currentHeight() {
return this.currentDimension('height');
}
/**
- * 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.
+ * Emit a 'tap' events when touch event support gets detected. This gets used to
+ * support toggling the controls through a tap on the video. They get enabled
+ * because every sub-component would have extra overhead otherwise.
*
* @private
- * @method emitTapEvents
+ * @fires Component#tap
+ * @listens Component#touchstart
+ * @listens Component#touchmove
+ * @listens Component#touchleave
+ * @listens Component#touchcancel
+ * @listens Component#touchend
+
*/
emitTapEvents() {
// Track the start time so we can determine how long the touch lasted
@@ -1211,7 +1505,8 @@ class Component {
let firstTouch = null;
// Maximum movement allowed during a touch event to still be considered a tap
- // Other popular libs use anywhere from 2 (hammer.js) to 15, so 10 seems like a nice, round number.
+ // Other popular libs use anywhere from 2 (hammer.js) to 15,
+ // so 10 seems like a nice, round number.
const tapMovementThreshold = 10;
// The maximum length a touch can be while still being considered a tap
@@ -1272,6 +1567,12 @@ class Component {
if (touchTime < touchTimeThreshold) {
// Don't let browser turn this into a click
event.preventDefault();
+ /**
+ * Triggered when a `Component` is tapped.
+ *
+ * @event Component#tap
+ * @type {EventTarget~Event}
+ */
this.trigger('tap');
// It may be good to copy the touchend event object and change the
// type to tap, if the other event properties aren't exact after
@@ -1282,25 +1583,27 @@ 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
- * checked asynchronously, so what could happen is a tap event on the video
- * 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.
+ * This function reports user activity whenever touch events happen. This can get
+ * turned off by any sub-components that wants touch events to act another way.
*
- * @method enableTouchActivity
+ * Report user touch activity when touch events occur. User activity gets used to
+ * determine when controls should show/hide. It is 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 as `touchstart` and `touchend` toggle player
+ * controls. So touch events can't help us at the player level either.
+ *
+ * User activity gets checked asynchronously. So what could happen is a tap event
+ * on the video 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.
+ * Furthermore a `touchmove` event and anything other than a tap, should not turn
+ * controls back on.
+ *
+ * @listens Component#touchstart
+ * @listens Component#touchmove
+ * @listens Component#touchend
+ * @listens Component#touchcancel
*/
enableTouchActivity() {
// Don't continue if the root player doesn't support reporting user activity
@@ -1335,19 +1638,42 @@ class Component {
}
/**
- * Creates timeout and sets up disposal automatically.
+ * A callback that has no parameters and is bound into `Component`s context.
*
- * @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
+ * @callback Component~GenericCallback
+ * @this Component
+ */
+
+ /**
+ * Creates a function that runs after an `x` millisecond timeout. This function is a
+ * wrapper around `window.setTimeout`. There are a few reasons to use this one
+ * instead though:
+ * 1. It gets cleared via {@link Component#clearTimeout} when
+ * {@link Component#dispose} gets called.
+ * 2. The function callback will gets turned into a {@link Component~GenericCallback}
+ *
+ * > Note: You can use `window.clearTimeout` on the id returned by this function. This
+ * will cause its dispose listener not to get cleaned up! Please use
+ * {@link Component#clearTimeout} or {@link Component#dispose}.
+ *
+ * @param {Component~GenericCallback} fn
+ * The function that will be run after `timeout`.
+ *
+ * @param {number} timeout
+ * Timeout in milliseconds to delay before executing the specified function.
+ *
+ * @return {number}
+ * Returns a timeout ID that gets used to identify the timeout. It can also
+ * get used in {@link Component#clearTimeout} to clear the timeout that
+ * was set.
+ *
+ * @listens Component#dispose
+ * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout}
*/
setTimeout(fn, timeout) {
fn = Fn.bind(this, fn);
- // window.setTimeout would be preferable here, but due to some bizarre issue with Sinon and/or Phantomjs, we can't.
const timeoutId = window.setTimeout(fn, timeout);
-
const disposeFn = function() {
this.clearTimeout(timeoutId);
};
@@ -1360,11 +1686,19 @@ class Component {
}
/**
- * Clears a timeout and removes the associated dispose listener
+ * Clears a timeout that gets created via `window.setTimeout` or
+ * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout}
+ * use this function instead of `window.clearTimout`. If you don't your dispose
+ * listener will not get cleaned up until {@link Component#dispose}!
*
- * @param {Number} timeoutId The id of the timeout to clear
- * @return {Number} Returns the timeout ID
- * @method clearTimeout
+ * @param {number} timeoutId
+ * The id of the timeout to clear. The return value of
+ * {@link Component#setTimeout} or `window.setTimeout`.
+ *
+ * @return {number}
+ * Returns the timeout id that was cleared.
+ *
+ * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout}
*/
clearTimeout(timeoutId) {
window.clearTimeout(timeoutId);
@@ -1379,12 +1713,24 @@ class Component {
}
/**
- * Creates an interval and sets up disposal automatically.
+ * Creates a function that gets run every `x` milliseconds. This function is a wrapper
+ * around `window.setInterval`. There are a few reasons to use this one instead though.
+ * 1. It gets cleared via {@link Component#clearInterval} when
+ * {@link Component#dispose} gets called.
+ * 2. The function callback will be a {@link Component~GenericCallback}
*
- * @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
+ * @param {Component~GenericCallback} fn
+ * The function to run every `x` seconds.
+ *
+ * @param {number} interval
+ * Execute the specified function every `x` milliseconds.
+ *
+ * @return {number}
+ * Returns an id that can be used to identify the interval. It can also be be used in
+ * {@link Component#clearInterval} to clear the interval.
+ *
+ * @listens Component#dispose
+ * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval}
*/
setInterval(fn, interval) {
fn = Fn.bind(this, fn);
@@ -1403,11 +1749,19 @@ class Component {
}
/**
- * Clears an interval and removes the associated dispose listener
+ * Clears an interval that gets created via `window.setInterval` or
+ * {@link Component#setInterval}. If you set an inteval via {@link Component#setInterval}
+ * use this function instead of `window.clearInterval`. If you don't your dispose
+ * listener will not get cleaned up until {@link Component#dispose}!
*
- * @param {Number} intervalId The id of the interval to clear
- * @return {Number} Returns the interval ID
- * @method clearInterval
+ * @param {number} intervalId
+ * The id of the interval to clear. The return value of
+ * {@link Component#setInterval} or `window.setInterval`.
+ *
+ * @return {number}
+ * Returns the interval id that was cleared.
+ *
+ * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval}
*/
clearInterval(intervalId) {
window.clearInterval(intervalId);
@@ -1422,12 +1776,23 @@ class Component {
}
/**
- * Registers a component
+ * Register a `Component` with `videojs` given the name and the component.
*
- * @param {String} name Name of the component to register
- * @param {Object} comp The component to register
- * @static
- * @method registerComponent
+ * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s
+ * should be registered using {@link Tech.registerTech} or
+ * {@link videojs:videojs.registerTech}.
+ *
+ * > NOTE: This function can also be seen on videojs as
+ * {@link videojs:videojs.registerComponent}.
+ *
+ * @param {string} name
+ * The name of the `Component` to register.
+ *
+ * @param {Component} comp
+ * The `Component` class to register.
+ *
+ * @return {Component}
+ * The `Component` that was registered.
*/
static registerComponent(name, comp) {
if (!name) {
@@ -1460,12 +1825,18 @@ class Component {
}
/**
- * Gets a component by name
+ * Get a `Component` based on the name it was registered with.
+ *
+ * @param {string} name
+ * The Name of the component to get.
*
- * @param {String} name Name of the component to get
* @return {Component}
- * @static
- * @method getComponent
+ * The `Component` that got registered under the given name.
+ *
+ * @deprecated In `videojs` 6 this will not return `Component`s that were not
+ * registered using {@link Component.registerComponent}. Currently we
+ * check the global `videojs` object for a `Component` name and
+ * return that if it exists.
*/
static getComponent(name) {
if (!name) {
@@ -1486,23 +1857,29 @@ class Component {
}
/**
- * Sets up the constructor using the supplied init method
- * or uses the init of the parent object
+ * 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
- * @deprecated
- * @method extend
+ * @param {Object} [props={}]
+ * An object of properties.
+ *
+ * @return {Object}
+ * the extended object.
+ *
+ * @deprecated since version 5
*/
static extend(props) {
props = props || {};
- log.warn('Component.extend({}) has been deprecated, use videojs.extend(Component, {}) instead');
+ log.warn('Component.extend({}) has been deprecated, ' +
+ ' use videojs.extend(Component, {}) instead'
+ );
// Set up the constructor using the supplied init method
// or using the init of the parent object
// Make sure to check the unobfuscated version for external libs
- const init = props.init || props.init || this.prototype.init || this.prototype.init || function() {};
+ const init = props.init || props.init || this.prototype.init ||
+ this.prototype.init || function() {};
// In Resig's simple class inheritance (previously used) the constructor
// is a function that calls `this.init.apply(arguments)`
// However that would prevent us from using `ParentObject.call(this);`
diff --git a/src/js/error-display.js b/src/js/error-display.js
index 095904028..54ef6a257 100644
--- a/src/js/error-display.js
+++ b/src/js/error-display.js
@@ -6,18 +6,21 @@ import ModalDialog from './modal-dialog';
import mergeOptions from './utils/merge-options';
/**
- * Display that an error has occurred making the video unplayable.
+ * A display that indicates an error has occurred. This means that the video
+ * is unplayable.
*
* @extends ModalDialog
- * @class ErrorDisplay
*/
class ErrorDisplay extends ModalDialog {
/**
- * Constructor for error display modal.
+ * Creates an instance of this class.
*
* @param {Player} player
+ * The `Player` that this class should be attached to.
+ *
* @param {Object} [options]
+ * The key/value store of player options.
*/
constructor(player, options) {
super(player, options);
@@ -25,22 +28,22 @@ class ErrorDisplay extends ModalDialog {
}
/**
- * Include the old class for backward-compatibility.
+ * Builds the default DOM `className`.
*
- * This can be removed in 6.0.
+ * @return {string}
+ * The DOM `className` for this object.
*
- * @method buildCSSClass
- * @deprecated
- * @return {String}
+ * @deprecated Since version 5.
*/
buildCSSClass() {
return `vjs-error-display ${super.buildCSSClass()}`;
}
/**
- * Generates the modal content based on the player error.
+ * Gets the localized error message based on the `Player`s error.
*
- * @return {String|Null}
+ * @return {string}
+ * The `Player`s error message localized or an empty string.
*/
content() {
const error = this.player().error();
@@ -49,6 +52,11 @@ class ErrorDisplay extends ModalDialog {
}
}
+/**
+ * The default options for an `ErrorDisplay`.
+ *
+ * @private
+ */
ErrorDisplay.prototype.options_ = mergeOptions(ModalDialog.prototype.options_, {
fillAlways: true,
temporary: false,
diff --git a/src/js/event-target.js b/src/js/event-target.js
index 2c738df3c..8a100ef4a 100644
--- a/src/js/event-target.js
+++ b/src/js/event-target.js
@@ -1,12 +1,73 @@
/**
- * @file event-target.js
+ * @file src/js/event-target.js
*/
import * as Events from './utils/events.js';
+/**
+ * `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It
+ * adds shorthand functions that wrap around lengthy functions. For example:
+ * the `on` function is a wrapper around `addEventListener`.
+ *
+ * @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget}
+ * @class EventTarget
+ */
const EventTarget = function() {};
+/**
+ * A Custom DOM event.
+ *
+ * @typedef {Object} EventTarget~Event
+ * @see [Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
+ */
+
+/**
+ * All event listeners should follow the following format.
+ *
+ * @callback EventTarget~EventListener
+ * @this {EventTarget}
+ *
+ * @param {EventTarget~Event} event
+ * the event that triggered this function
+ *
+ * @param {Object} [hash]
+ * hash of data sent during the event
+ */
+
+/**
+ * An object containing event names as keys and booleans as values.
+ *
+ * > NOTE: If an event name is set to a true value here {@link EventTarget#trigger}
+ * will have extra functionality. See that function for more information.
+ *
+ * @property EventTarget.prototype.allowedEvents_
+ * @private
+ */
EventTarget.prototype.allowedEvents_ = {};
+/**
+ * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a
+ * function that will get called when an event with a certain name gets triggered.
+ *
+ * ```js
+ * var foo = new EventTarget();
+ * var handleBar = function() {
+ * console.log('bar was triggered');
+ * };
+ *
+ * foo.on('bar', handleBar);
+ *
+ * // This causes any `event listeners` for the `bar` event to get called
+ * // see {@link EventTarget#trigger} for more information
+ * foo.trigger('bar');
+ * // logs 'bar was triggered'
+ * ```
+ *
+ * @param {string|string[]} type
+ * An event name or an array of event names.
+ *
+ * @param {EventTarget~EventListener} fn
+ * The function to call with `EventTarget`s
+ */
EventTarget.prototype.on = function(type, fn) {
// Remove the addEventListener alias before calling Events.on
// so we don't get into an infinite type loop
@@ -17,16 +78,105 @@ EventTarget.prototype.on = function(type, fn) {
this.addEventListener = ael;
};
+/**
+ * An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic
+ * the standard DOM API.
+ *
+ * @function
+ * @see {@link EventTarget#on}
+ */
EventTarget.prototype.addEventListener = EventTarget.prototype.on;
+/**
+ * Removes an `event listener` for a specific event from an instance of `EventTarget`.
+ * This makes it so that the `event listener` will no longer get called when the
+ * named event happens.
+ *
+ * ```js
+ * var foo = new EventTarget();
+ * var handleBar = function() {
+ * console.log('bar was triggered');
+ * };
+ *
+ * // adds an `event listener` for the `bar` event
+ * // see {@link EventTarget#on} for more info
+ * foo.on('bar', handleBar);
+ *
+ * // runs all `event listeners` for the `bar` event
+ * // see {@link EventTarget#trigger} for more info
+ * foo.trigger('bar');
+ * // logs 'bar was triggered'
+ *
+ * foo.off('bar', handleBar);
+ * foo.trigger('bar');
+ * // does nothing
+ * ```
+ *
+ * @param {string|string[]} type
+ * An event name or an array of event names.
+ *
+ * @param {EventTarget~EventListener} fn
+ * The function to remove.
+ */
EventTarget.prototype.off = function(type, fn) {
Events.off(this, type, fn);
};
+/**
+ * An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic
+ * the standard DOM API.
+ *
+ * @function
+ * @see {@link EventTarget#off}
+ */
EventTarget.prototype.removeEventListener = EventTarget.prototype.off;
+/**
+ * This function will add an `event listener` that gets triggered only once. After the
+ * first trigger it will get removed. This is like adding an `event listener`
+ * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself.
+ *
+ * Using {@link EventTarget#on} and {@link EventTarget#off} to mimic {@link EventTarget#one}
+ * ```js
+ * var foo = new EventTarget();
+ * var handleBar = function() {
+ * console.log('bar was triggered');
+ * // after the first trigger remove this handler
+ * foo.off('bar', handleBar);
+ * };
+ *
+ * foo.on('bar', handleBar);
+ * foo.trigger('bar');
+ * // logs 'bar was triggered'
+ *
+ * foo.trigger('bar');
+ * // does nothing
+ * ```
+ *
+ * Using {@link EventTarget#one}
+ * ```js
+ * var foo = new EventTarget();
+ * var handleBar = function() {
+ * console.log('bar was triggered');
+ * };
+ *
+ * // removed after the first trigger
+ * foo.one('bar', handleBar);
+ * foo.trigger('bar');
+ * // logs 'bar was triggered'
+ *
+ * foo.trigger('bar');
+ * // does nothing
+ * ```
+ *
+ * @param {string|string[]} type
+ * An event name or an array of event names.
+ *
+ * @param {EventTarget~EventListener} fn
+ * The function to be called once for each event name.
+ */
EventTarget.prototype.one = function(type, fn) {
- // Remove the addEventListener alias before calling Events.on
+ // Remove the addEventListener alialing Events.on
// so we don't get into an infinite type loop
const ael = this.addEventListener;
@@ -35,6 +185,39 @@ EventTarget.prototype.one = function(type, fn) {
this.addEventListener = ael;
};
+/**
+ * This function causes an event to happen. This will then cause any `event listeners`
+ * that are waiting for that event, to get called. If there are no `event listeners`
+ * for an event then nothing will happen.
+ *
+ * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`.
+ * Trigger will also call the `on` + `uppercaseEventName` function.
+ *
+ * Example:
+ * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call
+ * `onClick` if it exists.
+ *
+ * ```js
+ * var foo = new EventTarget();
+ * var handleBar = function() {
+ * console.log('bar was triggered');
+ * };
+ *
+ * foo.on('bar', handleBar);
+ * foo.trigger('bar');
+ * // logs 'bar was triggered'
+ *
+ * foo.trigger('bar');
+ * // logs 'bar was triggered'
+ *
+ * foo.trigger('foo');
+ * // does nothing
+ * ```
+ *
+ * @param {string|EventTarget~Event|Object} event
+ * The name of the event, an `Event`, or an object with a key of type set to
+ * an event name.
+ */
EventTarget.prototype.trigger = function(event) {
const type = event.type || event;
@@ -50,7 +233,13 @@ EventTarget.prototype.trigger = function(event) {
Events.trigger(this, event);
};
-// The standard DOM EventTarget.dispatchEvent() is aliased to trigger()
+/**
+ * An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic
+ * the standard DOM API.
+ *
+ * @function
+ * @see {@link EventTarget#trigger}
+ */
EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;
export default EventTarget;