diff --git a/.jshintrc b/.jshintrc
deleted file mode 100644
index 826ec9ffb2..0000000000
--- a/.jshintrc
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "evil" : true,
- "validthis": true,
- "node" : true,
- "debug" : true,
- "boss" : true,
- "expr" : true,
- "eqnull" : true,
- "quotmark" : "single",
- "sub" : true,
- "trailing" : true,
- "undef" : true,
- "laxbreak" : true,
- "esnext" : true,
- "eqeqeq" : true,
- "predef" : [
- "_V_",
- "goog",
- "console",
-
- "require",
- "define",
- "module",
- "exports",
- "process",
-
- "q",
- "asyncTest",
- "deepEqual",
- "equal",
- "expect",
- "module",
- "notDeepEqual",
- "notEqual",
- "notStrictEqual",
- "ok",
- "throws",
- "QUnit",
- "raises",
- "start",
- "stop",
- "strictEqual",
- "test",
- "throws",
- "sinon"
- ]
-}
diff --git a/build/grunt.js b/build/grunt.js
index 379a815ac2..7372c7530b 100644
--- a/build/grunt.js
+++ b/build/grunt.js
@@ -114,14 +114,6 @@ module.exports = function(grunt) {
build: ['build/temp/*'],
dist: ['dist/*']
},
- jshint: {
- src: {
- src: ['src/js/**/*.js', 'Gruntfile.js', 'test/unit/**/*.js'],
- options: {
- jshintrc: '.jshintrc'
- }
- }
- },
uglify: {
options: {
sourceMap: true,
@@ -160,10 +152,6 @@ module.exports = function(grunt) {
skin: {
files: ['src/css/**/*'],
tasks: ['sass']
- },
- jshint: {
- files: ['src/**/*', 'test/unit/**/*.js', 'Gruntfile.js'],
- tasks: 'jshint'
}
},
connect: {
@@ -443,6 +431,14 @@ module.exports = function(grunt) {
src: ['build/temp/video.js']
}
}
+ },
+ shell: {
+ lint: {
+ command: 'vjsstandard',
+ options: {
+ preferLocal: true
+ }
+ }
}
});
@@ -455,7 +451,6 @@ module.exports = function(grunt) {
const buildDependents = [
'clean:build',
- 'jshint',
'browserify:build',
'exorcise:build',
'concat:novtt',
diff --git a/package.json b/package.json
index 892c4090cf..522f631712 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
"homepage": "http://videojs.com",
"author": "Steve Heffernan",
"scripts": {
+ "lint": "vjsstandard",
"test": "grunt test"
},
"repository": {
@@ -45,6 +46,7 @@
"css": "^2.2.0",
"es5-shim": "^4.1.3",
"es6-shim": "^0.35.1",
+ "ghooks": "^1.3.2",
"gkatsev-grunt-sass": "^1.1.1",
"grunt": "^0.4.4",
"grunt-aws-s3": "^0.12.1",
@@ -57,7 +59,6 @@
"grunt-contrib-connect": "~0.7.1",
"grunt-contrib-copy": "^0.8.0",
"grunt-contrib-cssmin": "~0.6.0",
- "grunt-contrib-jshint": "~0.11.3",
"grunt-contrib-less": "~0.6.4",
"grunt-contrib-uglify": "^0.8.0",
"grunt-contrib-watch": "~0.1.4",
@@ -66,6 +67,7 @@
"grunt-fastly": "^0.1.3",
"grunt-github-releaser": "^0.1.17",
"grunt-karma": "^0.8.3",
+ "grunt-shell": "^1.3.0",
"grunt-version": "~0.3.0",
"grunt-videojs-languages": "0.0.4",
"grunt-zip": "0.10.2",
@@ -87,9 +89,10 @@
"sinon": "^1.16.1",
"time-grunt": "^1.1.1",
"uglify-js": "~2.3.6",
- "videojs-doc-generator": "0.0.1"
+ "videojs-doc-generator": "0.0.1",
+ "videojs-standard": "^5.0.0"
},
- "standard": {
+ "vjsstandard": {
"ignore": [
"**/Gruntfile.js",
"**/build/**",
@@ -97,7 +100,14 @@
"**/docs/**",
"**/lang/**",
"**/sandbox/**",
- "**/test/**"
+ "**/test/api/**",
+ "**/test/coverage/**",
+ "**/test/karma.conf.js"
]
+ },
+ "config": {
+ "ghooks": {
+ "pre-push": "npm run lint"
+ }
}
}
diff --git a/src/js/base-styles.js b/src/js/base-styles.js
index be6e302393..cd6ff7a128 100644
--- a/src/js/base-styles.js
+++ b/src/js/base-styles.js
@@ -6,13 +6,17 @@
import window from 'global/window';
import document from 'global/document';
-if (window.VIDEOJS_NO_BASE_THEME) return;
+if (window.VIDEOJS_NO_BASE_THEME) {
+ return;
+}
const styles = '{{GENERATED_STYLES}}';
-if (styles === '{{GENERATED'+'_STYLES}}');
+// Don't think we need this as it's a noop?
+// if (styles === '{{GENERATED'+'_STYLES}}');
const styleNode = document.createElement('style');
+
styleNode.innerHTML = styles;
document.head.insertBefore(styleNode, document.head.firstChild);
diff --git a/src/js/button.js b/src/js/button.js
index 54067cc02c..5583d9541a 100644
--- a/src/js/button.js
+++ b/src/js/button.js
@@ -3,10 +3,7 @@
*/
import ClickableComponent from './clickable-component.js';
import Component from './component';
-import * as Events from './utils/events.js';
-import * as Fn from './utils/fn.js';
import log from './utils/log.js';
-import document from 'global/document';
import assign from 'object.assign';
/**
@@ -32,7 +29,7 @@ class Button extends ClickableComponent {
* @return {Element}
* @method createEl
*/
- createEl(tag='button', props={}, attributes={}) {
+ createEl(tag = 'button', props = {}, attributes = {}) {
props = assign({
className: this.buildCSSClass()
}, props);
@@ -53,11 +50,15 @@ class Button extends ClickableComponent {
// Add attributes for button element
attributes = assign({
- type: 'button', // Necessary since the default button type is "submit"
- 'aria-live': 'polite' // let the screen reader user know that the text of the button may change
+
+ // Necessary since the default button type is "submit"
+ 'type': 'button',
+
+ // let the screen reader user know that the text of the button may change
+ 'aria-live': 'polite'
}, attributes);
- let el = Component.prototype.createEl.call(this, tag, props, attributes);
+ const el = Component.prototype.createEl.call(this, tag, props, attributes);
this.createControlTextEl(el);
@@ -73,8 +74,9 @@ class Button extends ClickableComponent {
* @deprecated
* @method addChild
*/
- addChild(child, options={}) {
- let className = this.constructor.name;
+ addChild(child, options = {}) {
+ const className = this.constructor.name;
+
log.warn(`Adding an actionable (user controllable) child to a Button (${className}) is not supported; use a ClickableComponent instead.`);
// Avoid the error message generated by ClickableComponent's addChild method
@@ -87,13 +89,15 @@ class Button extends ClickableComponent {
* @method handleKeyPress
*/
handleKeyPress(event) {
+
// Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button.
if (event.which === 32 || event.which === 13) {
- } else {
- super.handleKeyPress(event); // Pass keypress handling up for unsupported keys
+ return;
}
- }
+ // Pass keypress handling up for unsupported keys
+ super.handleKeyPress(event);
+ }
}
Component.registerComponent('Button', Button);
diff --git a/src/js/clickable-component.js b/src/js/clickable-component.js
index 2861b3a228..4b4c830165 100644
--- a/src/js/clickable-component.js
+++ b/src/js/clickable-component.js
@@ -39,7 +39,7 @@ class ClickableComponent extends Component {
* @return {Element}
* @method createEl
*/
- createEl(tag='div', props={}, attributes={}) {
+ createEl(tag = 'div', props = {}, attributes = {}) {
props = assign({
className: this.buildCSSClass(),
tabIndex: 0
@@ -51,11 +51,13 @@ class ClickableComponent extends Component {
// Add ARIA attributes for clickable element which is not a native HTML button
attributes = assign({
- role: 'button',
- 'aria-live': 'polite' // let the screen reader user know that the text of the element may change
+ 'role': 'button',
+
+ // let the screen reader user know that the text of the element may change
+ 'aria-live': 'polite'
}, attributes);
- let el = super.createEl(tag, props, attributes);
+ const el = super.createEl(tag, props, attributes);
this.createControlTextEl(el);
@@ -91,9 +93,11 @@ class ClickableComponent extends Component {
* @return {String}
* @method controlText
*/
- controlText(text, el=this.el()) {
- if (!text) return this.controlText_ || 'Need Text';
-
+ controlText(text, el = this.el()) {
+ if (!text) {
+ return this.controlText_ || 'Need Text';
+ }
+
const localizedText = this.localize(text);
this.controlText_ = text;
@@ -121,14 +125,14 @@ class ClickableComponent extends Component {
* @return {Component} The child component (created by this process if a string was used)
* @method addChild
*/
- addChild(child, options={}) {
+ addChild(child, options = {}) {
// TODO: Fix adding an actionable child to a ClickableComponent; currently
// it will cause issues with assistive technology (e.g. screen readers)
// which support ARIA, since an element with role="button" cannot have
// actionable child elements.
- //let className = this.constructor.name;
- //log.warn(`Adding a child to a ClickableComponent (${className}) can cause issues with assistive technology which supports ARIA, since an element with role="button" cannot have actionable child elements.`);
+ // let className = this.constructor.name;
+ // log.warn(`Adding a child to a ClickableComponent (${className}) can cause issues with assistive technology which supports ARIA, since an element with role="button" cannot have actionable child elements.`);
return super.addChild(child, options);
}
@@ -179,12 +183,15 @@ class ClickableComponent extends Component {
* @method handleKeyPress
*/
handleKeyPress(event) {
+
// Support Space (32) or Enter (13) key operation to fire a click event
if (event.which === 32 || event.which === 13) {
event.preventDefault();
this.handleClick(event);
} else if (super.handleKeyPress) {
- super.handleKeyPress(event); // Pass keypress handling up for unsupported keys
+
+ // Pass keypress handling up for unsupported keys
+ super.handleKeyPress(event);
}
}
diff --git a/src/js/component.js b/src/js/component.js
index 9ef9d0caf3..3e1362b34d 100644
--- a/src/js/component.js
+++ b/src/js/component.js
@@ -3,7 +3,6 @@
*
* Player Component - Base class for all UI objects
*/
-
import window from 'global/window';
import * as Dom from './utils/dom.js';
import * as Fn from './utils/fn.js';
@@ -14,7 +13,6 @@ import toTitleCase from './utils/to-title-case.js';
import assign from 'object.assign';
import mergeOptions from './utils/merge-options.js';
-
/**
* Base UI Component class
* Components are embeddable UI objects that are represented by both a
@@ -32,7 +30,7 @@ import mergeOptions from './utils/merge-options.js';
* ```
* Components are also event targets.
* ```js
- * button.on('click', function(){
+ * button.on('click', function() {
* console.log('Button Clicked!');
* });
* button.trigger('customevent');
@@ -66,7 +64,7 @@ class Component {
// If there was no ID from the options, generate one
if (!this.id_) {
// Don't require the player ID function in the case of mock players
- let id = player && player.id && player.id() || 'no_player';
+ const id = player && player.id && player.id() || 'no_player';
this.id_ = `${id}_component_${Guid.newGUID()}`;
}
@@ -219,21 +217,21 @@ class Component {
}
localize(string) {
- let code = this.player_.language && this.player_.language();
- let languages = this.player_.languages && this.player_.languages();
+ const code = this.player_.language && this.player_.language();
+ const languages = this.player_.languages && this.player_.languages();
if (!code || !languages) {
return string;
}
- let language = languages[code];
+ const language = languages[code];
if (language && language[string]) {
return language[string];
}
- let primaryCode = code.split('-')[0];
- let primaryLang = languages[primaryCode];
+ const primaryCode = code.split('-')[0];
+ const primaryLang = languages[primaryCode];
if (primaryLang && primaryLang[string]) {
return primaryLang[string];
@@ -340,7 +338,7 @@ class Component {
* @return {Component} The child component (created by this process if a string was used)
* @method addChild
*/
- addChild(child, options={}, index=this.children_.length) {
+ addChild(child, options = {}, index = this.children_.length) {
let component;
let componentName;
@@ -361,14 +359,14 @@ class Component {
// If no componentClass in options, assume componentClass is the name lowercased
// (e.g. playButton)
- let componentClassName = options.componentClass || toTitleCase(componentName);
+ const componentClassName = options.componentClass || toTitleCase(componentName);
// Set name through options
options.name = componentName;
// Create a new object & element for this controls set
// If there's no .player_, this is a player
- let ComponentClass = Component.getComponent(componentClassName);
+ const ComponentClass = Component.getComponent(componentClassName);
if (!ComponentClass) {
throw new Error(`Component ${componentClassName} does not exist`);
@@ -406,8 +404,9 @@ class Component {
// Add the UI object's element to the container div (box)
// Having an element is not required
if (typeof component.el === 'function' && component.el()) {
- let childNodes = this.contentEl().children;
- let refNode = childNodes[index] || null;
+ const childNodes = this.contentEl().children;
+ const refNode = childNodes[index] || null;
+
this.contentEl().insertBefore(component.el(), refNode);
}
@@ -448,7 +447,7 @@ class Component {
this.childIndex_[component.id()] = null;
this.childNameIndex_[component.name()] = null;
- let compEl = component.el();
+ const compEl = component.el();
if (compEl && compEl.parentNode === this.contentEl()) {
this.contentEl().removeChild(component.el());
@@ -502,14 +501,14 @@ class Component {
* @method initChildren
*/
initChildren() {
- let children = this.options_.children;
+ const children = this.options_.children;
if (children) {
// `this` is `parent`
- let parentOptions = this.options_;
+ const parentOptions = this.options_;
- let handleAdd = (child) => {
- let name = child.name;
+ const handleAdd = (child) => {
+ const name = child.name;
let opts = child.opts;
// Allow options for children to be set at the parent options
@@ -539,7 +538,8 @@ class Component {
// Add a direct reference to the child by name on the parent instance.
// If two of the same component are used, different names should be supplied
// for each
- let newChild = this.addChild(name, opts);
+ const newChild = this.addChild(name, opts);
+
if (newChild) {
this[name] = newChild;
}
@@ -547,7 +547,7 @@ class Component {
// Allow for an array of children details to passed in the options
let workingChildren;
- let Tech = Component.getComponent('Tech');
+ const Tech = Component.getComponent('Tech');
if (Array.isArray(children)) {
workingChildren = children;
@@ -563,13 +563,13 @@ class Component {
return !workingChildren.some(function(wchild) {
if (typeof wchild === 'string') {
return child === wchild;
- } else {
- return child === wchild.name;
}
+ return child === wchild.name;
});
}))
.map((child) => {
- let name, opts;
+ let name;
+ let opts;
if (typeof child === 'string') {
name = child;
@@ -585,8 +585,9 @@ class Component {
// we have to make sure that child.name isn't in the techOrder since
// techs are registerd as Components but can't aren't compatible
// See https://github.com/videojs/video.js/issues/2772
- let c = Component.getComponent(child.opts.componentClass ||
+ const c = Component.getComponent(child.opts.componentClass ||
toTitleCase(child.name));
+
return c && !Tech.isTech(c);
})
.forEach(handleAdd);
@@ -608,7 +609,7 @@ class Component {
/**
* Add an event listener to this component's element
* ```js
- * var myFunc = function(){
+ * var myFunc = function() {
* var myComponent = this;
* // Do something when the event is fired
* };
@@ -797,7 +798,7 @@ class Component {
* @return {Component}
* @method ready
*/
- ready(fn, sync=false) {
+ ready(fn, sync = false) {
if (fn) {
if (this.isReady_) {
if (sync) {
@@ -824,14 +825,14 @@ class Component {
this.isReady_ = true;
// Ensure ready is triggerd asynchronously
- this.setTimeout(function(){
- let readyQueue = this.readyQueue_;
+ this.setTimeout(function() {
+ const readyQueue = this.readyQueue_;
// Reset Ready Queue
this.readyQueue_ = [];
if (readyQueue && readyQueue.length > 0) {
- readyQueue.forEach(function(fn){
+ readyQueue.forEach(function(fn) {
fn.call(this);
}, this);
}
@@ -1077,8 +1078,8 @@ class Component {
}
// Get dimension value from style
- let val = this.el_.style[widthOrHeight];
- let pxIndex = val.indexOf('px');
+ const val = this.el_.style[widthOrHeight];
+ const pxIndex = val.indexOf('px');
if (pxIndex !== -1) {
// Return the pixel value with no 'px'
@@ -1106,11 +1107,13 @@ class Component {
if (typeof window.getComputedStyle === 'function') {
const computedStyle = window.getComputedStyle(this.el_);
+
computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight];
} else if (this.el_.currentStyle) {
// ie 8 doesn't support computed style, shim it
// return clientWidth or clientHeight instead for better accuracy
const rule = `offset${toTitleCase(widthOrHeight)}`;
+
computedWidthOrHeight = this.el_[rule];
}
@@ -1194,7 +1197,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;
@@ -1297,7 +1300,7 @@ class Component {
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.
- let timeoutId = window.setTimeout(fn, timeout);
+ const timeoutId = window.setTimeout(fn, timeout);
const disposeFn = function() {
this.clearTimeout(timeoutId);
@@ -1340,7 +1343,7 @@ class Component {
setInterval(fn, interval) {
fn = Fn.bind(this, fn);
- let intervalId = window.setInterval(fn, interval);
+ const intervalId = window.setInterval(fn, interval);
const disposeFn = function() {
this.clearInterval(intervalId);
@@ -1425,7 +1428,7 @@ class Component {
// 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
- let 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);`
@@ -1435,7 +1438,7 @@ class Component {
// `ParentObject.prototype.init.apply(this, arguments);`
// Bleh. We're not creating a _super() function, so it's good to keep
// the parent constructor reference simple.
- let subObj = function() {
+ const subObj = function() {
init.apply(this, arguments);
};
@@ -1449,7 +1452,7 @@ class Component {
subObj.extend = Component.extend;
// Extend subObj's prototype with functions and other properties from props
- for (let name in props) {
+ for (const name in props) {
if (props.hasOwnProperty(name)) {
subObj.prototype[name] = props[name];
}
diff --git a/src/js/control-bar/audio-track-controls/audio-track-button.js b/src/js/control-bar/audio-track-controls/audio-track-button.js
index b4f7d5575a..3b84c3db6b 100644
--- a/src/js/control-bar/audio-track-controls/audio-track-button.js
+++ b/src/js/control-bar/audio-track-controls/audio-track-button.js
@@ -3,7 +3,6 @@
*/
import TrackButton from '../track-button.js';
import Component from '../../component.js';
-import * as Fn from '../../utils/fn.js';
import AudioTrackMenuItem from './audio-track-menu-item.js';
/**
@@ -40,19 +39,19 @@ class AudioTrackButton extends TrackButton {
* @method createItems
*/
createItems(items = []) {
- let tracks = this.player_.audioTracks && this.player_.audioTracks();
+ const tracks = this.player_.audioTracks && this.player_.audioTracks();
if (!tracks) {
return items;
}
for (let i = 0; i < tracks.length; i++) {
- let track = tracks[i];
+ const track = tracks[i];
items.push(new AudioTrackMenuItem(this.player_, {
+ track,
// MenuItem is selectable
- 'selectable': true,
- 'track': track
+ selectable: true
}));
}
diff --git a/src/js/control-bar/audio-track-controls/audio-track-menu-item.js b/src/js/control-bar/audio-track-controls/audio-track-menu-item.js
index fcaf428a43..b97f44a22f 100644
--- a/src/js/control-bar/audio-track-controls/audio-track-menu-item.js
+++ b/src/js/control-bar/audio-track-controls/audio-track-menu-item.js
@@ -15,8 +15,8 @@ import * as Fn from '../../utils/fn.js';
*/
class AudioTrackMenuItem extends MenuItem {
constructor(player, options) {
- let track = options.track;
- let tracks = player.audioTracks();
+ const track = options.track;
+ const tracks = player.audioTracks();
// Modify options for parent MenuItem class's init.
options.label = track.label || track.language || 'Unknown';
@@ -27,7 +27,7 @@ class AudioTrackMenuItem extends MenuItem {
this.track = track;
if (tracks) {
- let changeHandler = Fn.bind(this, this.handleTracksChange);
+ const changeHandler = Fn.bind(this, this.handleTracksChange);
tracks.addEventListener('change', changeHandler);
this.on('dispose', () => {
@@ -42,14 +42,16 @@ class AudioTrackMenuItem extends MenuItem {
* @method handleClick
*/
handleClick(event) {
- let tracks = this.player_.audioTracks();
+ const tracks = this.player_.audioTracks();
super.handleClick(event);
- if (!tracks) return;
+ if (!tracks) {
+ return;
+ }
for (let i = 0; i < tracks.length; i++) {
- let track = tracks[i];
+ const track = tracks[i];
if (track === this.track) {
track.enabled = true;
diff --git a/src/js/control-bar/control-bar.js b/src/js/control-bar/control-bar.js
index 1fbc82abd6..90d110f696 100644
--- a/src/js/control-bar/control-bar.js
+++ b/src/js/control-bar/control-bar.js
@@ -4,24 +4,24 @@
import Component from '../component.js';
// Required children
-import PlayToggle from './play-toggle.js';
-import CurrentTimeDisplay from './time-controls/current-time-display.js';
-import DurationDisplay from './time-controls/duration-display.js';
-import TimeDivider from './time-controls/time-divider.js';
-import RemainingTimeDisplay from './time-controls/remaining-time-display.js';
-import LiveDisplay from './live-display.js';
-import ProgressControl from './progress-control/progress-control.js';
-import FullscreenToggle from './fullscreen-toggle.js';
-import VolumeControl from './volume-control/volume-control.js';
-import VolumeMenuButton from './volume-menu-button.js';
-import MuteToggle from './mute-toggle.js';
-import ChaptersButton from './text-track-controls/chapters-button.js';
-import DescriptionsButton from './text-track-controls/descriptions-button.js';
-import SubtitlesButton from './text-track-controls/subtitles-button.js';
-import CaptionsButton from './text-track-controls/captions-button.js';
-import AudioTrackButton from './audio-track-controls/audio-track-button.js';
-import PlaybackRateMenuButton from './playback-rate-menu/playback-rate-menu-button.js';
-import CustomControlSpacer from './spacer-controls/custom-control-spacer.js';
+import './play-toggle.js';
+import './time-controls/current-time-display.js';
+import './time-controls/duration-display.js';
+import './time-controls/time-divider.js';
+import './time-controls/remaining-time-display.js';
+import './live-display.js';
+import './progress-control/progress-control.js';
+import './fullscreen-toggle.js';
+import './volume-control/volume-control.js';
+import './volume-menu-button.js';
+import './mute-toggle.js';
+import './text-track-controls/chapters-button.js';
+import './text-track-controls/descriptions-button.js';
+import './text-track-controls/subtitles-button.js';
+import './text-track-controls/captions-button.js';
+import './audio-track-controls/audio-track-button.js';
+import './playback-rate-menu/playback-rate-menu-button.js';
+import './spacer-controls/custom-control-spacer.js';
/**
* Container of main controls
@@ -42,7 +42,8 @@ class ControlBar extends Component {
className: 'vjs-control-bar',
dir: 'ltr'
}, {
- 'role': 'group' // The control bar is a group, so it can contain menuitems
+ // The control bar is a group, so it can contain menuitems
+ role: 'group'
});
}
}
diff --git a/src/js/control-bar/live-display.js b/src/js/control-bar/live-display.js
index 25fd01710b..017b5d0576 100644
--- a/src/js/control-bar/live-display.js
+++ b/src/js/control-bar/live-display.js
@@ -27,7 +27,7 @@ class LiveDisplay extends Component {
* @method createEl
*/
createEl() {
- var el = super.createEl('div', {
+ const 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 aa063ecc23..16adb66b1b 100644
--- a/src/js/control-bar/mute-toggle.js
+++ b/src/js/control-bar/mute-toggle.js
@@ -21,14 +21,15 @@ class MuteToggle extends Button {
this.on(player, 'volumechange', this.update);
// hide mute toggle if the current tech doesn't support volume control
- if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
+ if (player.tech_ && player.tech_.featuresVolumeControl === false) {
this.addClass('vjs-hidden');
}
this.on(player, 'loadstart', function() {
- this.update(); // We need to update the button to account for a default muted state.
+ // We need to update the button to account for a default muted state.
+ this.update();
- if (player.tech_['featuresVolumeControl'] === false) {
+ if (player.tech_.featuresVolumeControl === false) {
this.addClass('vjs-hidden');
} else {
this.removeClass('vjs-hidden');
@@ -52,7 +53,7 @@ class MuteToggle extends Button {
* @method handleClick
*/
handleClick() {
- this.player_.muted( this.player_.muted() ? false : true );
+ this.player_.muted(this.player_.muted() ? false : true);
}
/**
@@ -61,8 +62,8 @@ class MuteToggle extends Button {
* @method update
*/
update() {
- var vol = this.player_.volume(),
- level = 3;
+ const vol = this.player_.volume();
+ let level = 3;
if (vol === 0 || this.player_.muted()) {
level = 0;
@@ -75,13 +76,14 @@ class MuteToggle extends Button {
// Don't rewrite the button text if the actual text doesn't change.
// This causes unnecessary and confusing information for screen reader users.
// This check is needed because this function gets called every time the volume level is changed.
- let toMute = this.player_.muted() ? 'Unmute' : 'Mute';
+ const toMute = this.player_.muted() ? 'Unmute' : 'Mute';
+
if (this.controlText() !== toMute) {
this.controlText(toMute);
}
- /* TODO improve muted icon classes */
- for (var i = 0; i < 4; i++) {
+ // TODO improve muted icon classes
+ for (let i = 0; i < 4; i++) {
Dom.removeElClass(this.el_, `vjs-vol-${i}`);
}
Dom.addElClass(this.el_, `vjs-vol-${level}`);
diff --git a/src/js/control-bar/play-toggle.js b/src/js/control-bar/play-toggle.js
index 5849d7808a..3781d135d4 100644
--- a/src/js/control-bar/play-toggle.js
+++ b/src/js/control-bar/play-toggle.js
@@ -14,7 +14,7 @@ import Component from '../component.js';
*/
class PlayToggle extends Button {
- constructor(player, options){
+ constructor(player, options) {
super(player, options);
this.on(player, 'play', this.handlePlay);
@@ -52,7 +52,8 @@ class PlayToggle extends Button {
handlePlay() {
this.removeClass('vjs-paused');
this.addClass('vjs-playing');
- this.controlText('Pause'); // change the button text to "Pause"
+ // change the button text to "Pause"
+ this.controlText('Pause');
}
/**
@@ -63,7 +64,8 @@ class PlayToggle extends Button {
handlePause() {
this.removeClass('vjs-playing');
this.addClass('vjs-paused');
- this.controlText('Play'); // change the button text to "Play"
+ // change the button text to "Play"
+ this.controlText('Play');
}
}
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 342c0aec16..993e94fdf2 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
@@ -17,7 +17,7 @@ import * as Dom from '../../utils/dom.js';
*/
class PlaybackRateMenuButton extends MenuButton {
- constructor(player, options){
+ constructor(player, options) {
super(player, options);
this.updateVisibility();
@@ -34,7 +34,7 @@ class PlaybackRateMenuButton extends MenuButton {
* @method createEl
*/
createEl() {
- let el = super.createEl();
+ const el = super.createEl();
this.labelEl_ = Dom.createEl('div', {
className: 'vjs-playback-rate-value',
@@ -63,13 +63,13 @@ class PlaybackRateMenuButton extends MenuButton {
* @method createMenu
*/
createMenu() {
- let menu = new Menu(this.player());
- let rates = this.playbackRates();
+ const menu = new Menu(this.player());
+ const rates = this.playbackRates();
if (rates) {
for (let i = rates.length - 1; i >= 0; i--) {
menu.addChild(
- new PlaybackRateMenuItem(this.player(), { 'rate': rates[i] + 'x'})
+ new PlaybackRateMenuItem(this.player(), {rate: rates[i] + 'x'})
);
}
}
@@ -94,12 +94,13 @@ class PlaybackRateMenuButton extends MenuButton {
*/
handleClick() {
// select next rate option
- let currentRate = this.player().playbackRate();
- let rates = this.playbackRates();
+ const currentRate = this.player().playbackRate();
+ const rates = this.playbackRates();
// this will select first one if the last one currently selected
let newRate = rates[0];
- for (let i = 0; i < rates.length ; i++) {
+
+ for (let i = 0; i < rates.length; i++) {
if (rates[i] > currentRate) {
newRate = rates[i];
break;
@@ -115,7 +116,7 @@ class PlaybackRateMenuButton extends MenuButton {
* @method playbackRates
*/
playbackRates() {
- return this.options_['playbackRates'] || (this.options_.playerOptions && this.options_.playerOptions['playbackRates']);
+ return this.options_.playbackRates || (this.options_.playerOptions && this.options_.playerOptions.playbackRates);
}
/**
@@ -126,10 +127,10 @@ class PlaybackRateMenuButton extends MenuButton {
* @method playbackRateSupported
*/
playbackRateSupported() {
- return this.player().tech_
- && this.player().tech_['featuresPlaybackRate']
- && this.playbackRates()
- && this.playbackRates().length > 0
+ return this.player().tech_ &&
+ this.player().tech_.featuresPlaybackRate &&
+ this.playbackRates() &&
+ this.playbackRates().length > 0
;
}
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 614d8c1cdb..6ec35dac4f 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
@@ -14,13 +14,13 @@ import Component from '../../component.js';
*/
class PlaybackRateMenuItem extends MenuItem {
- constructor(player, options){
- let label = options['rate'];
- let rate = parseFloat(label, 10);
+ constructor(player, options) {
+ const label = options.rate;
+ const rate = parseFloat(label, 10);
// Modify options for parent MenuItem class's init.
- options['label'] = label;
- options['selected'] = rate === 1;
+ options.label = label;
+ options.selected = rate === 1;
super(player, options);
this.label = label;
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 ec20e8afff..2e1a8aae1c 100644
--- a/src/js/control-bar/progress-control/load-progress-bar.js
+++ b/src/js/control-bar/progress-control/load-progress-bar.js
@@ -14,7 +14,7 @@ import * as Dom from '../../utils/dom.js';
*/
class LoadProgressBar extends Component {
- constructor(player, options){
+ constructor(player, options) {
super(player, options);
this.on(player, 'progress', this.update);
}
@@ -38,14 +38,16 @@ class LoadProgressBar extends Component {
* @method update
*/
update() {
- let buffered = this.player_.buffered();
- let duration = this.player_.duration();
- let bufferedEnd = this.player_.bufferedEnd();
- let children = this.el_.children;
+ const buffered = this.player_.buffered();
+ const duration = this.player_.duration();
+ const bufferedEnd = this.player_.bufferedEnd();
+ const children = this.el_.children;
// get the percent width of a time compared to the total end
- let percentify = function (time, end){
- let percent = (time / end) || 0; // no NaN
+ const percentify = function(time, end) {
+ // no NaN
+ const percent = (time / end) || 0;
+
return ((percent >= 1 ? 1 : percent) * 100) + '%';
};
@@ -54,8 +56,8 @@ class LoadProgressBar extends Component {
// add child elements to represent the individual buffered time ranges
for (let i = 0; i < buffered.length; i++) {
- let start = buffered.start(i);
- let end = buffered.end(i);
+ const start = buffered.start(i);
+ const end = buffered.end(i);
let part = children[i];
if (!part) {
@@ -69,7 +71,7 @@ class LoadProgressBar extends Component {
// remove unused buffered range elements
for (let i = children.length; i > buffered.length; i--) {
- this.el_.removeChild(children[i-1]);
+ this.el_.removeChild(children[i - 1]);
}
}
diff --git a/src/js/control-bar/progress-control/mouse-time-display.js b/src/js/control-bar/progress-control/mouse-time-display.js
index e59be2caa4..c72d132adf 100644
--- a/src/js/control-bar/progress-control/mouse-time-display.js
+++ b/src/js/control-bar/progress-control/mouse-time-display.js
@@ -55,24 +55,24 @@ class MouseTimeDisplay extends Component {
}
handleMouseMove(event) {
- let duration = this.player_.duration();
- let newTime = this.calculateDistance(event) * duration;
- let position = event.pageX - Dom.findElPosition(this.el().parentNode).left;
+ const duration = this.player_.duration();
+ const newTime = this.calculateDistance(event) * duration;
+ const position = event.pageX - Dom.findElPosition(this.el().parentNode).left;
this.update(newTime, position);
}
update(newTime, position) {
- let time = formatTime(newTime, this.player_.duration());
+ const time = formatTime(newTime, this.player_.duration());
this.el().style.left = position + 'px';
this.el().setAttribute('data-current-time', time);
if (this.keepTooltipsInside) {
- let clampedPosition = this.clampPosition_(position);
- let difference = position - clampedPosition + 1;
- let tooltipWidth = parseFloat(window.getComputedStyle(this.tooltip).width);
- let tooltipWidthHalf = tooltipWidth / 2;
+ const clampedPosition = this.clampPosition_(position);
+ const difference = position - clampedPosition + 1;
+ const tooltipWidth = parseFloat(window.getComputedStyle(this.tooltip).width);
+ const tooltipWidthHalf = tooltipWidth / 2;
this.tooltip.innerHTML = time;
this.tooltip.style.right = `-${tooltipWidthHalf - difference}px`;
@@ -98,9 +98,9 @@ class MouseTimeDisplay extends Component {
return position;
}
- let playerWidth = parseFloat(window.getComputedStyle(this.player().el()).width);
- let tooltipWidth = parseFloat(window.getComputedStyle(this.tooltip).width);
- let tooltipWidthHalf = tooltipWidth / 2;
+ const playerWidth = parseFloat(window.getComputedStyle(this.player().el()).width);
+ const tooltipWidth = parseFloat(window.getComputedStyle(this.tooltip).width);
+ const tooltipWidthHalf = tooltipWidth / 2;
let actualPosition = position;
if (position < tooltipWidthHalf) {
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 7ddea6cf45..5b29ba862a 100644
--- a/src/js/control-bar/progress-control/play-progress-bar.js
+++ b/src/js/control-bar/progress-control/play-progress-bar.js
@@ -3,7 +3,6 @@
*/
import Component from '../../component.js';
import * as Fn from '../../utils/fn.js';
-import * as Dom from '../../utils/dom.js';
import formatTime from '../../utils/format-time.js';
/**
@@ -16,7 +15,7 @@ import formatTime from '../../utils/format-time.js';
*/
class PlayProgressBar extends Component {
- constructor(player, options){
+ constructor(player, options) {
super(player, options);
this.updateDataAttr();
this.on(player, 'timeupdate', this.updateDataAttr);
@@ -48,7 +47,8 @@ class PlayProgressBar extends Component {
}
updateDataAttr() {
- let time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
+ const time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
+
this.el_.setAttribute('data-current-time', formatTime(time, this.player_.duration()));
}
diff --git a/src/js/control-bar/progress-control/progress-control.js b/src/js/control-bar/progress-control/progress-control.js
index 703989e4db..e142f42e3d 100644
--- a/src/js/control-bar/progress-control/progress-control.js
+++ b/src/js/control-bar/progress-control/progress-control.js
@@ -2,8 +2,9 @@
* @file progress-control.js
*/
import Component from '../../component.js';
-import SeekBar from './seek-bar.js';
-import MouseTimeDisplay from './mouse-time-display.js';
+
+import './seek-bar.js';
+import './mouse-time-display.js';
/**
* The Progress Control component contains the seek bar, load progress,
diff --git a/src/js/control-bar/progress-control/seek-bar.js b/src/js/control-bar/progress-control/seek-bar.js
index 21fdc15adb..8fa34694a6 100644
--- a/src/js/control-bar/progress-control/seek-bar.js
+++ b/src/js/control-bar/progress-control/seek-bar.js
@@ -4,12 +4,12 @@
import window from 'global/window';
import Slider from '../../slider/slider.js';
import Component from '../../component.js';
-import LoadProgressBar from './load-progress-bar.js';
-import PlayProgressBar from './play-progress-bar.js';
-import TooltipProgressBar from './tooltip-progress-bar.js';
import * as Fn from '../../utils/fn.js';
import formatTime from '../../utils/format-time.js';
-import assign from 'object.assign';
+
+import './load-progress-bar.js';
+import './play-progress-bar.js';
+import './tooltip-progress-bar.js';
/**
* Seek Bar and holder for the progress bars
@@ -21,7 +21,7 @@ import assign from 'object.assign';
*/
class SeekBar extends Slider {
- constructor(player, options){
+ constructor(player, options) {
super(player, options);
this.on(player, 'timeupdate', this.updateProgress);
this.on(player, 'ended', this.updateProgress);
@@ -65,9 +65,10 @@ class SeekBar extends Slider {
this.updateAriaAttributes(this.tooltipProgressBar.el_);
this.tooltipProgressBar.el_.style.width = this.bar.el_.style.width;
- let playerWidth = parseFloat(window.getComputedStyle(this.player().el()).width);
- let tooltipWidth = parseFloat(window.getComputedStyle(this.tooltipProgressBar.tooltip).width);
- let tooltipStyle = this.tooltipProgressBar.el().style;
+ const playerWidth = parseFloat(window.getComputedStyle(this.player().el()).width);
+ const tooltipWidth = parseFloat(window.getComputedStyle(this.tooltipProgressBar.tooltip).width);
+ const tooltipStyle = this.tooltipProgressBar.el().style;
+
tooltipStyle.maxWidth = Math.floor(playerWidth - (tooltipWidth / 2)) + 'px';
tooltipStyle.minWidth = Math.ceil(tooltipWidth / 2) + 'px';
tooltipStyle.right = `-${tooltipWidth / 2}px`;
@@ -76,9 +77,12 @@ class SeekBar extends Slider {
updateAriaAttributes(el) {
// Allows for smooth scrubbing, when player can't keep up.
- let time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
- el.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2)); // machine readable value of progress bar (percentage complete)
- el.setAttribute('aria-valuetext', formatTime(time, this.player_.duration())); // human readable value of progress bar (time complete)
+ const time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
+
+ // machine readable value of progress bar (percentage complete)
+ el.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2));
+ // human readable value of progress bar (time complete)
+ el.setAttribute('aria-valuetext', formatTime(time, this.player_.duration()));
}
/**
@@ -88,7 +92,8 @@ class SeekBar extends Slider {
* @method getPercent
*/
getPercent() {
- let percent = this.player_.currentTime() / this.player_.duration();
+ const percent = this.player_.currentTime() / this.player_.duration();
+
return percent >= 1 ? 1 : percent;
}
@@ -115,7 +120,9 @@ class SeekBar extends Slider {
let newTime = this.calculateDistance(event) * this.player_.duration();
// Don't let video end while scrubbing.
- if (newTime === this.player_.duration()) { newTime = newTime - 0.1; }
+ if (newTime === this.player_.duration()) {
+ newTime = newTime - 0.1;
+ }
// Set new time (tell player to seek to new time)
this.player_.currentTime(newTime);
@@ -141,7 +148,8 @@ class SeekBar extends Slider {
* @method stepForward
*/
stepForward() {
- this.player_.currentTime(this.player_.currentTime() + 5); // more quickly fast forward for keyboard-only users
+ // more quickly fast forward for keyboard-only users
+ this.player_.currentTime(this.player_.currentTime() + 5);
}
/**
@@ -150,7 +158,8 @@ class SeekBar extends Slider {
* @method stepBack
*/
stepBack() {
- this.player_.currentTime(this.player_.currentTime() - 5); // more quickly rewind for keyboard-only users
+ // more quickly rewind for keyboard-only users
+ this.player_.currentTime(this.player_.currentTime() - 5);
}
}
@@ -161,7 +170,7 @@ SeekBar.prototype.options_ = {
'mouseTimeDisplay',
'playProgressBar'
],
- 'barName': 'playProgressBar'
+ barName: 'playProgressBar'
};
SeekBar.prototype.playerEvent = 'timeupdate';
diff --git a/src/js/control-bar/progress-control/tooltip-progress-bar.js b/src/js/control-bar/progress-control/tooltip-progress-bar.js
index f1e092dad3..4a6db351ba 100644
--- a/src/js/control-bar/progress-control/tooltip-progress-bar.js
+++ b/src/js/control-bar/progress-control/tooltip-progress-bar.js
@@ -3,7 +3,6 @@
*/
import Component from '../../component.js';
import * as Fn from '../../utils/fn.js';
-import * as Dom from '../../utils/dom.js';
import formatTime from '../../utils/format-time.js';
/**
@@ -16,7 +15,7 @@ import formatTime from '../../utils/format-time.js';
*/
class TooltipProgressBar extends Component {
- constructor(player, options){
+ constructor(player, options) {
super(player, options);
this.updateDataAttr();
this.on(player, 'timeupdate', this.updateDataAttr);
@@ -30,7 +29,7 @@ class TooltipProgressBar extends Component {
* @method createEl
*/
createEl() {
- let el = super.createEl('div', {
+ const el = super.createEl('div', {
className: 'vjs-tooltip-progress-bar vjs-slider-bar',
innerHTML: `
${this.localize('Progress')}: 0%`
@@ -42,8 +41,9 @@ class TooltipProgressBar extends Component {
}
updateDataAttr() {
- let time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
- let formattedTime = formatTime(time, this.player_.duration());
+ const time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
+ const formattedTime = formatTime(time, this.player_.duration());
+
this.el_.setAttribute('data-current-time', formattedTime);
this.tooltip.innerHTML = formattedTime;
}
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 7327442b4a..a5c5a21f34 100644
--- a/src/js/control-bar/spacer-controls/custom-control-spacer.js
+++ b/src/js/control-bar/spacer-controls/custom-control-spacer.js
@@ -29,8 +29,8 @@ class CustomControlSpacer extends Spacer {
* @method createEl
*/
createEl() {
- let el = super.createEl({
- className: this.buildCSSClass(),
+ const el = super.createEl({
+ className: this.buildCSSClass()
});
// No-flex/table-cell mode requires there be some content
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 712543f20b..7632802cb8 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
@@ -12,24 +12,24 @@ import Component from '../../component.js';
* @extends TextTrackMenuItem
* @class CaptionSettingsMenuItem
*/
- class CaptionSettingsMenuItem extends TextTrackMenuItem {
+class CaptionSettingsMenuItem extends TextTrackMenuItem {
constructor(player, options) {
- options['track'] = {
- 'kind': options['kind'],
- 'player': player,
- 'label': options['kind'] + ' settings',
- 'selectable': false,
- 'default': false,
+ options.track = {
+ player,
+ kind: options.kind,
+ label: options.kind + ' settings',
+ selectable: false,
+ default: false,
mode: 'disabled'
};
// CaptionSettingsMenuItem has no concept of 'selected'
- options['selectable'] = false;
+ options.selectable = false;
super(player, options);
this.addClass('vjs-texttrack-settings');
- this.controlText(', opens ' + options['kind'] + ' settings dialog');
+ this.controlText(', opens ' + options.kind + ' settings dialog');
}
/**
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 b5ee37cfc9..929c841022 100644
--- a/src/js/control-bar/text-track-controls/captions-button.js
+++ b/src/js/control-bar/text-track-controls/captions-button.js
@@ -16,9 +16,9 @@ import CaptionSettingsMenuItem from './caption-settings-menu-item.js';
*/
class CaptionsButton extends TextTrackButton {
- constructor(player, options, ready){
+ constructor(player, options, ready) {
super(player, options, ready);
- this.el_.setAttribute('aria-label','Captions Menu');
+ this.el_.setAttribute('aria-label', 'Captions Menu');
}
/**
@@ -38,10 +38,11 @@ class CaptionsButton extends TextTrackButton {
*/
update() {
let threshold = 2;
+
super.update();
// if native, then threshold is 1 because no settings button
- if (this.player().tech_ && this.player().tech_['featuresNativeTextTracks']) {
+ if (this.player().tech_ && this.player().tech_.featuresNativeTextTracks) {
threshold = 1;
}
@@ -59,10 +60,10 @@ class CaptionsButton extends TextTrackButton {
* @method createItems
*/
createItems() {
- let items = [];
+ const items = [];
- if (!(this.player().tech_ && this.player().tech_['featuresNativeTextTracks'])) {
- items.push(new CaptionSettingsMenuItem(this.player_, { 'kind': this.kind_ }));
+ if (!(this.player().tech_ && this.player().tech_.featuresNativeTextTracks)) {
+ items.push(new CaptionSettingsMenuItem(this.player_, {kind: this.kind_}));
}
return super.createItems(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 0cc8606ea8..004be740d2 100644
--- a/src/js/control-bar/text-track-controls/chapters-button.js
+++ b/src/js/control-bar/text-track-controls/chapters-button.js
@@ -7,9 +7,7 @@ import TextTrackMenuItem from './text-track-menu-item.js';
import ChaptersTrackMenuItem from './chapters-track-menu-item.js';
import Menu from '../../menu/menu.js';
import * as Dom from '../../utils/dom.js';
-import * as Fn from '../../utils/fn.js';
import toTitleCase from '../../utils/to-title-case.js';
-import window from 'global/window';
/**
* The button component for toggling and selecting chapters
@@ -24,9 +22,9 @@ import window from 'global/window';
*/
class ChaptersButton extends TextTrackButton {
- constructor(player, options, ready){
+ constructor(player, options, ready) {
super(player, options, ready);
- this.el_.setAttribute('aria-label','Chapters Menu');
+ this.el_.setAttribute('aria-label', 'Chapters Menu');
}
/**
@@ -46,20 +44,18 @@ class ChaptersButton extends TextTrackButton {
* @method createItems
*/
createItems() {
- let items = [];
-
- let tracks = this.player_.textTracks();
+ const items = [];
+ const tracks = this.player_.textTracks();
if (!tracks) {
return items;
}
for (let i = 0; i < tracks.length; i++) {
- let track = tracks[i];
- if (track['kind'] === this.kind_) {
- items.push(new TextTrackMenuItem(this.player_, {
- 'track': track
- }));
+ const track = tracks[i];
+
+ if (track.kind === this.kind_) {
+ items.push(new TextTrackMenuItem(this.player_, {track}));
}
}
@@ -73,16 +69,16 @@ class ChaptersButton extends TextTrackButton {
* @method createMenu
*/
createMenu() {
- let tracks = this.player_.textTracks() || [];
+ const tracks = this.player_.textTracks() || [];
let chaptersTrack;
let items = this.items || [];
for (let i = tracks.length - 1; i >= 0; i--) {
// We will always choose the last track as our chaptersTrack
- let track = tracks[i];
+ const track = tracks[i];
- if (track['kind'] === this.kind_) {
+ if (track.kind === this.kind_) {
chaptersTrack = track;
break;
@@ -90,27 +86,30 @@ class ChaptersButton extends TextTrackButton {
}
let menu = this.menu;
+
if (menu === undefined) {
menu = new Menu(this.player_);
- let title = Dom.createEl('li', {
+
+ const title = Dom.createEl('li', {
className: 'vjs-menu-title',
innerHTML: toTitleCase(this.kind_),
tabIndex: -1
});
+
menu.children_.unshift(title);
Dom.insertElFirst(title, menu.contentEl());
} else {
- // We will empty out the menu children each time because we want a
- // fresh new menu child list each time
- items.forEach(item => menu.removeChild(item));
- // Empty out the ChaptersButton menu items because we no longer need them
- items = [];
+ // We will empty out the menu children each time because we want a
+ // fresh new menu child list each time
+ items.forEach(item => menu.removeChild(item));
+ // Empty out the ChaptersButton menu items because we no longer need them
+ items = [];
}
- if (chaptersTrack && chaptersTrack.cues == null) {
- chaptersTrack['mode'] = 'hidden';
+ if (chaptersTrack && (chaptersTrack.cues === null || chaptersTrack.cues === undefined)) {
+ chaptersTrack.mode = 'hidden';
- let remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(chaptersTrack);
+ const remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(chaptersTrack);
if (remoteTextTrackEl) {
remoteTextTrackEl.addEventListener('load', (event) => this.update());
@@ -118,14 +117,14 @@ class ChaptersButton extends TextTrackButton {
}
if (chaptersTrack && chaptersTrack.cues && chaptersTrack.cues.length > 0) {
- let cues = chaptersTrack['cues'], cue;
+ const cues = chaptersTrack.cues;
for (let i = 0, l = cues.length; i < l; i++) {
- cue = cues[i];
+ const cue = cues[i];
- let mi = new ChaptersTrackMenuItem(this.player_, {
- 'track': chaptersTrack,
- 'cue': cue
+ const mi = new ChaptersTrackMenuItem(this.player_, {
+ cue,
+ track: chaptersTrack
});
items.push(mi);
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 40b717a0e4..2291da4c30 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
@@ -15,14 +15,14 @@ import * as Fn from '../../utils/fn.js';
*/
class ChaptersTrackMenuItem extends MenuItem {
- constructor(player, options){
- let track = options['track'];
- let cue = options['cue'];
- let currentTime = player.currentTime();
+ constructor(player, options) {
+ const track = options.track;
+ const cue = options.cue;
+ const currentTime = player.currentTime();
// Modify options for parent MenuItem class's init.
- options['label'] = cue.text;
- options['selected'] = (cue['startTime'] <= currentTime && currentTime < cue['endTime']);
+ options.label = cue.text;
+ options.selected = (cue.startTime <= currentTime && currentTime < cue.endTime);
super(player, options);
this.track = track;
@@ -47,11 +47,11 @@ class ChaptersTrackMenuItem extends MenuItem {
* @method update
*/
update() {
- let cue = this.cue;
- let currentTime = this.player_.currentTime();
+ const cue = this.cue;
+ const currentTime = this.player_.currentTime();
// vjs.log(currentTime, cue.startTime);
- this.selected(cue['startTime'] <= currentTime && currentTime < cue['endTime']);
+ this.selected(cue.startTime <= currentTime && currentTime < cue.endTime);
}
}
diff --git a/src/js/control-bar/text-track-controls/descriptions-button.js b/src/js/control-bar/text-track-controls/descriptions-button.js
index 671c620c56..0b7bd02b45 100644
--- a/src/js/control-bar/text-track-controls/descriptions-button.js
+++ b/src/js/control-bar/text-track-controls/descriptions-button.js
@@ -16,14 +16,14 @@ import * as Fn from '../../utils/fn.js';
*/
class DescriptionsButton extends TextTrackButton {
- constructor(player, options, ready){
+ constructor(player, options, ready) {
super(player, options, ready);
this.el_.setAttribute('aria-label', 'Descriptions Menu');
- let tracks = player.textTracks();
+ const tracks = player.textTracks();
if (tracks) {
- let changeHandler = Fn.bind(this, this.handleTracksChange);
+ const changeHandler = Fn.bind(this, this.handleTracksChange);
tracks.addEventListener('change', changeHandler);
this.on('dispose', function() {
@@ -37,14 +37,15 @@ class DescriptionsButton extends TextTrackButton {
*
* @method handleTracksChange
*/
- handleTracksChange(event){
- let tracks = this.player().textTracks();
+ handleTracksChange(event) {
+ const tracks = this.player().textTracks();
let disabled = false;
// Check whether a track of a different kind is showing
for (let i = 0, l = tracks.length; i < l; i++) {
- let track = tracks[i];
- if (track['kind'] !== this.kind_ && track['mode'] === 'showing') {
+ const track = tracks[i];
+
+ if (track.kind !== this.kind_ && track.mode === 'showing') {
disabled = true;
break;
}
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 9cc124b9df..a23b82bd4d 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
@@ -14,19 +14,19 @@ import Component from '../../component.js';
*/
class OffTextTrackMenuItem extends TextTrackMenuItem {
- constructor(player, options){
+ constructor(player, options) {
// Create pseudo track info
// Requires options['kind']
- options['track'] = {
- 'kind': options['kind'],
- 'player': player,
- 'label': options['kind'] + ' off',
- 'default': false,
- 'mode': 'disabled'
+ options.track = {
+ player,
+ kind: options.kind,
+ label: options.kind + ' off',
+ default: false,
+ mode: 'disabled'
};
// MenuItem is selectable
- options['selectable'] = true;
+ options.selectable = true;
super(player, options);
this.selected(true);
@@ -38,13 +38,14 @@ class OffTextTrackMenuItem extends TextTrackMenuItem {
* @param {Object} event Event object
* @method handleTracksChange
*/
- handleTracksChange(event){
- let tracks = this.player().textTracks();
+ handleTracksChange(event) {
+ const tracks = this.player().textTracks();
let selected = true;
for (let i = 0, l = tracks.length; i < l; i++) {
- let track = tracks[i];
- if (track['kind'] === this.track['kind'] && track['mode'] === 'showing') {
+ const track = tracks[i];
+
+ if (track.kind === this.track.kind && track.mode === 'showing') {
selected = false;
break;
}
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 c56731496e..207e8179d2 100644
--- a/src/js/control-bar/text-track-controls/subtitles-button.js
+++ b/src/js/control-bar/text-track-controls/subtitles-button.js
@@ -15,9 +15,9 @@ import Component from '../../component.js';
*/
class SubtitlesButton extends TextTrackButton {
- constructor(player, options, ready){
+ constructor(player, options, ready) {
super(player, options, ready);
- this.el_.setAttribute('aria-label','Subtitles Menu');
+ this.el_.setAttribute('aria-label', 'Subtitles Menu');
}
/**
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 1decbeec24..fced8fb3ce 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
@@ -3,7 +3,6 @@
*/
import TrackButton from '../track-button.js';
import Component from '../../component.js';
-import * as Fn from '../../utils/fn.js';
import TextTrackMenuItem from './text-track-menu-item.js';
import OffTextTrackMenuItem from './off-text-track-menu-item.js';
@@ -17,7 +16,7 @@ import OffTextTrackMenuItem from './off-text-track-menu-item.js';
*/
class TextTrackButton extends TrackButton {
- constructor(player, options = {}){
+ constructor(player, options = {}) {
options.tracks = player.textTracks();
super(player, options);
@@ -29,25 +28,25 @@ class TextTrackButton extends TrackButton {
* @return {Array} Array of menu items
* @method createItems
*/
- createItems(items=[]) {
+ createItems(items = []) {
// Add an OFF menu item to turn all tracks off
- items.push(new OffTextTrackMenuItem(this.player_, { 'kind': this.kind_ }));
+ items.push(new OffTextTrackMenuItem(this.player_, {kind: this.kind_}));
- let tracks = this.player_.textTracks();
+ const tracks = this.player_.textTracks();
if (!tracks) {
return items;
}
for (let i = 0; i < tracks.length; i++) {
- let track = tracks[i];
+ const track = tracks[i];
// only add tracks that are of the appropriate kind and have a label
- if (track['kind'] === this.kind_) {
+ if (track.kind === this.kind_) {
items.push(new TextTrackMenuItem(this.player_, {
+ track,
// MenuItem is selectable
- 'selectable': true,
- 'track': track
+ selectable: true
}));
}
}
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 8b4c73bdad..ccb5b02010 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
@@ -17,20 +17,20 @@ import document from 'global/document';
*/
class TextTrackMenuItem extends MenuItem {
- constructor(player, options){
- let track = options['track'];
- let tracks = player.textTracks();
+ constructor(player, options) {
+ const track = options.track;
+ const tracks = player.textTracks();
// Modify options for parent MenuItem class's init.
- options['label'] = track['label'] || track['language'] || 'Unknown';
- options['selected'] = track['default'] || track['mode'] === 'showing';
+ options.label = track.label || track.language || 'Unknown';
+ options.selected = track.default || track.mode === 'showing';
super(player, options);
this.track = track;
if (tracks) {
- let changeHandler = Fn.bind(this, this.handleTracksChange);
+ const changeHandler = Fn.bind(this, this.handleTracksChange);
tracks.addEventListener('change', changeHandler);
this.on('dispose', function() {
@@ -52,7 +52,9 @@ class TextTrackMenuItem extends MenuItem {
// Android 2.3 throws an Illegal Constructor error for window.Event
try {
event = new window.Event('change');
- } catch(err){}
+ } catch (err) {
+ // continue regardless of error
+ }
}
if (!event) {
@@ -71,24 +73,26 @@ class TextTrackMenuItem extends MenuItem {
* @method handleClick
*/
handleClick(event) {
- let kind = this.track['kind'];
- let tracks = this.player_.textTracks();
+ const kind = this.track.kind;
+ const tracks = this.player_.textTracks();
super.handleClick(event);
- if (!tracks) return;
+ if (!tracks) {
+ return;
+ }
for (let i = 0; i < tracks.length; i++) {
- let track = tracks[i];
+ const track = tracks[i];
- if (track['kind'] !== kind) {
+ if (track.kind !== kind) {
continue;
}
if (track === this.track) {
- track['mode'] = 'showing';
+ track.mode = 'showing';
} else {
- track['mode'] = 'disabled';
+ track.mode = 'disabled';
}
}
}
@@ -98,8 +102,8 @@ class TextTrackMenuItem extends MenuItem {
*
* @method handleTracksChange
*/
- handleTracksChange(event){
- this.selected(this.track['mode'] === 'showing');
+ 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 ff99fc54e6..66a102aeea 100644
--- a/src/js/control-bar/time-controls/current-time-display.js
+++ b/src/js/control-bar/time-controls/current-time-display.js
@@ -15,7 +15,7 @@ import formatTime from '../../utils/format-time.js';
*/
class CurrentTimeDisplay extends Component {
- constructor(player, options){
+ constructor(player, options) {
super(player, options);
this.on(player, 'timeupdate', this.updateContent);
@@ -28,14 +28,14 @@ class CurrentTimeDisplay extends Component {
* @method createEl
*/
createEl() {
- let el = super.createEl('div', {
+ const el = super.createEl('div', {
className: 'vjs-current-time vjs-time-control vjs-control'
});
this.contentEl_ = Dom.createEl('div', {
className: 'vjs-current-time-display',
// label the current time for screen reader users
- innerHTML: 'Current Time ' + '0:00',
+ innerHTML: 'Current Time ' + '0:00'
}, {
// tell screen readers not to automatically read the time as it changes
'aria-live': 'off'
@@ -52,9 +52,10 @@ class CurrentTimeDisplay extends Component {
*/
updateContent() {
// Allows for smooth scrubbing, when player can't keep up.
- let time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
- let localizedText = this.localize('Current Time');
- let formattedTime = formatTime(time, this.player_.duration());
+ const time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
+ const localizedText = this.localize('Current Time');
+ const formattedTime = formatTime(time, this.player_.duration());
+
if (formattedTime !== this.formattedTime_) {
this.formattedTime_ = formattedTime;
this.contentEl_.innerHTML = `${localizedText} ${formattedTime}`;
diff --git a/src/js/control-bar/time-controls/duration-display.js b/src/js/control-bar/time-controls/duration-display.js
index 0496e3cd50..1b2cb27f50 100644
--- a/src/js/control-bar/time-controls/duration-display.js
+++ b/src/js/control-bar/time-controls/duration-display.js
@@ -15,7 +15,7 @@ import formatTime from '../../utils/format-time.js';
*/
class DurationDisplay extends Component {
- constructor(player, options){
+ constructor(player, options) {
super(player, options);
this.on(player, 'durationchange', this.updateContent);
@@ -28,7 +28,7 @@ class DurationDisplay extends Component {
* @method createEl
*/
createEl() {
- let el = super.createEl('div', {
+ const el = super.createEl('div', {
className: 'vjs-duration vjs-time-control vjs-control'
});
@@ -51,12 +51,15 @@ class DurationDisplay extends Component {
* @method updateContent
*/
updateContent() {
- let duration = this.player_.duration();
+ const duration = this.player_.duration();
+
if (duration && this.duration_ !== duration) {
this.duration_ = duration;
- let localizedText = this.localize('Duration Time');
- let formattedTime = formatTime(duration);
- this.contentEl_.innerHTML = `${localizedText} ${formattedTime}`; // label the duration time for screen reader users
+ const localizedText = this.localize('Duration Time');
+ const formattedTime = formatTime(duration);
+
+ // label the duration time for screen reader users
+ this.contentEl_.innerHTML = `${localizedText} ${formattedTime}`;
}
}
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 8ac701f6b1..40914b7cd1 100644
--- a/src/js/control-bar/time-controls/remaining-time-display.js
+++ b/src/js/control-bar/time-controls/remaining-time-display.js
@@ -15,7 +15,7 @@ import formatTime from '../../utils/format-time.js';
*/
class RemainingTimeDisplay extends Component {
- constructor(player, options){
+ constructor(player, options) {
super(player, options);
this.on(player, 'timeupdate', this.updateContent);
@@ -29,14 +29,14 @@ class RemainingTimeDisplay extends Component {
* @method createEl
*/
createEl() {
- let el = super.createEl('div', {
+ const el = super.createEl('div', {
className: 'vjs-remaining-time vjs-time-control vjs-control'
});
this.contentEl_ = Dom.createEl('div', {
className: 'vjs-remaining-time-display',
// label the remaining time for screen reader users
- innerHTML: `${this.localize('Remaining Time')} -0:00`,
+ innerHTML: `${this.localize('Remaining Time')} -0:00`
}, {
// tell screen readers not to automatically read the time as it changes
'aria-live': 'off'
@@ -55,6 +55,7 @@ class RemainingTimeDisplay extends Component {
if (this.player_.duration()) {
const localizedText = this.localize('Remaining Time');
const formattedTime = formatTime(this.player_.remainingTime());
+
if (formattedTime !== this.formattedTime_) {
this.formattedTime_ = formattedTime;
this.contentEl_.innerHTML = `${localizedText} -${formattedTime}`;
diff --git a/src/js/control-bar/track-button.js b/src/js/control-bar/track-button.js
index f482465fa1..4b3056b1a8 100644
--- a/src/js/control-bar/track-button.js
+++ b/src/js/control-bar/track-button.js
@@ -15,8 +15,8 @@ import * as Fn from '../utils/fn.js';
*/
class TrackButton extends MenuButton {
- constructor(player, options){
- let tracks = options.tracks;
+ constructor(player, options) {
+ const tracks = options.tracks;
super(player, options);
@@ -28,7 +28,8 @@ class TrackButton extends MenuButton {
return;
}
- let updateHandler = Fn.bind(this, this.update);
+ const updateHandler = Fn.bind(this, this.update);
+
tracks.addEventListener('removetrack', updateHandler);
tracks.addEventListener('addtrack', updateHandler);
diff --git a/src/js/control-bar/volume-control/volume-bar.js b/src/js/control-bar/volume-control/volume-bar.js
index bf775cd6cc..db44eb9e59 100644
--- a/src/js/control-bar/volume-control/volume-bar.js
+++ b/src/js/control-bar/volume-control/volume-bar.js
@@ -6,7 +6,7 @@ import Component from '../../component.js';
import * as Fn from '../../utils/fn.js';
// Required children
-import VolumeLevel from './volume-level.js';
+import './volume-level.js';
/**
* The bar that contains the volume level and can be clicked on to adjust the level
@@ -18,7 +18,7 @@ import VolumeLevel from './volume-level.js';
*/
class VolumeBar extends Slider {
- constructor(player, options){
+ constructor(player, options) {
super(player, options);
this.on(player, 'volumechange', this.updateARIAAttributes);
player.ready(Fn.bind(this, this.updateARIAAttributes));
@@ -63,9 +63,8 @@ class VolumeBar extends Slider {
getPercent() {
if (this.player_.muted()) {
return 0;
- } else {
- return this.player_.volume();
}
+ return this.player_.volume();
}
/**
@@ -95,7 +94,8 @@ class VolumeBar extends Slider {
*/
updateARIAAttributes() {
// Current value of volume bar as a percentage
- let volume = (this.player_.volume() * 100).toFixed(2);
+ const volume = (this.player_.volume() * 100).toFixed(2);
+
this.el_.setAttribute('aria-valuenow', volume);
this.el_.setAttribute('aria-valuetext', volume + '%');
}
@@ -106,7 +106,7 @@ VolumeBar.prototype.options_ = {
children: [
'volumeLevel'
],
- 'barName': 'volumeLevel'
+ barName: 'volumeLevel'
};
VolumeBar.prototype.playerEvent = 'volumechange';
diff --git a/src/js/control-bar/volume-control/volume-control.js b/src/js/control-bar/volume-control/volume-control.js
index 2095b3dfac..741b403c17 100644
--- a/src/js/control-bar/volume-control/volume-control.js
+++ b/src/js/control-bar/volume-control/volume-control.js
@@ -4,7 +4,7 @@
import Component from '../../component.js';
// Required children
-import VolumeBar from './volume-bar.js';
+import './volume-bar.js';
/**
* The component for controlling the volume level
@@ -16,15 +16,15 @@ import VolumeBar from './volume-bar.js';
*/
class VolumeControl extends Component {
- constructor(player, options){
+ constructor(player, options) {
super(player, options);
// hide volume controls when they're not supported by the current tech
- if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
+ if (player.tech_ && player.tech_.featuresVolumeControl === false) {
this.addClass('vjs-hidden');
}
- this.on(player, 'loadstart', function(){
- if (player.tech_['featuresVolumeControl'] === false) {
+ this.on(player, 'loadstart', function() {
+ if (player.tech_.featuresVolumeControl === false) {
this.addClass('vjs-hidden');
} else {
this.removeClass('vjs-hidden');
diff --git a/src/js/control-bar/volume-menu-button.js b/src/js/control-bar/volume-menu-button.js
index 83879ab5f9..d650a245e4 100644
--- a/src/js/control-bar/volume-menu-button.js
+++ b/src/js/control-bar/volume-menu-button.js
@@ -18,7 +18,7 @@ import VolumeBar from './volume-control/volume-bar.js';
*/
class VolumeMenuButton extends PopupButton {
- constructor(player, options={}){
+ constructor(player, options = {}) {
// Default to inline
if (options.inline === undefined) {
options.inline = true;
@@ -48,7 +48,7 @@ class VolumeMenuButton extends PopupButton {
// hide mute toggle if the current tech doesn't support volume control
function updateVisibility() {
- if (player.tech_ && player.tech_['featuresVolumeControl'] === false) {
+ if (player.tech_ && player.tech_.featuresVolumeControl === false) {
this.addClass('vjs-hidden');
} else {
this.removeClass('vjs-hidden');
@@ -58,19 +58,19 @@ class VolumeMenuButton extends PopupButton {
updateVisibility.call(this);
this.on(player, 'loadstart', updateVisibility);
- this.on(this.volumeBar, ['slideractive', 'focus'], function(){
+ this.on(this.volumeBar, ['slideractive', 'focus'], function() {
this.addClass('vjs-slider-active');
});
- this.on(this.volumeBar, ['sliderinactive', 'blur'], function(){
+ this.on(this.volumeBar, ['sliderinactive', 'blur'], function() {
this.removeClass('vjs-slider-active');
});
- this.on(this.volumeBar, ['focus'], function(){
+ this.on(this.volumeBar, ['focus'], function() {
this.addClass('vjs-lock-showing');
});
- this.on(this.volumeBar, ['blur'], function(){
+ this.on(this.volumeBar, ['blur'], function() {
this.removeClass('vjs-lock-showing');
});
}
@@ -83,7 +83,8 @@ class VolumeMenuButton extends PopupButton {
*/
buildCSSClass() {
let orientationClass = '';
- if (!!this.options_.vertical) {
+
+ if (this.options_.vertical) {
orientationClass = 'vjs-volume-menu-button-vertical';
} else {
orientationClass = 'vjs-volume-menu-button-horizontal';
@@ -99,11 +100,11 @@ class VolumeMenuButton extends PopupButton {
* @method createPopup
*/
createPopup() {
- let popup = new Popup(this.player_, {
+ const popup = new Popup(this.player_, {
contentElType: 'div'
});
- let vb = new VolumeBar(this.player_, this.options_.volumeBar);
+ const vb = new VolumeBar(this.player_, this.options_.volumeBar);
popup.addChild(vb);
diff --git a/src/js/error-display.js b/src/js/error-display.js
index 36cde55267..0959040288 100644
--- a/src/js/error-display.js
+++ b/src/js/error-display.js
@@ -3,8 +3,6 @@
*/
import Component from './component';
import ModalDialog from './modal-dialog';
-
-import * as Dom from './utils/dom';
import mergeOptions from './utils/merge-options';
/**
@@ -45,7 +43,8 @@ class ErrorDisplay extends ModalDialog {
* @return {String|Null}
*/
content() {
- let error = this.player().error();
+ const error = this.player().error();
+
return error ? this.localize(error.message) : '';
}
}
diff --git a/src/js/event-target.js b/src/js/event-target.js
index 281d2b99c2..2c738df3cd 100644
--- a/src/js/event-target.js
+++ b/src/js/event-target.js
@@ -3,41 +3,43 @@
*/
import * as Events from './utils/events.js';
-var EventTarget = function() {};
+const EventTarget = function() {};
EventTarget.prototype.allowedEvents_ = {};
EventTarget.prototype.on = function(type, fn) {
// Remove the addEventListener alias before calling Events.on
// so we don't get into an infinite type loop
- let ael = this.addEventListener;
+ const ael = this.addEventListener;
+
this.addEventListener = () => {};
Events.on(this, type, fn);
this.addEventListener = ael;
};
+
EventTarget.prototype.addEventListener = EventTarget.prototype.on;
EventTarget.prototype.off = function(type, fn) {
Events.off(this, type, fn);
};
+
EventTarget.prototype.removeEventListener = EventTarget.prototype.off;
EventTarget.prototype.one = function(type, fn) {
// Remove the addEventListener alias before calling Events.on
// so we don't get into an infinite type loop
- let ael = this.addEventListener;
+ const ael = this.addEventListener;
+
this.addEventListener = () => {};
Events.one(this, type, fn);
this.addEventListener = ael;
};
EventTarget.prototype.trigger = function(event) {
- let type = event.type || event;
+ const type = event.type || event;
if (typeof event === 'string') {
- event = {
- type: type
- };
+ event = {type};
}
event = Events.fixEvent(event);
@@ -47,6 +49,7 @@ EventTarget.prototype.trigger = function(event) {
Events.trigger(this, event);
};
+
// The standard DOM EventTarget.dispatchEvent() is aliased to trigger()
EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;
diff --git a/src/js/extend.js b/src/js/extend.js
index 963ca2eda2..aa2df7baa6 100644
--- a/src/js/extend.js
+++ b/src/js/extend.js
@@ -7,7 +7,7 @@ import log from './utils/log';
* Both work the same but node adds `super_` to the subClass
* and Bable adds the superClass as __proto__. Both seem useful.
*/
-const _inherits = function (subClass, superClass) {
+const _inherits = function(subClass, superClass) {
if (typeof superClass !== 'function' && superClass !== null) {
throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
}
@@ -44,10 +44,11 @@ const _inherits = function (subClass, superClass) {
* });
* ```
*/
-const extendFn = function(superClass, subClassMethods={}) {
+const extendFn = function(superClass, subClassMethods = {}) {
let subClass = function() {
superClass.apply(this, arguments);
};
+
let methods = {};
if (typeof subClassMethods === 'object') {
@@ -66,7 +67,7 @@ const extendFn = function(superClass, subClassMethods={}) {
_inherits(subClass, superClass);
// Extend subObj's prototype with functions and other properties from props
- for (var name in methods) {
+ for (const name in methods) {
if (methods.hasOwnProperty(name)) {
subClass.prototype[name] = methods[name];
}
diff --git a/src/js/fullscreen-api.js b/src/js/fullscreen-api.js
index b594541ab1..cd15def3db 100644
--- a/src/js/fullscreen-api.js
+++ b/src/js/fullscreen-api.js
@@ -8,7 +8,7 @@ import document from 'global/document';
* @type {Object|undefined}
* @private
*/
-let FullscreenApi = {};
+const FullscreenApi = {};
// browser API methods
// map approach from Screenful.js - https://github.com/sindresorhus/screenfull.js
@@ -60,7 +60,7 @@ const apiMap = [
]
];
-let specApi = apiMap[0];
+const specApi = apiMap[0];
let browserApi;
// determine the supported set of functions
@@ -74,7 +74,7 @@ for (let i = 0; i < apiMap.length; i++) {
// map the browser API names to the spec API names
if (browserApi) {
- for (let i=0; i= 0) {
@@ -497,8 +515,8 @@ class Player extends Component {
}
// Get the ratio as a decimal we can use to calculate dimensions
- let ratioParts = aspectRatio.split(':');
- let ratioMultiplier = ratioParts[1] / ratioParts[0];
+ const ratioParts = aspectRatio.split(':');
+ const ratioMultiplier = ratioParts[1] / ratioParts[0];
if (this.width_ !== undefined) {
// Use any width that's been specifically set
@@ -516,14 +534,14 @@ class Player extends Component {
height = this.height_;
} else {
// Otherwise calculate the height from the ratio and the width
- height = width * ratioMultiplier;
+ height = width * ratioMultiplier;
}
// Ensure the CSS class is valid by starting with an alpha character
- if (/^[^a-zA-Z]/.test(this.id())) {
- idClass = 'dimensions-'+this.id();
+ if ((/^[^a-zA-Z]/).test(this.id())) {
+ idClass = 'dimensions-' + this.id();
} else {
- idClass = this.id()+'-dimensions';
+ idClass = this.id() + '-dimensions';
}
// Ensure the right class is still on the player for the style element
@@ -571,9 +589,9 @@ class Player extends Component {
this.isReady_ = false;
// Grab tech-specific options from player options and add source and parent element to use.
- var techOptions = assign({
+ const techOptions = assign({
+ source,
'nativeControlsForTouch': this.options_.nativeControlsForTouch,
- 'source': source,
'playerId': this.id(),
'techId': `${this.id()}_${techName}_api`,
'videoTracks': this.videoTracks_,
@@ -602,13 +620,14 @@ class Player extends Component {
}
// Initialize tech instance
- let techComponent = Tech.getTech(techName);
+ let TechComponent = Tech.getTech(techName);
+
// Support old behavior of techs being registered as components.
// Remove once that deprecated behavior is removed.
- if (!techComponent) {
- techComponent = Component.getComponent(techName);
+ if (!TechComponent) {
+ TechComponent = Component.getComponent(techName);
}
- this.tech_ = new techComponent(techOptions);
+ this.tech_ = new TechComponent(techOptions);
// player.triggerReady is always async, so don't need this to be async
this.tech_.ready(Fn.bind(this, this.handleTechReady_), true);
@@ -698,12 +717,13 @@ class Player extends Component {
if (safety && safety.IWillNotUseThisInPlugins) {
return this.tech_;
}
- let errorText = `
+ const errorText = `
Please make sure that you are not using this inside of a plugin.
To disable this alert and error, please pass in an object with
\`IWillNotUseThisInPlugins\` to the \`tech\` method. See
https://github.com/videojs/video.js/issues/2617 for more info.
`;
+
window.alert(errorText);
throw new Error(errorText);
}
@@ -794,9 +814,9 @@ class Player extends Component {
// This fixes both issues. Need to wait for API, so it updates displays correctly
if ((this.src() || this.currentSrc()) && this.tag && this.options_.autoplay && this.paused()) {
try {
- delete this.tag.poster; // Chrome Fix. Fixed in Chrome v16.
- }
- catch (e) {
+ // Chrome Fix. Fixed in Chrome v16.
+ delete this.tag.poster;
+ } catch (e) {
log('deleting tag.poster throws in some browsers', e);
}
this.play();
@@ -954,9 +974,9 @@ class Player extends Component {
* @method handleTechFirstPlay_
*/
handleTechFirstPlay_() {
- //If the first starttime attribute is specified
- //then we will start at the given offset in seconds
- if(this.options_.starttime){
+ // If the first starttime attribute is specified
+ // then we will start at the given offset in seconds
+ if (this.options_.starttime) {
this.currentTime(this.options_.starttime);
}
@@ -1024,7 +1044,9 @@ class Player extends Component {
handleTechClick_(event) {
// We're using mousedown to detect clicks thanks to Flash, but mousedown
// will also be triggered with right-clicks, so we need to prevent that
- if (event.button !== 0) return;
+ if (event.button !== 0) {
+ return;
+ }
// When controls are disabled a click should not toggle playback because
// the click is considered a control
@@ -1065,7 +1087,7 @@ class Player extends Component {
* @method handleTechTouchMove_
*/
handleTechTouchMove_() {
- if (this.userWasActive){
+ if (this.userWasActive) {
this.reportUserActivity();
}
}
@@ -1126,7 +1148,8 @@ class Player extends Component {
* @method handleTechError_
*/
handleTechError_() {
- let error = this.tech_.error();
+ const error = this.tech_.error();
+
this.error(error);
}
@@ -1181,7 +1204,8 @@ class Player extends Component {
}
handleTechTextData_() {
- var data = null;
+ let data = null;
+
if (arguments.length > 1) {
data = arguments[1];
}
@@ -1259,15 +1283,17 @@ class Player extends Component {
techCall_(method, arg) {
// If it's not ready yet, call method when it is
if (this.tech_ && !this.tech_.isReady_) {
- this.tech_.ready(function(){
+ this.tech_.ready(function() {
this[method](arg);
}, true);
// Otherwise call method now
} else {
try {
- this.tech_ && this.tech_[method](arg);
- } catch(e) {
+ if (this.tech_) {
+ this.tech_[method](arg);
+ }
+ } catch (e) {
log(e);
throw e;
}
@@ -1290,18 +1316,17 @@ class Player extends Component {
// When that happens we'll catch the errors and inform tech that it's not ready any more.
try {
return this.tech_[method]();
- } catch(e) {
+ } catch (e) {
// When building additional tech libs, an expected method may not be defined yet
if (this.tech_[method] === undefined) {
log(`Video.js: ${method} method not defined for ${this.techName_} playback technology.`, e);
+
+ // When a method isn't available on the object it throws a TypeError
+ } else if (e.name === 'TypeError') {
+ log(`Video.js: ${method} unavailable on ${this.techName_} playback technology element.`, e);
+ this.tech_.isReady_ = false;
} else {
- // When a method isn't available on the object it throws a TypeError
- if (e.name === 'TypeError') {
- log(`Video.js: ${method} unavailable on ${this.techName_} playback technology element.`, e);
- this.tech_.isReady_ = false;
- } else {
- log(e);
- }
+ log(e);
}
throw e;
}
@@ -1414,7 +1439,8 @@ class Player extends Component {
// currentTime when scrubbing, but may not provide much performance benefit afterall.
// Should be tested. Also something has to read the actual current time or the cache will
// never get updated.
- return this.cache_.currentTime = (this.techGet_('currentTime') || 0);
+ this.cache_.currentTime = (this.techGet_('currentTime') || 0);
+ return this.cache_.currentTime;
}
/**
@@ -1495,10 +1521,10 @@ class Player extends Component {
* @method buffered
*/
buffered() {
- var buffered = this.techGet_('buffered');
+ let buffered = this.techGet_('buffered');
if (!buffered || !buffered.length) {
- buffered = createTimeRange(0,0);
+ buffered = createTimeRange(0, 0);
}
return buffered;
@@ -1527,9 +1553,9 @@ class Player extends Component {
* @method bufferedEnd
*/
bufferedEnd() {
- var buffered = this.buffered(),
- duration = this.duration(),
- end = buffered.end(buffered.length-1);
+ const buffered = this.buffered();
+ const duration = this.duration();
+ let end = buffered.end(buffered.length - 1);
if (end > duration) {
end = duration;
@@ -1557,7 +1583,8 @@ class Player extends Component {
let vol;
if (percentAsDecimal !== undefined) {
- vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); // Force value to between 0 and 1
+ // Force value to between 0 and 1
+ vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal)));
this.cache_.volume = vol;
this.techCall_('setVolume', vol);
@@ -1569,7 +1596,6 @@ class Player extends Component {
return (isNaN(vol)) ? 1 : vol;
}
-
/**
* Get the current muted state, or turn mute on or off
* ```js
@@ -1589,7 +1615,7 @@ class Player extends Component {
this.techCall_('setMuted', muted);
return this;
}
- return this.techGet_('muted') || false; // Default to false
+ return this.techGet_('muted') || false;
}
// Check if current tech can support native fullscreen
@@ -1645,7 +1671,7 @@ class Player extends Component {
* @method requestFullscreen
*/
requestFullscreen() {
- var fsApi = FullscreenApi;
+ const fsApi = FullscreenApi;
this.isFullscreen(true);
@@ -1658,7 +1684,7 @@ class Player extends Component {
// when canceling fullscreen. Otherwise if there's multiple
// players on a page, they would all be reacting to the same fullscreen
// events
- Events.on(document, fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e){
+ Events.on(document, fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) {
this.isFullscreen(document[fsApi.fullscreenElement]);
// If cancelling fullscreen, remove event listener.
@@ -1695,17 +1721,18 @@ class Player extends Component {
* @method exitFullscreen
*/
exitFullscreen() {
- var fsApi = FullscreenApi;
+ const fsApi = FullscreenApi;
+
this.isFullscreen(false);
// Check for browser element fullscreen support
if (fsApi.requestFullscreen) {
document[fsApi.exitFullscreen]();
} else if (this.tech_.supportsFullScreen()) {
- this.techCall_('exitFullScreen');
+ this.techCall_('exitFullScreen');
} else {
- this.exitFullWindow();
- this.trigger('fullscreenchange');
+ this.exitFullWindow();
+ this.trigger('fullscreenchange');
}
return this;
@@ -1782,7 +1809,7 @@ class Player extends Component {
// Loop through each playback technology in the options order
for (let i = 0, j = this.options_.techOrder; i < j.length; i++) {
- let techName = toTitleCase(j[i]);
+ const techName = toTitleCase(j[i]);
let tech = Tech.getTech(techName);
// Support old behavior of techs being registered as components.
@@ -1822,7 +1849,7 @@ class Player extends Component {
selectSource(sources) {
// Get only the techs specified in `techOrder` that exist and are supported by the
// current platform
- let techs =
+ const techs =
this.options_.techOrder
.map(toTitleCase)
.map((techName) => {
@@ -1845,7 +1872,7 @@ class Player extends Component {
// Iterate over each `innerArray` element once per `outerArray` element and execute
// `tester` with both. If `tester` returns a non-falsy value, exit early and return
// that value.
- let findFirstPassingTechSourcePair = function (outerArray, innerArray, tester) {
+ const findFirstPassingTechSourcePair = function(outerArray, innerArray, tester) {
let found;
outerArray.some((outerChoice) => {
@@ -1862,10 +1889,10 @@ class Player extends Component {
};
let foundSourceAndTech;
- let flip = (fn) => (a, b) => fn(b, a);
- let finder = ([techName, tech], source) => {
+ const flip = (fn) => (a, b) => fn(b, a);
+ const finder = ([techName, tech], source) => {
if (tech.canPlaySource(source, this.options_[techName.toLowerCase()])) {
- return {source: source, tech: techName};
+ return {source, tech: techName};
}
};
@@ -1920,6 +1947,7 @@ class Player extends Component {
}
let currentTech = Tech.getTech(this.techName_);
+
// Support old behavior of techs being registered as components.
// Remove once that deprecated behavior is removed.
if (!currentTech) {
@@ -1948,7 +1976,7 @@ class Player extends Component {
this.currentType_ = source.type || '';
// wait until the tech is ready to set the source
- this.ready(function(){
+ this.ready(function() {
// The setSource tech method was added with source handlers
// so older techs won't support it
@@ -1984,7 +2012,7 @@ class Player extends Component {
* @method sourceList_
*/
sourceList_(sources) {
- var sourceTech = this.selectSource(sources);
+ const sourceTech = this.selectSource(sources);
if (sourceTech) {
if (sourceTech.tech === this.techName_) {
@@ -1996,7 +2024,7 @@ class Player extends Component {
}
} else {
// We need to wrap this in a timeout to give folks a chance to add error event handlers
- this.setTimeout( function() {
+ this.setTimeout(function() {
this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) });
}, 0);
@@ -2098,7 +2126,7 @@ class Player extends Component {
loop(value) {
if (value !== undefined) {
this.techCall_('setLoop', value);
- this.options_['loop'] = value;
+ this.options_.loop = value;
return this;
}
return this.techGet_('loop');
@@ -2172,7 +2200,8 @@ class Player extends Component {
*/
controls(bool) {
if (bool !== undefined) {
- bool = !!bool; // force boolean
+ bool = !!bool;
+
// Don't trigger a change event unless it actually changed
if (this.controls_ !== bool) {
this.controls_ = bool;
@@ -2218,7 +2247,8 @@ class Player extends Component {
*/
usingNativeControls(bool) {
if (bool !== undefined) {
- bool = !!bool; // force boolean
+ bool = !!bool;
+
// Don't trigger a change event unless it actually changed
if (this.usingNativeControls_ !== bool) {
this.usingNativeControls_ = bool;
@@ -2302,7 +2332,9 @@ class Player extends Component {
* @return {Boolean} True if the player is in the ended state, false if not.
* @method ended
*/
- ended() { return this.techGet_('ended'); }
+ ended() {
+ return this.techGet_('ended');
+ }
/**
* Returns whether or not the player is in the "seeking" state.
@@ -2310,7 +2342,9 @@ class Player extends Component {
* @return {Boolean} True if the player is in the seeking state, false if not.
* @method seeking
*/
- seeking() { return this.techGet_('seeking'); }
+ seeking() {
+ return this.techGet_('seeking');
+ }
/**
* Returns the TimeRanges of the media that are currently available
@@ -2319,7 +2353,9 @@ class Player extends Component {
* @return {TimeRanges} the seekable intervals of the media timeline
* @method seekable
*/
- seekable() { return this.techGet_('seekable'); }
+ seekable() {
+ return this.techGet_('seekable');
+ }
/**
* Report user activity
@@ -2363,8 +2399,8 @@ class Player extends Component {
//
// When this gets resolved in ALL browsers it can be removed
// https://code.google.com/p/chromium/issues/detail?id=103041
- if(this.tech_) {
- this.tech_.one('mousemove', function(e){
+ if (this.tech_) {
+ this.tech_.one('mousemove', function(e) {
e.stopPropagation();
e.preventDefault();
});
@@ -2387,21 +2423,22 @@ class Player extends Component {
* @method listenForUserActivity_
*/
listenForUserActivity_() {
- let mouseInProgress, lastMoveX, lastMoveY;
-
- let handleActivity = Fn.bind(this, this.reportUserActivity);
+ let mouseInProgress;
+ let lastMoveX;
+ let lastMoveY;
+ const handleActivity = Fn.bind(this, this.reportUserActivity);
- let handleMouseMove = function(e) {
+ const handleMouseMove = function(e) {
// #1068 - Prevent mousemove spamming
// Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970
- if(e.screenX !== lastMoveX || e.screenY !== lastMoveY) {
+ if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) {
lastMoveX = e.screenX;
lastMoveY = e.screenY;
handleActivity();
}
};
- let handleMouseDown = function() {
+ const handleMouseDown = function() {
handleActivity();
// For as long as the they are touching the device or have their mouse down,
// we consider them active even if they're not moving their finger or mouse.
@@ -2413,7 +2450,7 @@ class Player extends Component {
mouseInProgress = this.setInterval(handleActivity, 250);
};
- let handleMouseUp = function(event) {
+ const handleMouseUp = function(event) {
handleActivity();
// Stop the interval that maintains activity if the mouse/touch is down
this.clearInterval(mouseInProgress);
@@ -2435,7 +2472,8 @@ class Player extends Component {
// then gets picked up by this loop
// http://ejohn.org/blog/learning-from-twitter/
let inactivityTimeout;
- let activityCheck = this.setInterval(function() {
+
+ this.setInterval(function() {
// Check to see if mouse/touch activity has happened
if (this.userActivity_) {
// Reset the activity tracker
@@ -2447,16 +2485,17 @@ class Player extends Component {
// Clear any existing inactivity timeout to start the timer over
this.clearTimeout(inactivityTimeout);
- var timeout = this.options_['inactivityTimeout'];
+ const timeout = this.options_.inactivityTimeout;
+
if (timeout > 0) {
// In milliseconds, if no more activity has occurred the
// user will be considered inactive
- inactivityTimeout = this.setTimeout(function () {
+ inactivityTimeout = this.setTimeout(function() {
// Protect against the case where the inactivityTimeout can trigger just
- // before the next user activity is picked up by the activityCheck loop
+ // before the next user activity is picked up by the activity check loop
// causing a flicker
if (!this.userActivity_) {
- this.userActive(false);
+ this.userActive(false);
}
}, timeout);
}
@@ -2481,11 +2520,10 @@ class Player extends Component {
return this;
}
- if (this.tech_ && this.tech_['featuresPlaybackRate']) {
+ if (this.tech_ && this.tech_.featuresPlaybackRate) {
return this.techGet_('playbackRate');
- } else {
- return 1.0;
}
+ return 1.0;
}
/**
@@ -2611,7 +2649,9 @@ class Player extends Component {
textTracks() {
// cannot use techGet_ directly because it checks to see whether the tech is ready.
// Flash is unlikely to be ready in time but textTracks should still work.
- return this.tech_ && this.tech_['textTracks']();
+ if (this.tech_) {
+ return this.tech_.textTracks();
+ }
}
/**
@@ -2621,7 +2661,9 @@ class Player extends Component {
* @method remoteTextTracks
*/
remoteTextTracks() {
- return this.tech_ && this.tech_['remoteTextTracks']();
+ if (this.tech_) {
+ return this.tech_.remoteTextTracks();
+ }
}
/**
@@ -2631,7 +2673,9 @@ class Player extends Component {
* @method remoteTextTrackEls
*/
remoteTextTrackEls() {
- return this.tech_ && this.tech_['remoteTextTrackEls']();
+ if (this.tech_) {
+ return this.tech_.remoteTextTrackEls();
+ }
}
/**
@@ -2645,7 +2689,9 @@ class Player extends Component {
* @method addTextTrack
*/
addTextTrack(kind, label, language) {
- return this.tech_ && this.tech_['addTextTrack'](kind, label, language);
+ if (this.tech_) {
+ return this.tech_.addTextTrack(kind, label, language);
+ }
}
/**
@@ -2655,7 +2701,9 @@ class Player extends Component {
* @method addRemoteTextTrack
*/
addRemoteTextTrack(options) {
- return this.tech_ && this.tech_['addRemoteTextTrack'](options);
+ if (this.tech_) {
+ return this.tech_.addRemoteTextTrack(options);
+ }
}
/**
@@ -2666,8 +2714,10 @@ class Player extends Component {
*/
// destructure the input into an object with a track argument, defaulting to arguments[0]
// default the whole argument to an empty object if nothing was passed in
- removeRemoteTextTrack({track = arguments[0]} = {}) { // jshint ignore:line
- this.tech_ && this.tech_['removeRemoteTextTrack'](track);
+ removeRemoteTextTrack({track = arguments[0]} = {}) {
+ if (this.tech_) {
+ return this.tech_.removeRemoteTextTrack(track);
+ }
}
/**
@@ -2691,11 +2741,11 @@ class Player extends Component {
}
// Methods to add support for
- // initialTime: function(){ return this.techCall_('initialTime'); },
- // startOffsetTime: function(){ return this.techCall_('startOffsetTime'); },
- // played: function(){ return this.techCall_('played'); },
- // defaultPlaybackRate: function(){ return this.techCall_('defaultPlaybackRate'); },
- // defaultMuted: function(){ return this.techCall_('defaultMuted'); }
+ // initialTime: function() { return this.techCall_('initialTime'); },
+ // startOffsetTime: function() { return this.techCall_('startOffsetTime'); },
+ // played: function() { return this.techCall_('played'); },
+ // defaultPlaybackRate: function() { return this.techCall_('defaultPlaybackRate'); },
+ // defaultMuted: function() { return this.techCall_('defaultMuted'); }
/**
* The player's language code
@@ -2713,7 +2763,7 @@ class Player extends Component {
return this.language_;
}
- this.language_ = (''+code).toLowerCase();
+ this.language_ = String(code).toLowerCase();
return this;
}
@@ -2726,7 +2776,7 @@ class Player extends Component {
* @method languages
*/
languages() {
- return mergeOptions(Player.prototype.options_.languages, this.languages_);
+ return mergeOptions(Player.prototype.options_.languages, this.languages_);
}
/**
@@ -2736,8 +2786,8 @@ class Player extends Component {
* @method toJSON
*/
toJSON() {
- let options = mergeOptions(this.options_);
- let tracks = options.tracks;
+ const options = mergeOptions(this.options_);
+ const tracks = options.tracks;
options.tracks = [];
@@ -2770,16 +2820,14 @@ class Player extends Component {
* @return {ModalDialog}
*/
createModal(content, options) {
- let player = this;
-
options = options || {};
options.content = content || '';
- let modal = new ModalDialog(player, options);
+ const modal = new ModalDialog(this, options);
- player.addChild(modal);
- modal.on('dispose', function() {
- player.removeChild(modal);
+ this.addChild(modal);
+ modal.on('dispose', () => {
+ this.removeChild(modal);
});
return modal.open();
@@ -2794,19 +2842,20 @@ class Player extends Component {
* @method getTagSettings
*/
static getTagSettings(tag) {
- let baseOptions = {
- 'sources': [],
- 'tracks': []
+ const baseOptions = {
+ sources: [],
+ tracks: []
};
const tagOptions = Dom.getElAttributes(tag);
const dataSetup = tagOptions['data-setup'];
// Check if data-setup attr exists.
- if (dataSetup !== null){
+ if (dataSetup !== null) {
// Parse options JSON
// If empty string, make it a parsable json object.
const [err, data] = safeParseTuple(dataSetup || '{}');
+
if (err) {
log.error(err);
}
@@ -2819,10 +2868,11 @@ class Player extends Component {
if (tag.hasChildNodes()) {
const children = tag.childNodes;
- for (let i=0, j=children.length; i 0) {
- for(let i=0, e=vids.length; i 0) {
- for(let i=0, e=audios.length; i 0) {
- for (let i=0, e=mediaEls.length; i this.play(), 0);
}
}
@@ -187,7 +190,8 @@ class Flash extends Tech {
* @method setCurrentTime
*/
setCurrentTime(time) {
- let seekable = this.seekable();
+ const seekable = this.seekable();
+
if (seekable.length) {
// clamp to the current seekable range
time = time > seekable.start(0) ? time : seekable.start(0);
@@ -224,9 +228,8 @@ class Flash extends Tech {
currentSrc() {
if (this.currentSource_) {
return this.currentSource_.src;
- } else {
- return this.el_.vjs_getProperty('currentSrc');
}
+ return this.el_.vjs_getProperty('currentSrc');
}
/**
@@ -237,10 +240,10 @@ class Flash extends Tech {
duration() {
if (this.readyState() === 0) {
return NaN;
- } else {
- let duration = this.el_.vjs_getProperty('duration');
- return duration >= 0 ? duration : Infinity;
}
+ const duration = this.el_.vjs_getProperty('duration');
+
+ return duration >= 0 ? duration : Infinity;
}
/**
@@ -276,6 +279,7 @@ class Flash extends Tech {
*/
seekable() {
const duration = this.duration();
+
if (duration === 0) {
return createTimeRange();
}
@@ -289,7 +293,8 @@ class Flash extends Tech {
* @method buffered
*/
buffered() {
- let ranges = this.el_.vjs_getProperty('buffered');
+ const ranges = this.el_.vjs_getProperty('buffered');
+
if (ranges.length === 0) {
return createTimeRange();
}
@@ -305,7 +310,8 @@ class Flash extends Tech {
* @method supportsFullScreen
*/
supportsFullScreen() {
- return false; // Flash does not allow fullscreen through javascript
+ // Flash does not allow fullscreen through javascript
+ return false;
}
/**
@@ -322,18 +328,23 @@ class Flash extends Tech {
}
-
// Create setters and getters for attributes
const _api = Flash.prototype;
const _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(',');
const _readOnly = 'networkState,readyState,initialTime,startOffsetTime,paused,ended,videoWidth,videoHeight'.split(',');
-function _createSetter(attr){
- var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
- _api['set'+attrUpper] = function(val){ return this.el_.vjs_setProperty(attr, val); };
+function _createSetter(attr) {
+ const attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
+
+ _api['set' + attrUpper] = function(val) {
+ return this.el_.vjs_setProperty(attr, val);
+ };
}
+
function _createGetter(attr) {
- _api[attr] = function(){ return this.el_.vjs_getProperty(attr); };
+ _api[attr] = function() {
+ return this.el_.vjs_getProperty(attr);
+ };
}
// Create getter and setters for all read/write attributes
@@ -349,7 +360,7 @@ for (let i = 0; i < _readOnly.length; i++) {
/* Flash Support Testing -------------------------------------------------------- */
-Flash.isSupported = function(){
+Flash.isSupported = function() {
return Flash.version()[0] >= 10;
// return swfobject.hasFlashPlayerVersion('10');
};
@@ -371,7 +382,7 @@ Flash.nativeSourceHandler = {};
* @param {String} type The mimetype to check
* @return {String} 'probably', 'maybe', or '' (empty string)
*/
-Flash.nativeSourceHandler.canPlayType = function(type){
+Flash.nativeSourceHandler.canPlayType = function(type) {
if (type in Flash.formats) {
return 'maybe';
}
@@ -386,11 +397,12 @@ Flash.nativeSourceHandler.canPlayType = function(type){
* @param {Object} options The options passed to the tech
* @return {String} 'probably', 'maybe', or '' (empty string)
*/
-Flash.nativeSourceHandler.canHandleSource = function(source, options){
- var type;
+Flash.nativeSourceHandler.canHandleSource = function(source, options) {
+ let type;
function guessMimeType(src) {
- var ext = Url.getFileExtension(src);
+ const ext = Url.getFileExtension(src);
+
if (ext) {
return `video/${ext}`;
}
@@ -416,7 +428,7 @@ Flash.nativeSourceHandler.canHandleSource = function(source, options){
* @param {Flash} tech The instance of the Flash tech
* @param {Object} options The options to pass to the source
*/
-Flash.nativeSourceHandler.handleSource = function(source, tech, options){
+Flash.nativeSourceHandler.handleSource = function(source, tech, options) {
tech.setSrc(source.src);
};
@@ -424,7 +436,7 @@ Flash.nativeSourceHandler.handleSource = function(source, tech, options){
* Clean up the source handler when disposing the player or switching sources..
* (no cleanup is needed when supporting the format natively)
*/
-Flash.nativeSourceHandler.dispose = function(){};
+Flash.nativeSourceHandler.dispose = function() {};
// Register the native source handler
Flash.registerSourceHandler(Flash.nativeSourceHandler);
@@ -436,9 +448,9 @@ Flash.formats = {
'video/m4v': 'MP4'
};
-Flash.onReady = function(currSwf){
- let el = Dom.getEl(currSwf);
- let tech = el && el.tech;
+Flash.onReady = function(currSwf) {
+ const el = Dom.getEl(currSwf);
+ const tech = el && el.tech;
// if there is no el then the tech has been disposed
// and the tech element was removed from the player div
@@ -450,7 +462,7 @@ Flash.onReady = function(currSwf){
// The SWF isn't always ready when it says it is. Sometimes the API functions still need to be added to the object.
// If it's not ready, we set a timeout to check again shortly.
-Flash.checkReady = function(tech){
+Flash.checkReady = function(tech) {
// stop worrying if the tech has been disposed
if (!tech.el()) {
return;
@@ -462,20 +474,21 @@ Flash.checkReady = function(tech){
tech.triggerReady();
} else {
// wait longer
- this.setTimeout(function(){
- Flash['checkReady'](tech);
+ this.setTimeout(function() {
+ Flash.checkReady(tech);
}, 50);
}
};
// Trigger events from the swf on the player
-Flash.onEvent = function(swfID, eventName){
- let tech = Dom.getEl(swfID).tech;
+Flash.onEvent = function(swfID, eventName) {
+ const tech = Dom.getEl(swfID).tech;
+
tech.trigger(eventName, Array.prototype.slice.call(arguments, 2));
};
// Log errors from the swf
-Flash.onError = function(swfID, err){
+Flash.onError = function(swfID, err) {
const tech = Dom.getEl(swfID).tech;
// trigger MEDIA_ERR_SRC_NOT_SUPPORTED
@@ -488,7 +501,7 @@ Flash.onError = function(swfID, err){
};
// Flash Version Check
-Flash.version = function(){
+Flash.version = function() {
let version = '0,0,0';
// IE
@@ -496,18 +509,20 @@ Flash.version = function(){
version = new window.ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
// other browsers
- } catch(e) {
+ } catch (e) {
try {
- if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin){
+ if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) {
version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
}
- } catch(err) {}
+ } catch (err) {
+ // satisfy linter
+ }
}
return version.split(',');
};
// Flash embedding method. Only used in non-iframe mode
-Flash.embed = function(swf, flashVars, params, attributes){
+Flash.embed = function(swf, flashVars, params, attributes) {
const code = Flash.getEmbedCode(swf, flashVars, params, attributes);
// Get element by embedding code and retrieving created element
@@ -516,7 +531,7 @@ Flash.embed = function(swf, flashVars, params, attributes){
return obj;
};
-Flash.getEmbedCode = function(swf, flashVars, params, attributes){
+Flash.getEmbedCode = function(swf, flashVars, params, attributes) {
const objTag = '`;
});
attributes = assign({
// Add swf to attributes (need both for IE and Others to work)
- 'data': swf,
+ data: swf,
// Default to 100% width/height
- 'width': '100%',
- 'height': '100%'
+ width: '100%',
+ height: '100%'
}, attributes);
// Create Attributes string
- Object.getOwnPropertyNames(attributes).forEach(function(key){
+ Object.getOwnPropertyNames(attributes).forEach(function(key) {
attrsString += `${key}="${attributes[key]}" `;
});
diff --git a/src/js/tech/html5.js b/src/js/tech/html5.js
index 8d72e042c9..2d64cb9680 100644
--- a/src/js/tech/html5.js
+++ b/src/js/tech/html5.js
@@ -10,7 +10,6 @@ import * as Url from '../utils/url.js';
import * as Fn from '../utils/fn.js';
import log from '../utils/log.js';
import tsml from 'tsml';
-import TextTrack from '../../../src/js/tracks/text-track.js';
import * as browser from '../utils/browser.js';
import document from 'global/document';
import window from 'global/window';
@@ -28,7 +27,7 @@ import toTitleCase from '../utils/to-title-case.js';
*/
class Html5 extends Tech {
- constructor(options, ready){
+ constructor(options, ready) {
super(options, ready);
const source = options.source;
@@ -46,13 +45,13 @@ class Html5 extends Tech {
if (this.el_.hasChildNodes()) {
- let nodes = this.el_.childNodes;
+ const nodes = this.el_.childNodes;
let nodesLength = nodes.length;
- let removeNodes = [];
+ const removeNodes = [];
while (nodesLength--) {
- let node = nodes[nodesLength];
- let nodeName = node.nodeName.toLowerCase();
+ const node = nodes[nodesLength];
+ const nodeName = node.nodeName.toLowerCase();
if (nodeName === 'track') {
if (!this.featuresNativeTextTracks) {
@@ -74,21 +73,21 @@ class Html5 extends Tech {
}
}
- for (let i=0; i {
- let capitalType = toTitleCase(type);
+ const capitalType = toTitleCase(type);
if (!this[`featuresNative${capitalType}Tracks`]) {
return;
}
- let tl = this.el()[`${type}Tracks`];
+ const tl = this.el()[`${type}Tracks`];
if (tl && tl.addEventListener) {
tl.addEventListener('change', Fn.bind(this, this[`handle${capitalType}TrackChange_`]));
@@ -102,7 +101,7 @@ class Html5 extends Tech {
if (this.featuresNativeTextTracks) {
if (crossoriginTracks) {
- log.warn(tsml`Text Tracks are being loaded from another origin but the crossorigin attribute isn't used.
+ log.warn(tsml`Text Tracks are being loaded from another origin but the crossorigin attribute isn't used.
This may prevent text tracks from loading.`);
}
@@ -132,15 +131,15 @@ class Html5 extends Tech {
dispose() {
// Un-ProxyNativeTracks
['audio', 'video', 'text'].forEach((type) => {
- let capitalType = toTitleCase(type);
- let tl = this.el_[`${type}Tracks`];
+ const capitalType = toTitleCase(type);
+ const tl = this.el_[`${type}Tracks`];
if (tl && tl.removeEventListener) {
tl.removeEventListener('change', this[`handle${capitalType}TrackChange_`]);
tl.removeEventListener('addtrack', this[`handle${capitalType}TrackAdd_`]);
tl.removeEventListener('removetrack', this[`handle${capitalType}TrackRemove_`]);
}
-
+
// Stop removing old text tracks
if (tl) {
this.off('loadstart', this[`removeOld${capitalType}Tracks_`]);
@@ -164,11 +163,12 @@ class Html5 extends Tech {
// Check if this browser supports moving the element into the box.
// On the iPhone video will break if you move the element,
// So we have to create a brand new element.
- if (!el || this['movingMediaElementInDOM'] === false) {
+ if (!el || this.movingMediaElementInDOM === false) {
// If the original tag is still there, clone and remove it.
if (el) {
const clone = el.cloneNode(true);
+
el.parentNode.insertBefore(clone, el);
Html5.disposeMediaElement(el);
el = clone;
@@ -176,8 +176,9 @@ class Html5 extends Tech {
el = document.createElement('video');
// determine if native controls should be used
- let tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag);
- let attributes = mergeOptions({}, tagAttributes);
+ const tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag);
+ const attributes = mergeOptions({}, tagAttributes);
+
if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) {
delete attributes.controls;
}
@@ -192,10 +193,12 @@ class Html5 extends Tech {
}
// Update specific tag settings, in case they were overridden
- let settingsAttrs = ['autoplay','preload','loop','muted'];
+ const settingsAttrs = ['autoplay', 'preload', 'loop', 'muted'];
+
for (let i = settingsAttrs.length - 1; i >= 0; i--) {
const attr = settingsAttrs[i];
- let overwriteAttrs = {};
+ const overwriteAttrs = {};
+
if (typeof this.options_[attr] !== 'undefined') {
overwriteAttrs[attr] = this.options_[attr];
}
@@ -229,21 +232,23 @@ class Html5 extends Tech {
// which could also happen between now and the next loop, so we'll
// watch for that also.
let loadstartFired = false;
- let setLoadstartFired = function() {
+ const setLoadstartFired = function() {
loadstartFired = true;
};
+
this.on('loadstart', setLoadstartFired);
- let triggerLoadstart = function() {
+ const triggerLoadstart = function() {
// We did miss the original loadstart. Make sure the player
// sees loadstart before loadedmetadata
if (!loadstartFired) {
this.trigger('loadstart');
}
};
+
this.on('loadedmetadata', triggerLoadstart);
- this.ready(function(){
+ this.ready(function() {
this.off('loadstart', setLoadstartFired);
this.off('loadedmetadata', triggerLoadstart);
@@ -260,7 +265,7 @@ class Html5 extends Tech {
// The other readyState events aren't as much of a problem if we double
// them, so not going to go to as much trouble as loadstart to prevent
// that unless we find reason to.
- let eventsToTrigger = ['loadstart'];
+ const eventsToTrigger = ['loadstart'];
// loadedmetadata: newly equal to HAVE_METADATA (1) or greater
eventsToTrigger.push('loadedmetadata');
@@ -281,15 +286,15 @@ class Html5 extends Tech {
}
// We still need to give the player time to add event listeners
- this.ready(function(){
- eventsToTrigger.forEach(function(type){
+ this.ready(function() {
+ eventsToTrigger.forEach(function(type) {
this.trigger(type);
}, this);
});
}
proxyNativeTextTracks_() {
- let tt = this.el().textTracks;
+ const tt = this.el().textTracks;
if (tt) {
// Add tracks - if player is initialised after DOM loaded, textTracks
@@ -303,14 +308,15 @@ class Html5 extends Tech {
tt.addEventListener('addtrack', this.handleTextTrackAdd_);
tt.addEventListener('removetrack', this.handleTextTrackRemove_);
}
-
+
// Remove (native) texttracks that are not used anymore
this.on('loadstart', this.removeOldTextTracks_);
}
}
handleTextTrackChange(e) {
- let tt = this.textTracks();
+ const tt = this.textTracks();
+
this.textTracks().trigger({
type: 'change',
target: tt,
@@ -328,7 +334,8 @@ class Html5 extends Tech {
}
handleVideoTrackChange_(e) {
- let vt = this.videoTracks();
+ const vt = this.videoTracks();
+
this.videoTracks().trigger({
type: 'change',
target: vt,
@@ -346,7 +353,8 @@ class Html5 extends Tech {
}
handleAudioTrackChange_(e) {
- let audioTrackList = this.audioTracks();
+ const audioTrackList = this.audioTracks();
+
this.audioTracks().trigger({
type: 'change',
target: audioTrackList,
@@ -373,15 +381,16 @@ class Html5 extends Tech {
removeOldTracks_(techTracks, elTracks) {
// This will loop over the techTracks and check if they are still used by the HTML5 video element
// If not, they will be removed from the emulated list
- let removeTracks = [];
+ const removeTracks = [];
+
if (!elTracks) {
return;
}
for (let i = 0; i < techTracks.length; i++) {
- let techTrack = techTracks[i];
-
+ const techTrack = techTracks[i];
let found = false;
+
for (let j = 0; j < elTracks.length; j++) {
if (elTracks[j] === techTrack) {
found = true;
@@ -396,6 +405,7 @@ class Html5 extends Tech {
for (let i = 0; i < removeTracks.length; i++) {
const track = removeTracks[i];
+
techTracks.removeTrack_(track);
}
}
@@ -403,18 +413,21 @@ class Html5 extends Tech {
removeOldTextTracks_() {
const techTracks = this.textTracks();
const elTracks = this.el().textTracks;
+
this.removeOldTracks_(techTracks, elTracks);
}
removeOldAudioTracks_() {
const techTracks = this.audioTracks();
const elTracks = this.el().audioTracks;
+
this.removeOldTracks_(techTracks, elTracks);
}
removeOldVideoTracks_() {
const techTracks = this.videoTracks();
const elTracks = this.el().videoTracks;
+
this.removeOldTracks_(techTracks, elTracks);
}
@@ -423,14 +436,18 @@ class Html5 extends Tech {
*
* @method play
*/
- play() { this.el_.play(); }
+ play() {
+ this.el_.play();
+ }
/**
* Pause for html5 tech
*
* @method pause
*/
- pause() { this.el_.pause(); }
+ pause() {
+ this.el_.pause();
+ }
/**
* Paused for html5 tech
@@ -438,7 +455,9 @@ class Html5 extends Tech {
* @return {Boolean}
* @method paused
*/
- paused() { return this.el_.paused; }
+ paused() {
+ return this.el_.paused;
+ }
/**
* Get current time
@@ -446,7 +465,9 @@ class Html5 extends Tech {
* @return {Number}
* @method currentTime
*/
- currentTime() { return this.el_.currentTime; }
+ currentTime() {
+ return this.el_.currentTime;
+ }
/**
* Set current time
@@ -457,7 +478,7 @@ class Html5 extends Tech {
setCurrentTime(seconds) {
try {
this.el_.currentTime = seconds;
- } catch(e) {
+ } catch (e) {
log(e, 'Video is not ready. (Video.js)');
// this.warning(VideoJS.warnings.videoNotReady);
}
@@ -469,7 +490,9 @@ class Html5 extends Tech {
* @return {Number}
* @method duration
*/
- duration() { return this.el_.duration || 0; }
+ duration() {
+ return this.el_.duration || 0;
+ }
/**
* Get a TimeRange object that represents the intersection
@@ -479,7 +502,9 @@ class Html5 extends Tech {
* @return {TimeRangeObject}
* @method buffered
*/
- buffered() { return this.el_.buffered; }
+ buffered() {
+ return this.el_.buffered;
+ }
/**
* Get volume level
@@ -487,7 +512,9 @@ class Html5 extends Tech {
* @return {Number}
* @method volume
*/
- volume() { return this.el_.volume; }
+ volume() {
+ return this.el_.volume;
+ }
/**
* Set volume level
@@ -495,7 +522,9 @@ class Html5 extends Tech {
* @param {Number} percentAsDecimal Volume percent as a decimal
* @method setVolume
*/
- setVolume(percentAsDecimal) { this.el_.volume = percentAsDecimal; }
+ setVolume(percentAsDecimal) {
+ this.el_.volume = percentAsDecimal;
+ }
/**
* Get if muted
@@ -503,7 +532,9 @@ class Html5 extends Tech {
* @return {Boolean}
* @method muted
*/
- muted() { return this.el_.muted; }
+ muted() {
+ return this.el_.muted;
+ }
/**
* Set muted
@@ -511,7 +542,9 @@ class Html5 extends Tech {
* @param {Boolean} If player is to be muted or note
* @method setMuted
*/
- setMuted(muted) { this.el_.muted = muted; }
+ setMuted(muted) {
+ this.el_.muted = muted;
+ }
/**
* Get player width
@@ -519,7 +552,9 @@ class Html5 extends Tech {
* @return {Number}
* @method width
*/
- width() { return this.el_.offsetWidth; }
+ width() {
+ return this.el_.offsetWidth;
+ }
/**
* Get player height
@@ -527,7 +562,9 @@ class Html5 extends Tech {
* @return {Number}
* @method height
*/
- height() { return this.el_.offsetHeight; }
+ height() {
+ return this.el_.offsetHeight;
+ }
/**
* Get if there is fullscreen support
@@ -537,9 +574,10 @@ class Html5 extends Tech {
*/
supportsFullScreen() {
if (typeof this.el_.webkitEnterFullScreen === 'function') {
- let userAgent = window.navigator.userAgent;
+ const userAgent = window.navigator.userAgent;
+
// Seems to be broken in Chromium/Chrome && Safari in Leopard
- if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) {
+ if ((/Android/).test(userAgent) || !(/Chrome|Mac OS X 10.5/).test(userAgent)) {
return true;
}
}
@@ -552,7 +590,7 @@ class Html5 extends Tech {
* @method enterFullScreen
*/
enterFullScreen() {
- var video = this.el_;
+ const video = this.el_;
if ('webkitDisplayingFullscreen' in video) {
this.one('webkitbeginfullscreen', function() {
@@ -571,7 +609,7 @@ class Html5 extends Tech {
// playing and pausing synchronously during the transition to fullscreen
// can get iOS ~6.1 devices into a play/pause loop
- this.setTimeout(function(){
+ this.setTimeout(function() {
video.pause();
video.webkitEnterFullScreen();
}, 0);
@@ -599,10 +637,10 @@ class Html5 extends Tech {
src(src) {
if (src === undefined) {
return this.el_.src;
- } else {
- // Setting src through `src` instead of `setSrc` will be deprecated
- this.setSrc(src);
}
+
+ // Setting src through `src` instead of `setSrc` will be deprecated
+ this.setSrc(src);
}
/**
@@ -621,7 +659,7 @@ class Html5 extends Tech {
*
* @method load
*/
- load(){
+ load() {
this.el_.load();
}
@@ -643,9 +681,8 @@ class Html5 extends Tech {
currentSrc() {
if (this.currentSource_) {
return this.currentSource_.src;
- } else {
- return this.el_.currentSrc;
}
+ return this.el_.currentSrc;
}
/**
@@ -654,7 +691,9 @@ class Html5 extends Tech {
* @return {String}
* @method poster
*/
- poster() { return this.el_.poster; }
+ poster() {
+ return this.el_.poster;
+ }
/**
* Set poster
@@ -662,7 +701,9 @@ class Html5 extends Tech {
* @param {String} val URL to poster image
* @method
*/
- setPoster(val) { this.el_.poster = val; }
+ setPoster(val) {
+ this.el_.poster = val;
+ }
/**
* Get preload attribute
@@ -670,7 +711,9 @@ class Html5 extends Tech {
* @return {String}
* @method preload
*/
- preload() { return this.el_.preload; }
+ preload() {
+ return this.el_.preload;
+ }
/**
* Set preload attribute
@@ -678,7 +721,9 @@ class Html5 extends Tech {
* @param {String} val Value for preload attribute
* @method setPreload
*/
- setPreload(val) { this.el_.preload = val; }
+ setPreload(val) {
+ this.el_.preload = val;
+ }
/**
* Get autoplay attribute
@@ -686,7 +731,9 @@ class Html5 extends Tech {
* @return {String}
* @method autoplay
*/
- autoplay() { return this.el_.autoplay; }
+ autoplay() {
+ return this.el_.autoplay;
+ }
/**
* Set autoplay attribute
@@ -694,7 +741,9 @@ class Html5 extends Tech {
* @param {String} val Value for preload attribute
* @method setAutoplay
*/
- setAutoplay(val) { this.el_.autoplay = val; }
+ setAutoplay(val) {
+ this.el_.autoplay = val;
+ }
/**
* Get controls attribute
@@ -702,7 +751,9 @@ class Html5 extends Tech {
* @return {String}
* @method controls
*/
- controls() { return this.el_.controls; }
+ controls() {
+ return this.el_.controls;
+ }
/**
* Set controls attribute
@@ -710,7 +761,9 @@ class Html5 extends Tech {
* @param {String} val Value for controls attribute
* @method setControls
*/
- setControls(val) { this.el_.controls = !!val; }
+ setControls(val) {
+ this.el_.controls = !!val;
+ }
/**
* Get loop attribute
@@ -718,7 +771,9 @@ class Html5 extends Tech {
* @return {String}
* @method loop
*/
- loop() { return this.el_.loop; }
+ loop() {
+ return this.el_.loop;
+ }
/**
* Set loop attribute
@@ -726,7 +781,9 @@ class Html5 extends Tech {
* @param {String} val Value for loop attribute
* @method setLoop
*/
- setLoop(val) { this.el_.loop = val; }
+ setLoop(val) {
+ this.el_.loop = val;
+ }
/**
* Get error value
@@ -734,7 +791,9 @@ class Html5 extends Tech {
* @return {String}
* @method error
*/
- error() { return this.el_.error; }
+ error() {
+ return this.el_.error;
+ }
/**
* Get whether or not the player is in the "seeking" state
@@ -742,7 +801,9 @@ class Html5 extends Tech {
* @return {Boolean}
* @method seeking
*/
- seeking() { return this.el_.seeking; }
+ seeking() {
+ return this.el_.seeking;
+ }
/**
* Get a TimeRanges object that represents the
@@ -752,7 +813,9 @@ class Html5 extends Tech {
* @return {TimeRangeObject}
* @method seekable
*/
- seekable() { return this.el_.seekable; }
+ seekable() {
+ return this.el_.seekable;
+ }
/**
* Get if video ended
@@ -760,7 +823,9 @@ class Html5 extends Tech {
* @return {Boolean}
* @method ended
*/
- ended() { return this.el_.ended; }
+ ended() {
+ return this.el_.ended;
+ }
/**
* Get the value of the muted content attribute
@@ -770,7 +835,9 @@ class Html5 extends Tech {
* @return {Boolean}
* @method defaultMuted
*/
- defaultMuted() { return this.el_.defaultMuted; }
+ defaultMuted() {
+ return this.el_.defaultMuted;
+ }
/**
* Get desired speed at which the media resource is to play
@@ -778,7 +845,9 @@ class Html5 extends Tech {
* @return {Number}
* @method playbackRate
*/
- playbackRate() { return this.el_.playbackRate; }
+ playbackRate() {
+ return this.el_.playbackRate;
+ }
/**
* Returns a TimeRanges object that represents the ranges of the
@@ -787,7 +856,9 @@ class Html5 extends Tech {
* timeline that has been reached through normal playback
* @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-played
*/
- played() { return this.el_.played; }
+ played() {
+ return this.el_.played;
+ }
/**
* Set desired speed at which the media resource is to play
@@ -795,7 +866,9 @@ class Html5 extends Tech {
* @param {Number} val Speed at which the media resource is to play
* @method setPlaybackRate
*/
- setPlaybackRate(val) { this.el_.playbackRate = val; }
+ setPlaybackRate(val) {
+ this.el_.playbackRate = val;
+ }
/**
* Get the current state of network activity for the element, from
@@ -808,7 +881,9 @@ class Html5 extends Tech {
* @return {Number}
* @method networkState
*/
- networkState() { return this.el_.networkState; }
+ networkState() {
+ return this.el_.networkState;
+ }
/**
* Get a value that expresses the current state of the element
@@ -823,7 +898,9 @@ class Html5 extends Tech {
* @return {Number}
* @method readyState
*/
- readyState() { return this.el_.readyState; }
+ readyState() {
+ return this.el_.readyState;
+ }
/**
* Get width of video
@@ -831,7 +908,9 @@ class Html5 extends Tech {
* @return {Number}
* @method videoWidth
*/
- videoWidth() { return this.el_.videoWidth; }
+ videoWidth() {
+ return this.el_.videoWidth;
+ }
/**
* Get height of video
@@ -839,7 +918,9 @@ class Html5 extends Tech {
* @return {Number}
* @method videoHeight
*/
- videoHeight() { return this.el_.videoHeight; }
+ videoHeight() {
+ return this.el_.videoHeight;
+ }
/**
* Get text tracks
@@ -862,7 +943,7 @@ class Html5 extends Tech {
* @method addTextTrack
*/
addTextTrack(kind, label, language) {
- if (!this['featuresNativeTextTracks']) {
+ if (!this.featuresNativeTextTracks) {
return super.addTextTrack(kind, label, language);
}
@@ -877,12 +958,12 @@ class Html5 extends Tech {
* @return {HTMLTrackElement}
* @method addRemoteTextTrack
*/
- addRemoteTextTrack(options={}) {
- if (!this['featuresNativeTextTracks']) {
+ addRemoteTextTrack(options = {}) {
+ if (!this.featuresNativeTextTracks) {
return super.addRemoteTextTrack(options);
}
- let htmlTrackElement = document.createElement('track');
+ const htmlTrackElement = document.createElement('track');
if (options.kind) {
htmlTrackElement.kind = options.kind;
@@ -919,21 +1000,20 @@ class Html5 extends Tech {
* @method removeRemoteTextTrack
*/
removeRemoteTextTrack(track) {
- if (!this['featuresNativeTextTracks']) {
+ if (!this.featuresNativeTextTracks) {
return super.removeRemoteTextTrack(track);
}
- let tracks, i;
-
- let trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
+ const trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
// remove HTMLTrackElement and TextTrack from remote list
this.remoteTextTrackEls().removeTrackElement_(trackElement);
this.remoteTextTracks().removeTrack_(track);
- tracks = this.$$('track');
+ const tracks = this.$$('track');
+
+ let i = tracks.length;
- i = tracks.length;
while (i--) {
if (track === tracks[i] || track === tracks[i].track) {
this.el().removeChild(tracks[i]);
@@ -943,7 +1023,6 @@ class Html5 extends Tech {
}
-
/* HTML5 Support Testing ---------------------------------------------------- */
/*
@@ -954,7 +1033,8 @@ class Html5 extends Tech {
* @private
*/
Html5.TEST_VID = document.createElement('video');
-let track = document.createElement('track');
+const track = document.createElement('track');
+
track.kind = 'captions';
track.srclang = 'en';
track.label = 'English';
@@ -965,10 +1045,10 @@ Html5.TEST_VID.appendChild(track);
*
* @return {Boolean}
*/
-Html5.isSupported = function(){
+Html5.isSupported = function() {
// IE9 with no Media Player is a LIAR! (#984)
try {
- Html5.TEST_VID['volume'] = 0.5;
+ Html5.TEST_VID.volume = 0.5;
} catch (e) {
return false;
}
@@ -994,12 +1074,12 @@ Html5.nativeSourceHandler = {};
* @param {String} type The mimetype to check
* @return {String} 'probably', 'maybe', or '' (empty string)
*/
-Html5.nativeSourceHandler.canPlayType = function(type){
+Html5.nativeSourceHandler.canPlayType = function(type) {
// IE9 on Windows 7 without MediaPlayer throws an error here
// https://github.com/videojs/video.js/issues/519
try {
return Html5.TEST_VID.canPlayType(type);
- } catch(e) {
+ } catch (e) {
return '';
}
};
@@ -1011,15 +1091,15 @@ Html5.nativeSourceHandler.canPlayType = function(type){
* @param {Object} options The options passed to the tech
* @return {String} 'probably', 'maybe', or '' (empty string)
*/
-Html5.nativeSourceHandler.canHandleSource = function(source, options){
- var match, ext;
+Html5.nativeSourceHandler.canHandleSource = function(source, options) {
// If a type was provided we should rely on that
if (source.type) {
return Html5.nativeSourceHandler.canPlayType(source.type);
+
+ // If no type, fall back to checking 'video/[EXTENSION]'
} else if (source.src) {
- // If no type, fall back to checking 'video/[EXTENSION]'
- ext = Url.getFileExtension(source.src);
+ const ext = Url.getFileExtension(source.src);
return Html5.nativeSourceHandler.canPlayType(`video/${ext}`);
}
@@ -1036,7 +1116,7 @@ Html5.nativeSourceHandler.canHandleSource = function(source, options){
* @param {Html5} tech The instance of the Html5 tech
* @param {Object} options The options to pass to the source
*/
-Html5.nativeSourceHandler.handleSource = function(source, tech, options){
+Html5.nativeSourceHandler.handleSource = function(source, tech, options) {
tech.setSrc(source.src);
};
@@ -1044,7 +1124,7 @@ Html5.nativeSourceHandler.handleSource = function(source, tech, options){
* Clean up the source handler when disposing the player or switching sources..
* (no cleanup is needed when supporting the format natively)
*/
-Html5.nativeSourceHandler.dispose = function(){};
+Html5.nativeSourceHandler.dispose = function() {};
// Register the native source handler
Html5.registerSourceHandler(Html5.nativeSourceHandler);
@@ -1056,13 +1136,14 @@ Html5.registerSourceHandler(Html5.nativeSourceHandler);
*
* @return {Boolean}
*/
-Html5.canControlVolume = function(){
+Html5.canControlVolume = function() {
// IE will error if Windows Media Player not installed #3315
try {
- var volume = Html5.TEST_VID.volume;
+ const volume = Html5.TEST_VID.volume;
+
Html5.TEST_VID.volume = (volume / 2) + 0.1;
return volume !== Html5.TEST_VID.volume;
- } catch(e) {
+ } catch (e) {
return false;
}
};
@@ -1072,7 +1153,7 @@ Html5.canControlVolume = function(){
*
* @return {Boolean}
*/
-Html5.canControlPlaybackRate = function(){
+Html5.canControlPlaybackRate = function() {
// Playback rate API is implemented in Android Chrome, but doesn't do anything
// https://github.com/videojs/video.js/issues/3180
if (browser.IS_ANDROID && browser.IS_CHROME) {
@@ -1080,10 +1161,11 @@ Html5.canControlPlaybackRate = function(){
}
// IE will error if Windows Media Player not installed #3315
try {
- var playbackRate = Html5.TEST_VID.playbackRate;
+ const playbackRate = Html5.TEST_VID.playbackRate;
+
Html5.TEST_VID.playbackRate = (playbackRate / 2) + 0.1;
return playbackRate !== Html5.TEST_VID.playbackRate;
- } catch(e) {
+ } catch (e) {
return false;
}
};
@@ -1094,7 +1176,7 @@ Html5.canControlPlaybackRate = function(){
* @return {Boolean}
*/
Html5.supportsNativeTextTracks = function() {
- var supportsTextTracks;
+ let supportsTextTracks;
// Figure out native text track support
// If mode is a number, we cannot change it because it'll disappear from view.
@@ -1103,7 +1185,7 @@ Html5.supportsNativeTextTracks = function() {
// TODO: Investigate firefox: https://github.com/videojs/video.js/issues/1862
supportsTextTracks = !!Html5.TEST_VID.textTracks;
if (supportsTextTracks && Html5.TEST_VID.textTracks.length > 0) {
- supportsTextTracks = typeof Html5.TEST_VID.textTracks[0]['mode'] !== 'number';
+ supportsTextTracks = typeof Html5.TEST_VID.textTracks[0].mode !== 'number';
}
if (supportsTextTracks && browser.IS_FIREFOX) {
supportsTextTracks = false;
@@ -1121,7 +1203,8 @@ Html5.supportsNativeTextTracks = function() {
* @return {Boolean}
*/
Html5.supportsNativeVideoTracks = function() {
- let supportsVideoTracks = !!Html5.TEST_VID.videoTracks;
+ const supportsVideoTracks = !!Html5.TEST_VID.videoTracks;
+
return supportsVideoTracks;
};
@@ -1131,11 +1214,11 @@ Html5.supportsNativeVideoTracks = function() {
* @return {Boolean}
*/
Html5.supportsNativeAudioTracks = function() {
- let supportsAudioTracks = !!Html5.TEST_VID.audioTracks;
+ const supportsAudioTracks = !!Html5.TEST_VID.audioTracks;
+
return supportsAudioTracks;
};
-
/**
* An array of events available on the Html5 tech.
*
@@ -1172,14 +1255,14 @@ Html5.Events = [
*
* @type {Boolean}
*/
-Html5.prototype['featuresVolumeControl'] = Html5.canControlVolume();
+Html5.prototype.featuresVolumeControl = Html5.canControlVolume();
/*
* Set the tech's playbackRate support status
*
* @type {Boolean}
*/
-Html5.prototype['featuresPlaybackRate'] = Html5.canControlPlaybackRate();
+Html5.prototype.featuresPlaybackRate = Html5.canControlPlaybackRate();
/*
* Set the tech's status on moving the video element.
@@ -1187,41 +1270,41 @@ Html5.prototype['featuresPlaybackRate'] = Html5.canControlPlaybackRate();
*
* @type {Boolean}
*/
-Html5.prototype['movingMediaElementInDOM'] = !browser.IS_IOS;
+Html5.prototype.movingMediaElementInDOM = !browser.IS_IOS;
/*
* Set the the tech's fullscreen resize support status.
* HTML video is able to automatically resize when going to fullscreen.
* (No longer appears to be used. Can probably be removed.)
*/
-Html5.prototype['featuresFullscreenResize'] = true;
+Html5.prototype.featuresFullscreenResize = true;
/*
* Set the tech's progress event support status
* (this disables the manual progress events of the Tech)
*/
-Html5.prototype['featuresProgressEvents'] = true;
+Html5.prototype.featuresProgressEvents = true;
/*
* Sets the tech's status on native text track support
*
* @type {Boolean}
*/
-Html5.prototype['featuresNativeTextTracks'] = Html5.supportsNativeTextTracks();
+Html5.prototype.featuresNativeTextTracks = Html5.supportsNativeTextTracks();
/**
* Sets the tech's status on native text track support
*
* @type {Boolean}
*/
-Html5.prototype['featuresNativeVideoTracks'] = Html5.supportsNativeVideoTracks();
+Html5.prototype.featuresNativeVideoTracks = Html5.supportsNativeVideoTracks();
/**
* Sets the tech's status on native audio track support
*
* @type {Boolean}
*/
-Html5.prototype['featuresNativeAudioTracks'] = Html5.supportsNativeAudioTracks();
+Html5.prototype.featuresNativeAudioTracks = Html5.supportsNativeAudioTracks();
// HTML5 Feature detection and Device Fixes --------------------------------- //
let canPlayType;
@@ -1249,7 +1332,7 @@ Html5.patchCanPlayType = function() {
canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType;
}
- Html5.TEST_VID.constructor.prototype.canPlayType = function(type){
+ Html5.TEST_VID.constructor.prototype.canPlayType = function(type) {
if (type && mp4RE.test(type)) {
return 'maybe';
}
@@ -1259,7 +1342,8 @@ Html5.patchCanPlayType = function() {
};
Html5.unpatchCanPlayType = function() {
- var r = Html5.TEST_VID.constructor.prototype.canPlayType;
+ const r = Html5.TEST_VID.constructor.prototype.canPlayType;
+
Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType;
canPlayType = null;
return r;
@@ -1268,15 +1352,17 @@ Html5.unpatchCanPlayType = function() {
// by default, patch the video element
Html5.patchCanPlayType();
-Html5.disposeMediaElement = function(el){
- if (!el) { return; }
+Html5.disposeMediaElement = function(el) {
+ if (!el) {
+ return;
+ }
if (el.parentNode) {
el.parentNode.removeChild(el);
}
// remove any child track or source nodes to prevent their loading
- while(el.hasChildNodes()) {
+ while (el.hasChildNodes()) {
el.removeChild(el.firstChild);
}
@@ -1294,15 +1380,18 @@ Html5.disposeMediaElement = function(el){
} catch (e) {
// not supported
}
- })();
+ }());
}
};
-Html5.resetMediaElement = function(el){
- if (!el) { return; }
+Html5.resetMediaElement = function(el) {
+ if (!el) {
+ return;
+ }
- let sources = el.querySelectorAll('source');
+ const sources = el.querySelectorAll('source');
let i = sources.length;
+
while (i--) {
el.removeChild(sources[i]);
}
@@ -1316,8 +1405,10 @@ Html5.resetMediaElement = function(el){
(function() {
try {
el.load();
- } catch (e) {}
- })();
+ } catch (e) {
+ // satisfy linter
+ }
+ }());
}
};
diff --git a/src/js/tech/loader.js b/src/js/tech/loader.js
index 14bc28c184..0675e4abcb 100644
--- a/src/js/tech/loader.js
+++ b/src/js/tech/loader.js
@@ -3,7 +3,6 @@
*/
import Component from '../component.js';
import Tech from './tech.js';
-import window from 'global/window';
import toTitleCase from '../utils/to-title-case.js';
/**
@@ -18,16 +17,17 @@ import toTitleCase from '../utils/to-title-case.js';
*/
class MediaLoader extends Component {
- constructor(player, options, ready){
+ constructor(player, options, ready) {
super(player, options, ready);
// If there are no sources when the player is initialized,
// load the first supported playback technology.
- if (!options.playerOptions['sources'] || options.playerOptions['sources'].length === 0) {
- for (let i=0, j=options.playerOptions['techOrder']; i {
- let list = this[`${type}Tracks`]() || [];
+ const list = this[`${type}Tracks`]() || [];
let i = list.length;
+
while (i--) {
- let track = list[i];
+ const track = list[i];
+
if (type === 'text') {
this.removeRemoteTextTrack(track);
}
@@ -315,7 +342,9 @@ class Tech extends Component {
*/
setCurrentTime() {
// improve the accuracy of manual timeupdates
- if (this.manualTimeUpdates) { this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true }); }
+ if (this.manualTimeUpdates) {
+ this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
+ }
}
/**
@@ -324,13 +353,15 @@ class Tech extends Component {
* @method initTextTrackListeners
*/
initTextTrackListeners() {
- let textTrackListChanges = Fn.bind(this, function() {
+ const textTrackListChanges = Fn.bind(this, function() {
this.trigger('texttrackchange');
});
- let tracks = this.textTracks();
+ const tracks = this.textTracks();
- if (!tracks) return;
+ if (!tracks) {
+ return;
+ }
tracks.addEventListener('removetrack', textTrackListChanges);
tracks.addEventListener('addtrack', textTrackListChanges);
@@ -341,7 +372,6 @@ class Tech extends Component {
}));
}
-
/**
* Initialize audio and video track listeners
*
@@ -351,11 +381,11 @@ class Tech extends Component {
const trackTypes = ['video', 'audio'];
trackTypes.forEach((type) => {
- let trackListChanges = () => {
+ const trackListChanges = () => {
this.trigger(`${type}trackchange`);
};
- let tracks = this[`${type}Tracks`]();
+ const tracks = this[`${type}Tracks`]();
tracks.addEventListener('removetrack', trackListChanges);
tracks.addEventListener('addtrack', trackListChanges);
@@ -373,13 +403,15 @@ class Tech extends Component {
* @method emulateTextTracks
*/
emulateTextTracks() {
- let tracks = this.textTracks();
+ const tracks = this.textTracks();
+
if (!tracks) {
return;
}
- if (!window['WebVTT'] && this.el().parentNode != null) {
- let script = document.createElement('script');
+ if (!window.WebVTT && this.el().parentNode !== null && this.el().parentNode !== undefined) {
+ const script = document.createElement('script');
+
script.src = this.options_['vtt.js'] || '../node_modules/videojs-vtt.js/dist/vtt.js';
script.onload = () => {
this.trigger('vttjsloaded');
@@ -393,16 +425,17 @@ class Tech extends Component {
});
// but have not loaded yet and we set it to true before the inject so that
// we don't overwrite the injected window.WebVTT if it loads right away
- window['WebVTT'] = true;
+ window.WebVTT = true;
this.el().parentNode.appendChild(script);
}
- let updateDisplay = () => this.trigger('texttrackchange');
- let textTracksChanges = () => {
+ const updateDisplay = () => this.trigger('texttrackchange');
+ const textTracksChanges = () => {
updateDisplay();
for (let i = 0; i < tracks.length; i++) {
- let track = tracks[i];
+ const track = tracks[i];
+
track.removeEventListener('cuechange', updateDisplay);
if (track.mode === 'showing') {
track.addEventListener('cuechange', updateDisplay);
@@ -506,11 +539,11 @@ class Tech extends Component {
* @method addRemoteTextTrack
*/
addRemoteTextTrack(options) {
- let track = mergeOptions(options, {
+ const track = mergeOptions(options, {
tech: this
});
- let htmlTrackElement = new HTMLTrackElement(track);
+ const htmlTrackElement = new HTMLTrackElement(track);
// store HTMLTrackElement and TextTrack to remote list
this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
@@ -531,7 +564,7 @@ class Tech extends Component {
removeRemoteTextTrack(track) {
this.textTracks().removeTrack_(track);
- let trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
+ const trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
// remove HTMLTrackElement and TextTrack from remote list
this.remoteTextTrackEls().removeTrackElement_(trackElement);
@@ -620,7 +653,7 @@ class Tech extends Component {
* @type {TextTrackList}
* @private
*/
-Tech.prototype.textTracks_;
+Tech.prototype.textTracks_; // eslint-disable-line
/**
* List of associated audio tracks
@@ -628,7 +661,7 @@ Tech.prototype.textTracks_;
* @type {AudioTrackList}
* @private
*/
-Tech.prototype.audioTracks_;
+Tech.prototype.audioTracks_; // eslint-disable-line
/**
* List of associated video tracks
@@ -636,27 +669,7 @@ Tech.prototype.audioTracks_;
* @type {VideoTrackList}
* @private
*/
-Tech.prototype.videoTracks_;
-
-
-var createTrackHelper = function(self, kind, label, language, options={}) {
- let tracks = self.textTracks();
-
- options.kind = kind;
-
- if (label) {
- options.label = label;
- }
- if (language) {
- options.language = language;
- }
- options.tech = self;
-
- let track = new TextTrack(options);
- tracks.addTrack_(track);
-
- return track;
-};
+Tech.prototype.videoTracks_; // eslint-disable-line
Tech.prototype.featuresVolumeControl = true;
@@ -671,7 +684,7 @@ Tech.prototype.featuresTimeupdateEvents = false;
Tech.prototype.featuresNativeTextTracks = false;
-/*
+/**
* A functional mixin for techs that want to use the Source Handler pattern.
*
* ##### EXAMPLE:
@@ -679,16 +692,17 @@ Tech.prototype.featuresNativeTextTracks = false;
* Tech.withSourceHandlers.call(MyTech);
*
*/
-Tech.withSourceHandlers = function(_Tech){
- /*
- * Register a source handler
- * Source handlers are scripts for handling specific formats.
- * The source handler pattern is used for adaptive formats (HLS, DASH) that
- * manually load video data and feed it into a Source Buffer (Media Source Extensions)
- * @param {Function} handler The source handler
- * @param {Boolean} first Register it before any existing handlers
- */
- _Tech.registerSourceHandler = function(handler, index){
+Tech.withSourceHandlers = function(_Tech) {
+
+ /**
+ * Register a source handler
+ * Source handlers are scripts for handling specific formats.
+ * The source handler pattern is used for adaptive formats (HLS, DASH) that
+ * manually load video data and feed it into a Source Buffer (Media Source Extensions)
+ * @param {Function} handler The source handler
+ * @param {Boolean} first Register it before any existing handlers
+ */
+ _Tech.registerSourceHandler = function(handler, index) {
let handlers = _Tech.sourceHandlers;
if (!handlers) {
@@ -703,13 +717,13 @@ Tech.withSourceHandlers = function(_Tech){
handlers.splice(index, 0, handler);
};
- /*
+ /**
* Check if the tech can support the given type
* @param {String} type The mimetype to check
* @return {String} 'probably', 'maybe', or '' (empty string)
*/
- _Tech.canPlayType = function(type){
- let handlers = _Tech.sourceHandlers || [];
+ _Tech.canPlayType = function(type) {
+ const handlers = _Tech.sourceHandlers || [];
let can;
for (let i = 0; i < handlers.length; i++) {
@@ -723,16 +737,16 @@ Tech.withSourceHandlers = function(_Tech){
return '';
};
- /*
- * Return the first source handler that supports the source
- * TODO: Answer question: should 'probably' be prioritized over 'maybe'
- * @param {Object} source The source object
- * @param {Object} options The options passed to the tech
- * @returns {Object} The first source handler that supports the source
- * @returns {null} Null if no source handler is found
- */
- _Tech.selectSourceHandler = function(source, options){
- let handlers = _Tech.sourceHandlers || [];
+ /**
+ * Return the first source handler that supports the source
+ * TODO: Answer question: should 'probably' be prioritized over 'maybe'
+ * @param {Object} source The source object
+ * @param {Object} options The options passed to the tech
+ * @returns {Object} The first source handler that supports the source
+ * @returns {null} Null if no source handler is found
+ */
+ _Tech.selectSourceHandler = function(source, options) {
+ const handlers = _Tech.sourceHandlers || [];
let can;
for (let i = 0; i < handlers.length; i++) {
@@ -746,14 +760,14 @@ Tech.withSourceHandlers = function(_Tech){
return null;
};
- /*
+ /**
* Check if the tech can support the given source
* @param {Object} srcObj The source object
* @param {Object} options The options passed to the tech
* @return {String} 'probably', 'maybe', or '' (empty string)
*/
- _Tech.canPlaySource = function(srcObj, options){
- let sh = _Tech.selectSourceHandler(srcObj, options);
+ _Tech.canPlaySource = function(srcObj, options) {
+ const sh = _Tech.selectSourceHandler(srcObj, options);
if (sh) {
return sh.canHandleSource(srcObj, options);
@@ -762,17 +776,17 @@ Tech.withSourceHandlers = function(_Tech){
return '';
};
- /*
+ /**
* When using a source handler, prefer its implementation of
* any function normally provided by the tech.
*/
- let deferrable = [
- 'seekable',
- 'duration'
- ];
+ const deferrable = [
+ 'seekable',
+ 'duration'
+ ];
- deferrable.forEach(function (fnName) {
- let originalFn = this[fnName];
+ deferrable.forEach(function(fnName) {
+ const originalFn = this[fnName];
if (typeof originalFn !== 'function') {
return;
@@ -786,14 +800,14 @@ Tech.withSourceHandlers = function(_Tech){
};
}, _Tech.prototype);
- /*
- * Create a function for setting the source using a source object
- * and source handlers.
- * Should never be called unless a source handler was found.
- * @param {Object} source A source object with src and type keys
- * @return {Tech} self
- */
- _Tech.prototype.setSource = function(source){
+ /**
+ * Create a function for setting the source using a source object
+ * and source handlers.
+ * Should never be called unless a source handler was found.
+ * @param {Object} source A source object with src and type keys
+ * @return {Tech} self
+ */
+ _Tech.prototype.setSource = function(source) {
let sh = _Tech.selectSourceHandler(source, this.options_);
if (!sh) {
diff --git a/src/js/tracks/audio-track-list.js b/src/js/tracks/audio-track-list.js
index d1499bec29..07c072c24d 100644
--- a/src/js/tracks/audio-track-list.js
+++ b/src/js/tracks/audio-track-list.js
@@ -21,6 +21,7 @@ const disableOthers = function(list, track) {
list[i].enabled = false;
}
};
+
/**
* A list of possible audio tracks. All functionality is in the
* base class Tracklist and the spec for AudioTrackList is located at:
@@ -57,12 +58,12 @@ class AudioTrackList extends TrackList {
// as it does not support Object.defineProperty properly
if (browser.IS_IE8) {
list = document.createElement('custom');
- for (let prop in TrackList.prototype) {
+ for (const prop in TrackList.prototype) {
if (prop !== 'constructor') {
list[prop] = TrackList.prototype[prop];
}
}
- for (let prop in AudioTrackList.prototype) {
+ for (const prop in AudioTrackList.prototype) {
if (prop !== 'constructor') {
list[prop] = AudioTrackList.prototype[prop];
}
diff --git a/src/js/tracks/audio-track.js b/src/js/tracks/audio-track.js
index e5f0f7854a..aa8892c18b 100644
--- a/src/js/tracks/audio-track.js
+++ b/src/js/tracks/audio-track.js
@@ -20,16 +20,16 @@ import * as browser from '../utils/browser.js';
*/
class AudioTrack extends Track {
constructor(options = {}) {
- let settings = merge(options, {
+ const settings = merge(options, {
kind: AudioTrackKind[options.kind] || ''
});
// on IE8 this will be a document element
// for every other browser this will be a normal object
- let track = super(settings);
+ const track = super(settings);
let enabled = false;
if (browser.IS_IE8) {
- for (let prop in AudioTrack.prototype) {
+ for (const prop in AudioTrack.prototype) {
if (prop !== 'constructor') {
track[prop] = AudioTrack.prototype[prop];
}
@@ -37,7 +37,9 @@ class AudioTrack extends Track {
}
Object.defineProperty(track, 'enabled', {
- get() { return enabled; },
+ get() {
+ return enabled;
+ },
set(newEnabled) {
// an invalid or unchanged value
if (typeof newEnabled !== 'boolean' || newEnabled === enabled) {
diff --git a/src/js/tracks/html-track-element-list.js b/src/js/tracks/html-track-element-list.js
index 9b38d05820..cbc0ef85c8 100644
--- a/src/js/tracks/html-track-element-list.js
+++ b/src/js/tracks/html-track-element-list.js
@@ -7,12 +7,12 @@ import document from 'global/document';
class HtmlTrackElementList {
constructor(trackElements = []) {
- let list = this;
+ let list = this; // eslint-disable-line
if (browser.IS_IE8) {
list = document.createElement('custom');
- for (let prop in HtmlTrackElementList.prototype) {
+ for (const prop in HtmlTrackElementList.prototype) {
if (prop !== 'constructor') {
list[prop] = HtmlTrackElementList.prototype[prop];
}
diff --git a/src/js/tracks/html-track-element.js b/src/js/tracks/html-track-element.js
index d799375efb..c3e3d393d4 100644
--- a/src/js/tracks/html-track-element.js
+++ b/src/js/tracks/html-track-element.js
@@ -39,20 +39,20 @@ class HTMLTrackElement extends EventTarget {
constructor(options = {}) {
super();
- let readyState,
- trackElement = this;
+ let readyState;
+ let trackElement = this; // eslint-disable-line
if (browser.IS_IE8) {
trackElement = document.createElement('custom');
- for (let prop in HTMLTrackElement.prototype) {
+ for (const prop in HTMLTrackElement.prototype) {
if (prop !== 'constructor') {
trackElement[prop] = HTMLTrackElement.prototype[prop];
}
}
}
- let track = new TextTrack(options);
+ const track = new TextTrack(options);
trackElement.kind = track.kind;
trackElement.src = track.src;
diff --git a/src/js/tracks/text-track-cue-list.js b/src/js/tracks/text-track-cue-list.js
index 3abd7ed069..eef9d559a0 100644
--- a/src/js/tracks/text-track-cue-list.js
+++ b/src/js/tracks/text-track-cue-list.js
@@ -20,12 +20,12 @@ import document from 'global/document';
class TextTrackCueList {
constructor(cues) {
- let list = this;
+ let list = this; // eslint-disable-line
if (browser.IS_IE8) {
list = document.createElement('custom');
- for (let prop in TextTrackCueList.prototype) {
+ for (const prop in TextTrackCueList.prototype) {
if (prop !== 'constructor') {
list[prop] = TextTrackCueList.prototype[prop];
}
@@ -53,14 +53,14 @@ class TextTrackCueList {
* @private
*/
setCues_(cues) {
- let oldLength = this.length || 0;
+ const oldLength = this.length || 0;
let i = 0;
- let l = cues.length;
+ const l = cues.length;
this.cues_ = cues;
this.length_ = cues.length;
- let defineProp = function(index) {
+ const defineProp = function(index) {
if (!('' + index in this)) {
Object.defineProperty(this, '' + index, {
get() {
@@ -90,7 +90,7 @@ class TextTrackCueList {
let result = null;
for (let i = 0, l = this.length; i < l; i++) {
- let cue = this[i];
+ const cue = this[i];
if (cue.id === id) {
result = cue;
diff --git a/src/js/tracks/text-track-display.js b/src/js/tracks/text-track-display.js
index 40ca875b37..995554e5ac 100644
--- a/src/js/tracks/text-track-display.js
+++ b/src/js/tracks/text-track-display.js
@@ -2,28 +2,60 @@
* @file text-track-display.js
*/
import Component from '../component';
-import Menu from '../menu/menu.js';
-import MenuItem from '../menu/menu-item.js';
-import MenuButton from '../menu/menu-button.js';
import * as Fn from '../utils/fn.js';
-import document from 'global/document';
import window from 'global/window';
const darkGray = '#222';
const lightGray = '#ccc';
const fontMap = {
- monospace: 'monospace',
- sansSerif: 'sans-serif',
- serif: 'serif',
- monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace',
- monospaceSerif: '"Courier New", monospace',
+ monospace: 'monospace',
+ sansSerif: 'sans-serif',
+ serif: 'serif',
+ monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace',
+ monospaceSerif: '"Courier New", monospace',
proportionalSansSerif: 'sans-serif',
- proportionalSerif: 'serif',
- casual: '"Comic Sans MS", Impact, fantasy',
- script: '"Monotype Corsiva", cursive',
- smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif'
+ proportionalSerif: 'serif',
+ casual: '"Comic Sans MS", Impact, fantasy',
+ script: '"Monotype Corsiva", cursive',
+ smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif'
};
+/**
+ * Add cue HTML to display
+ *
+ * @param {Number} color Hex number for color, like #f0e
+ * @param {Number} opacity Value for opacity,0.0 - 1.0
+ * @return {RGBAColor} In the form 'rgba(255, 0, 0, 0.3)'
+ * @method constructColor
+ */
+function constructColor(color, opacity) {
+ return 'rgba(' +
+ // color looks like "#f0e"
+ parseInt(color[1] + color[1], 16) + ',' +
+ parseInt(color[2] + color[2], 16) + ',' +
+ parseInt(color[3] + color[3], 16) + ',' +
+ opacity + ')';
+}
+
+/**
+ * Try to update style
+ * Some style changes will throw an error, particularly in IE8. Those should be noops.
+ *
+ * @param {Element} el The element to be styles
+ * @param {CSSProperty} style The CSS property to be styled
+ * @param {CSSStyle} rule The actual style to be applied to the property
+ * @method tryUpdateStyle
+ */
+function tryUpdateStyle(el, style, rule) {
+ try {
+ el.style[style] = rule;
+ } catch (e) {
+
+ // Satisfies linter.
+ return;
+ }
+}
+
/**
* The component for displaying text track cues
*
@@ -35,7 +67,7 @@ const fontMap = {
*/
class TextTrackDisplay extends Component {
- constructor(player, options, ready){
+ constructor(player, options, ready) {
super(player, options, ready);
player.on('loadstart', Fn.bind(this, this.toggleDisplay));
@@ -46,27 +78,28 @@ class TextTrackDisplay extends Component {
// Should probably be moved to an external track loader when we support
// tracks that don't need a display.
player.ready(Fn.bind(this, function() {
- if (player.tech_ && player.tech_['featuresNativeTextTracks']) {
+ if (player.tech_ && player.tech_.featuresNativeTextTracks) {
this.hide();
return;
}
player.on('fullscreenchange', Fn.bind(this, this.updateDisplay));
- let tracks = this.options_.playerOptions['tracks'] || [];
+ const tracks = this.options_.playerOptions.tracks || [];
+
for (let i = 0; i < tracks.length; i++) {
- let track = tracks[i];
- this.player_.addRemoteTextTrack(track);
+ this.player_.addRemoteTextTrack(tracks[i]);
}
- let modes = {'captions': 1, 'subtitles': 1};
- let trackList = this.player_.textTracks();
+ const modes = {captions: 1, subtitles: 1};
+ const trackList = this.player_.textTracks();
let firstDesc;
let firstCaptions;
if (trackList) {
for (let i = 0; i < trackList.length; i++) {
- let track = trackList[i];
+ const track = trackList[i];
+
if (track.default) {
if (track.kind === 'descriptions' && !firstDesc) {
firstDesc = track;
@@ -95,7 +128,7 @@ class TextTrackDisplay extends Component {
* @method toggleDisplay
*/
toggleDisplay() {
- if (this.player_.tech_ && this.player_.tech_['featuresNativeTextTracks']) {
+ if (this.player_.tech_ && this.player_.tech_.featuresNativeTextTracks) {
this.hide();
} else {
this.show();
@@ -123,8 +156,8 @@ class TextTrackDisplay extends Component {
* @method clearDisplay
*/
clearDisplay() {
- if (typeof window['WebVTT'] === 'function') {
- window['WebVTT']['processCues'](window, [], this.el_);
+ if (typeof window.WebVTT === 'function') {
+ window.WebVTT.processCues(window, [], this.el_);
}
}
@@ -134,7 +167,7 @@ class TextTrackDisplay extends Component {
* @method updateDisplay
*/
updateDisplay() {
- var tracks = this.player_.textTracks();
+ const tracks = this.player_.textTracks();
this.clearDisplay();
@@ -150,10 +183,12 @@ class TextTrackDisplay extends Component {
let captionsSubtitlesTrack = null;
let i = tracks.length;
+
while (i--) {
- let track = tracks[i];
- if (track['mode'] === 'showing') {
- if (track['kind'] === 'descriptions') {
+ const track = tracks[i];
+
+ if (track.mode === 'showing') {
+ if (track.kind === 'descriptions') {
descriptionsTrack = track;
} else {
captionsSubtitlesTrack = track;
@@ -175,27 +210,30 @@ class TextTrackDisplay extends Component {
* @method updateForTrack
*/
updateForTrack(track) {
- if (typeof window['WebVTT'] !== 'function' || !track['activeCues']) {
+ if (typeof window.WebVTT !== 'function' || !track.activeCues) {
return;
}
- let overrides = this.player_['textTrackSettings'].getValues();
+ const overrides = this.player_.textTrackSettings.getValues();
+ const cues = [];
- let cues = [];
- for (let i = 0; i < track['activeCues'].length; i++) {
- cues.push(track['activeCues'][i]);
+ for (let i = 0; i < track.activeCues.length; i++) {
+ cues.push(track.activeCues[i]);
}
- window['WebVTT']['processCues'](window, cues, this.el_);
+ window.WebVTT.processCues(window, cues, this.el_);
let i = cues.length;
+
while (i--) {
- let cue = cues[i];
+ const cue = cues[i];
+
if (!cue) {
continue;
}
- let cueDiv = cue.displayState;
+ const cueDiv = cue.displayState;
+
if (overrides.color) {
cueDiv.firstChild.style.color = overrides.color;
}
@@ -236,6 +274,7 @@ class TextTrackDisplay extends Component {
}
if (overrides.fontPercent && overrides.fontPercent !== 1) {
const fontSize = window.parseFloat(cueDiv.style.fontSize);
+
cueDiv.style.fontSize = (fontSize * overrides.fontPercent) + 'px';
cueDiv.style.height = 'auto';
cueDiv.style.top = 'auto';
@@ -253,38 +292,5 @@ class TextTrackDisplay extends Component {
}
-/**
-* Add cue HTML to display
-*
-* @param {Number} color Hex number for color, like #f0e
-* @param {Number} opacity Value for opacity,0.0 - 1.0
-* @return {RGBAColor} In the form 'rgba(255, 0, 0, 0.3)'
-* @method constructColor
-*/
-function constructColor(color, opacity) {
- return 'rgba(' +
- // color looks like "#f0e"
- parseInt(color[1] + color[1], 16) + ',' +
- parseInt(color[2] + color[2], 16) + ',' +
- parseInt(color[3] + color[3], 16) + ',' +
- opacity + ')';
-}
-
-/**
- * Try to update style
- * Some style changes will throw an error, particularly in IE8. Those should be noops.
- *
- * @param {Element} el The element to be styles
- * @param {CSSProperty} style The CSS property to be styled
- * @param {CSSStyle} rule The actual style to be applied to the property
- * @method tryUpdateStyle
- */
-function tryUpdateStyle(el, style, rule) {
- //
- try {
- el.style[style] = rule;
- } catch (e) {}
-}
-
Component.registerComponent('TextTrackDisplay', TextTrackDisplay);
export default TextTrackDisplay;
diff --git a/src/js/tracks/text-track-list-converter.js b/src/js/tracks/text-track-list-converter.js
index b7ab4dd1f5..375e584e32 100644
--- a/src/js/tracks/text-track-list-converter.js
+++ b/src/js/tracks/text-track-list-converter.js
@@ -12,14 +12,16 @@
* @return {Object} a serializable javascript representation of the
* @private
*/
-let trackToJson_ = function(track) {
- let ret = ['kind', 'label', 'language', 'id',
- 'inBandMetadataTrackDispatchType',
- 'mode', 'src'].reduce((acc, prop, i) => {
+const trackToJson_ = function(track) {
+ const ret = [
+ 'kind', 'label', 'language', 'id',
+ 'inBandMetadataTrackDispatchType', 'mode', 'src'
+ ].reduce((acc, prop, i) => {
+
if (track[prop]) {
acc[prop] = track[prop];
}
-
+
return acc;
}, {
cues: track.cues && Array.prototype.map.call(track.cues, function(cue) {
@@ -43,13 +45,14 @@ let trackToJson_ = function(track) {
* @return {Array} a serializable javascript representation of the
* @function textTracksToJson
*/
-let textTracksToJson = function(tech) {
+const textTracksToJson = function(tech) {
- let trackEls = tech.$$('track');
+ const trackEls = tech.$$('track');
+
+ const trackObjs = Array.prototype.map.call(trackEls, (t) => t.track);
+ const tracks = Array.prototype.map.call(trackEls, function(trackEl) {
+ const json = trackToJson_(trackEl.track);
- let trackObjs = Array.prototype.map.call(trackEls, (t) => t.track);
- let tracks = Array.prototype.map.call(trackEls, function(trackEl) {
- let json = trackToJson_(trackEl.track);
if (trackEl.src) {
json.src = trackEl.src;
}
@@ -69,9 +72,10 @@ let textTracksToJson = function(tech) {
* @param tech {tech} the tech to create text tracks on
* @function jsonToTextTracks
*/
-let jsonToTextTracks = function(json, tech) {
+const jsonToTextTracks = function(json, tech) {
json.forEach(function(track) {
- let addedTrack = tech.addRemoteTextTrack(track).track;
+ const addedTrack = tech.addRemoteTextTrack(track).track;
+
if (!track.src && track.cues) {
track.cues.forEach((cue) => addedTrack.addCue(cue));
}
diff --git a/src/js/tracks/text-track-list.js b/src/js/tracks/text-track-list.js
index f316ef8987..58610d2c6c 100644
--- a/src/js/tracks/text-track-list.js
+++ b/src/js/tracks/text-track-list.js
@@ -33,12 +33,12 @@ class TextTrackList extends TrackList {
// as it does not support Object.defineProperty properly
if (browser.IS_IE8) {
list = document.createElement('custom');
- for (let prop in TrackList.prototype) {
+ for (const prop in TrackList.prototype) {
if (prop !== 'constructor') {
list[prop] = TrackList.prototype[prop];
}
}
- for (let prop in TextTrackList.prototype) {
+ for (const prop in TextTrackList.prototype) {
if (prop !== 'constructor') {
list[prop] = TextTrackList.prototype[prop];
}
@@ -102,7 +102,7 @@ class TextTrackList extends TrackList {
let result = null;
for (let i = 0, l = this.length; i < l; i++) {
- let track = this[i];
+ const track = this[i];
if (track.id === id) {
result = track;
diff --git a/src/js/tracks/text-track-settings.js b/src/js/tracks/text-track-settings.js
index 50d845f04b..4e8e21ab87 100644
--- a/src/js/tracks/text-track-settings.js
+++ b/src/js/tracks/text-track-settings.js
@@ -8,6 +8,159 @@ import log from '../utils/log.js';
import safeParseTuple from 'safe-json-parse/tuple';
import window from 'global/window';
+function captionOptionsMenuTemplate(uniqueId, dialogLabelId, dialogDescriptionId) {
+ const template = `
+
+
Captions Settings Dialog
+
Beginning of dialog window. Escape will cancel and close the window.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `;
+
+ return template;
+}
+
+function getSelectedOptionValue(target) {
+ let selectedOption;
+
+ // not all browsers support selectedOptions, so, fallback to options
+ if (target.selectedOptions) {
+ selectedOption = target.selectedOptions[0];
+ } else if (target.options) {
+ selectedOption = target.options[target.options.selectedIndex];
+ }
+
+ return selectedOption.value;
+}
+
+function setSelectedOption(target, value) {
+ if (!value) {
+ return;
+ }
+
+ let i;
+
+ for (i = 0; i < target.options.length; i++) {
+ const option = target.options[i];
+
+ if (option.value === value) {
+ break;
+ }
+ }
+
+ target.selectedIndex = i;
+}
+
/**
* Manipulate settings of texttracks
*
@@ -67,16 +220,16 @@ class TextTrackSettings extends Component {
* @method createEl
*/
createEl() {
- let uniqueId = this.id_;
- let dialogLabelId = 'TTsettingsDialogLabel-' + uniqueId;
- let dialogDescriptionId = 'TTsettingsDialogDescription-' + uniqueId;
+ const uniqueId = this.id_;
+ const dialogLabelId = 'TTsettingsDialogLabel-' + uniqueId;
+ const dialogDescriptionId = 'TTsettingsDialogDescription-' + uniqueId;
return super.createEl('div', {
className: 'vjs-caption-settings vjs-modal-overlay',
innerHTML: captionOptionsMenuTemplate(uniqueId, dialogLabelId, dialogDescriptionId),
tabIndex: -1
}, {
- role: 'dialog',
+ 'role': 'dialog',
'aria-labelledby': dialogLabelId,
'aria-describedby': dialogDescriptionId
});
@@ -106,20 +259,21 @@ class TextTrackSettings extends Component {
const bgOpacity = getSelectedOptionValue(this.$('.vjs-bg-opacity > select'));
const windowColor = getSelectedOptionValue(this.$('.window-color > select'));
const windowOpacity = getSelectedOptionValue(this.$('.vjs-window-opacity > select'));
- const fontPercent = window['parseFloat'](getSelectedOptionValue(this.$('.vjs-font-percent > select')));
-
- let result = {
- 'backgroundOpacity': bgOpacity,
- 'textOpacity': textOpacity,
- 'windowOpacity': windowOpacity,
- 'edgeStyle': textEdge,
- 'fontFamily': fontFamily,
- 'color': fgColor,
- 'backgroundColor': bgColor,
- 'windowColor': windowColor,
- 'fontPercent': fontPercent
+ const fontPercent = window.parseFloat(getSelectedOptionValue(this.$('.vjs-font-percent > select')));
+
+ const result = {
+ fontPercent,
+ fontFamily,
+ textOpacity,
+ windowColor,
+ windowOpacity,
+ backgroundOpacity: bgOpacity,
+ edgeStyle: textEdge,
+ color: fgColor,
+ backgroundColor: bgColor
};
- for (let name in result) {
+
+ for (const name in result) {
if (result[name] === '' || result[name] === 'none' || (name === 'fontPercent' && result[name] === 1.00)) {
delete result[name];
}
@@ -167,7 +321,8 @@ class TextTrackSettings extends Component {
* @method restoreSettings
*/
restoreSettings() {
- let err, values;
+ let err;
+ let values;
try {
[err, values] = safeParseTuple(window.localStorage.getItem('vjs-text-track-settings'));
@@ -194,7 +349,8 @@ class TextTrackSettings extends Component {
return;
}
- let values = this.getValues();
+ const values = this.getValues();
+
try {
if (Object.getOwnPropertyNames(values).length > 0) {
window.localStorage.setItem('vjs-text-track-settings', JSON.stringify(values));
@@ -212,7 +368,8 @@ class TextTrackSettings extends Component {
* @method updateDisplay
*/
updateDisplay() {
- let ttDisplay = this.player_.getChild('textTrackDisplay');
+ const ttDisplay = this.player_.getChild('textTrackDisplay');
+
if (ttDisplay) {
ttDisplay.updateDisplay();
}
@@ -222,154 +379,4 @@ class TextTrackSettings extends Component {
Component.registerComponent('TextTrackSettings', TextTrackSettings);
-function getSelectedOptionValue(target) {
- let selectedOption;
- // not all browsers support selectedOptions, so, fallback to options
- if (target.selectedOptions) {
- selectedOption = target.selectedOptions[0];
- } else if (target.options) {
- selectedOption = target.options[target.options.selectedIndex];
- }
-
- return selectedOption.value;
-}
-
-function setSelectedOption(target, value) {
- if (!value) {
- return;
- }
-
- let i;
- for (i = 0; i < target.options.length; i++) {
- const option = target.options[i];
- if (option.value === value) {
- break;
- }
- }
-
- target.selectedIndex = i;
-}
-
-function captionOptionsMenuTemplate(uniqueId, dialogLabelId, dialogDescriptionId) {
-
- let template = `
-
-
Captions Settings Dialog
-
Beginning of dialog window. Escape will cancel and close the window.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
`;
-
- return template;
-}
-
export default TextTrackSettings;
diff --git a/src/js/tracks/text-track.js b/src/js/tracks/text-track.js
index 582734f3d7..39ec67bc86 100644
--- a/src/js/tracks/text-track.js
+++ b/src/js/tracks/text-track.js
@@ -5,7 +5,6 @@ import TextTrackCueList from './text-track-cue-list';
import * as Fn from '../utils/fn.js';
import {TextTrackKind, TextTrackMode} from './track-enums';
import log from '../utils/log.js';
-import document from 'global/document';
import window from 'global/window';
import Track from './track.js';
import { isCrossOrigin } from '../utils/url.js';
@@ -20,10 +19,10 @@ import * as browser from '../utils/browser.js';
* @param {Track} track track to addcues to
*/
const parseCues = function(srcContent, track) {
- let parser = new window.WebVTT.Parser(window,
+ const parser = new window.WebVTT.Parser(window,
window.vttjs,
window.WebVTT.StringDecoder());
- let errors = [];
+ const errors = [];
parser.oncue = function(cue) {
track.addCue(cue);
@@ -42,12 +41,12 @@ const parseCues = function(srcContent, track) {
parser.parse(srcContent);
if (errors.length > 0) {
- if (console.groupCollapsed) {
- console.groupCollapsed(`Text Track parsing errors for ${track.src}`);
+ if (window.console && window.console.groupCollapsed) {
+ window.console.groupCollapsed(`Text Track parsing errors for ${track.src}`);
}
errors.forEach((error) => log.error(error));
- if (console.groupEnd) {
- console.groupEnd();
+ if (window.console && window.console.groupEnd) {
+ window.console.groupEnd();
}
}
@@ -61,10 +60,10 @@ const parseCues = function(srcContent, track) {
* @param {Track} track track to addcues to
*/
const loadTrack = function(src, track) {
- let opts = {
+ const opts = {
uri: src
};
- let crossOrigin = isCrossOrigin(src);
+ const crossOrigin = isCrossOrigin(src);
if (crossOrigin) {
opts.cors = crossOrigin;
@@ -81,7 +80,8 @@ const loadTrack = function(src, track) {
// NOTE: this is only used for the alt/video.novtt.js build
if (typeof window.WebVTT !== 'function') {
if (track.tech_) {
- let loadHandler = () => parseCues(responseBody, track);
+ const loadHandler = () => parseCues(responseBody, track);
+
track.tech_.on('vttjsloaded', loadHandler);
track.tech_.on('vttjserror', () => {
log.error(`vttjs failed to load, stopping trying to process ${track.src}`);
@@ -129,23 +129,24 @@ class TextTrack extends Track {
throw new Error('A tech was not provided.');
}
- let settings = merge(options, {
+ const settings = merge(options, {
kind: TextTrackKind[options.kind] || 'subtitles',
language: options.language || options.srclang || ''
});
let mode = TextTrackMode[settings.mode] || 'disabled';
- let default_ = settings.default;
+ const default_ = settings.default;
if (settings.kind === 'metadata' || settings.kind === 'chapters') {
mode = 'hidden';
}
// on IE8 this will be a document element
// for every other browser this will be a normal object
- let tt = super(settings);
+ const tt = super(settings);
+
tt.tech_ = settings.tech;
if (browser.IS_IE8) {
- for (let prop in TextTrack.prototype) {
+ for (const prop in TextTrack.prototype) {
if (prop !== 'constructor') {
tt[prop] = TextTrack.prototype[prop];
}
@@ -155,11 +156,17 @@ class TextTrack extends Track {
tt.cues_ = [];
tt.activeCues_ = [];
- let cues = new TextTrackCueList(tt.cues_);
- let activeCues = new TextTrackCueList(tt.activeCues_);
+ const cues = new TextTrackCueList(tt.cues_);
+ const activeCues = new TextTrackCueList(tt.activeCues_);
let changed = false;
- let timeupdateHandler = Fn.bind(tt, function() {
+ const timeupdateHandler = Fn.bind(tt, function() {
+
+ // Accessing this.activeCues for the side-effects of updating itself
+ // due to it's nature as a getter function. Do not remove or cues will
+ // stop updating!
+ /* eslint-disable no-unused-expressions */
this.activeCues;
+ /* eslint-enable no-unused-expressions */
if (changed) {
this.trigger('cuechange');
changed = false;
@@ -215,11 +222,11 @@ class TextTrack extends Track {
return activeCues;
}
- let ct = this.tech_.currentTime();
- let active = [];
+ const ct = this.tech_.currentTime();
+ const active = [];
for (let i = 0, l = this.cues.length; i < l; i++) {
- let cue = this.cues[i];
+ const cue = this.cues[i];
if (cue.startTime <= ct && cue.endTime >= ct) {
active.push(cue);
@@ -267,7 +274,7 @@ class TextTrack extends Track {
* @method addCue
*/
addCue(cue) {
- let tracks = this.tech_.textTracks();
+ const tracks = this.tech_.textTracks();
if (tracks) {
for (let i = 0; i < tracks.length; i++) {
@@ -291,7 +298,7 @@ class TextTrack extends Track {
let removed = false;
for (let i = 0, l = this.cues_.length; i < l; i++) {
- let cue = this.cues_[i];
+ const cue = this.cues_[i];
if (cue === removeCue) {
this.cues_.splice(i, 1);
diff --git a/src/js/tracks/track-enums.js b/src/js/tracks/track-enums.js
index ecab4dd4b3..e11d0d1c81 100644
--- a/src/js/tracks/track-enums.js
+++ b/src/js/tracks/track-enums.js
@@ -21,7 +21,7 @@ const VideoTrackKind = {
main: 'main',
sign: 'sign',
subtitles: 'subtitles',
- commentary: 'commentary',
+ commentary: 'commentary'
};
/**
@@ -38,12 +38,12 @@ const VideoTrackKind = {
* };
*/
const AudioTrackKind = {
- alternative: 'alternative',
- descriptions: 'descriptions',
- main: 'main',
+ 'alternative': 'alternative',
+ 'descriptions': 'descriptions',
+ 'main': 'main',
'main-desc': 'main-desc',
- translation: 'translation',
- commentary: 'commentary',
+ 'translation': 'translation',
+ 'commentary': 'commentary'
};
/**
@@ -65,8 +65,6 @@ const TextTrackKind = {
metadata: 'metadata'
};
-
-
/**
* https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode
*
@@ -78,9 +76,4 @@ const TextTrackMode = {
showing: 'showing'
};
-/* jshint ignore:start */
-// we ignore jshint here because it does not see
-// AudioTrackKind as defined here
export default { VideoTrackKind, AudioTrackKind, TextTrackKind, TextTrackMode };
-/* jshint ignore:end */
-
diff --git a/src/js/tracks/track-list.js b/src/js/tracks/track-list.js
index 3d15e164b3..f71df82f8b 100644
--- a/src/js/tracks/track-list.js
+++ b/src/js/tracks/track-list.js
@@ -2,7 +2,6 @@
* @file track-list.js
*/
import EventTarget from '../event-target';
-import * as Fn from '../utils/fn.js';
import * as browser from '../utils/browser.js';
import document from 'global/document';
@@ -20,10 +19,10 @@ class TrackList extends EventTarget {
constructor(tracks = [], list = null) {
super();
if (!list) {
- list = this;
+ list = this; // eslint-disable-line
if (browser.IS_IE8) {
list = document.createElement('custom');
- for (let prop in TrackList.prototype) {
+ for (const prop in TrackList.prototype) {
if (prop !== 'constructor') {
list[prop] = TrackList.prototype[prop];
}
@@ -53,7 +52,7 @@ class TrackList extends EventTarget {
* @private
*/
addTrack_(track) {
- let index = this.tracks_.length;
+ const index = this.tracks_.length;
if (!('' + index in this)) {
Object.defineProperty(this, index, {
@@ -118,7 +117,8 @@ class TrackList extends EventTarget {
let result = null;
for (let i = 0, l = this.length; i < l; i++) {
- let track = this[i];
+ const track = this[i];
+
if (track.id === id) {
result = track;
break;
@@ -141,7 +141,7 @@ TrackList.prototype.allowedEvents_ = {
};
// emulate attribute EventHandler support to allow for feature detection
-for (let event in TrackList.prototype.allowedEvents_) {
+for (const event in TrackList.prototype.allowedEvents_) {
TrackList.prototype['on' + event] = null;
}
diff --git a/src/js/tracks/track.js b/src/js/tracks/track.js
index 8c8a115350..401ad7193b 100644
--- a/src/js/tracks/track.js
+++ b/src/js/tracks/track.js
@@ -19,26 +19,29 @@ class Track extends EventTarget {
constructor(options = {}) {
super();
- let track = this;
+ let track = this; // eslint-disable-line
+
if (browser.IS_IE8) {
track = document.createElement('custom');
- for (let prop in Track.prototype) {
+ for (const prop in Track.prototype) {
if (prop !== 'constructor') {
track[prop] = Track.prototype[prop];
}
}
}
- let trackProps = {
+ const trackProps = {
id: options.id || 'vjs_track_' + Guid.newGUID(),
kind: options.kind || '',
label: options.label || '',
language: options.language || ''
};
- for (let key in trackProps) {
+ for (const key in trackProps) {
Object.defineProperty(track, key, {
- get() { return trackProps[key]; },
+ get() {
+ return trackProps[key];
+ },
set() {}
});
}
diff --git a/src/js/tracks/video-track-list.js b/src/js/tracks/video-track-list.js
index 89e7cdbfa3..9e68587beb 100644
--- a/src/js/tracks/video-track-list.js
+++ b/src/js/tracks/video-track-list.js
@@ -59,12 +59,12 @@ class VideoTrackList extends TrackList {
// as it does not support Object.defineProperty properly
if (browser.IS_IE8) {
list = document.createElement('custom');
- for (let prop in TrackList.prototype) {
+ for (const prop in TrackList.prototype) {
if (prop !== 'constructor') {
list[prop] = TrackList.prototype[prop];
}
}
- for (let prop in VideoTrackList.prototype) {
+ for (const prop in VideoTrackList.prototype) {
if (prop !== 'constructor') {
list[prop] = VideoTrackList.prototype[prop];
}
diff --git a/src/js/tracks/video-track.js b/src/js/tracks/video-track.js
index fe8f172f53..eafa84f930 100644
--- a/src/js/tracks/video-track.js
+++ b/src/js/tracks/video-track.js
@@ -20,17 +20,17 @@ import * as browser from '../utils/browser.js';
*/
class VideoTrack extends Track {
constructor(options = {}) {
- let settings = merge(options, {
+ const settings = merge(options, {
kind: VideoTrackKind[options.kind] || ''
});
// on IE8 this will be a document element
// for every other browser this will be a normal object
- let track = super(settings);
+ const track = super(settings);
let selected = false;
if (browser.IS_IE8) {
- for (let prop in VideoTrack.prototype) {
+ for (const prop in VideoTrack.prototype) {
if (prop !== 'constructor') {
track[prop] = VideoTrack.prototype[prop];
}
@@ -38,7 +38,9 @@ class VideoTrack extends Track {
}
Object.defineProperty(track, 'selected', {
- get() { return selected; },
+ get() {
+ return selected;
+ },
set(newSelected) {
// an invalid or unchanged value
if (typeof newSelected !== 'boolean' || newSelected === selected) {
diff --git a/src/js/utils/browser.js b/src/js/utils/browser.js
index 9bad972b40..72e52daff0 100644
--- a/src/js/utils/browser.js
+++ b/src/js/utils/browser.js
@@ -24,34 +24,35 @@ export const IS_IPHONE = (/iPhone/i).test(USER_AGENT) && !IS_IPAD;
export const IS_IPOD = (/iPod/i).test(USER_AGENT);
export const IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;
-export const IOS_VERSION = (function(){
- var match = USER_AGENT.match(/OS (\d+)_/i);
- if (match && match[1]) { return match[1]; }
-})();
+export const IOS_VERSION = (function() {
+ const match = USER_AGENT.match(/OS (\d+)_/i);
+
+ if (match && match[1]) {
+ return match[1];
+ }
+}());
export const IS_ANDROID = (/Android/i).test(USER_AGENT);
export const ANDROID_VERSION = (function() {
// This matches Android Major.Minor.Patch versions
// ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
- var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i),
- major,
- minor;
+ const match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);
if (!match) {
return null;
}
- major = match[1] && parseFloat(match[1]);
- minor = match[2] && parseFloat(match[2]);
+ const major = match[1] && parseFloat(match[1]);
+ const minor = match[2] && parseFloat(match[2]);
if (major && minor) {
return parseFloat(match[1] + '.' + match[2]);
} else if (major) {
return major;
- } else {
- return null;
}
-})();
+ return null;
+}());
+
// Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser
export const IS_OLD_ANDROID = IS_ANDROID && (/webkit/i).test(USER_AGENT) && ANDROID_VERSION < 2.3;
export const IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537;
@@ -60,9 +61,9 @@ export const IS_FIREFOX = (/Firefox/i).test(USER_AGENT);
export const IS_EDGE = (/Edge/i).test(USER_AGENT);
export const IS_CHROME = !IS_EDGE && (/Chrome/i).test(USER_AGENT);
export const IS_IE8 = (/MSIE\s8\.0/).test(USER_AGENT);
-export const IE_VERSION = (function(result){
+export const IE_VERSION = (function(result) {
return result && parseFloat(result[1]);
-})((/MSIE\s(\d+)\.\d/).exec(USER_AGENT));
+}((/MSIE\s(\d+)\.\d/).exec(USER_AGENT)));
export const TOUCH_ENABLED = !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch);
export const BACKGROUND_SIZE_SUPPORTED = 'backgroundSize' in document.createElement('video').style;
diff --git a/src/js/utils/buffer.js b/src/js/utils/buffer.js
index 063a9ec95c..4a303aaa25 100644
--- a/src/js/utils/buffer.js
+++ b/src/js/utils/buffer.js
@@ -13,8 +13,9 @@ import { createTimeRange } from './time-ranges.js';
* @function bufferedPercent
*/
export function bufferedPercent(buffered, duration) {
- var bufferedDuration = 0,
- start, end;
+ let bufferedDuration = 0;
+ let start;
+ let end;
if (!duration) {
return 0;
@@ -24,9 +25,9 @@ export function bufferedPercent(buffered, duration) {
buffered = createTimeRange(0, 0);
}
- for (let i = 0; i < buffered.length; i++){
+ for (let i = 0; i < buffered.length; i++) {
start = buffered.start(i);
- end = buffered.end(i);
+ end = buffered.end(i);
// buffered end can be bigger than duration by a very small fraction
if (end > duration) {
diff --git a/src/js/utils/dom.js b/src/js/utils/dom.js
index 3d8fb51679..66fe9f597a 100644
--- a/src/js/utils/dom.js
+++ b/src/js/utils/dom.js
@@ -3,7 +3,7 @@
*/
import document from 'global/document';
import window from 'global/window';
-import * as Guid from './guid.js';
+import * as Guid from './guid.js';
import log from './log.js';
import tsml from 'tsml';
@@ -14,7 +14,7 @@ import tsml from 'tsml';
* @return {Boolean}
*/
function isNonBlankString(str) {
- return typeof str === 'string' && /\S/.test(str);
+ return typeof str === 'string' && (/\S/).test(str);
}
/**
@@ -25,7 +25,7 @@ function isNonBlankString(str) {
* @return {Boolean}
*/
function throwIfWhitespace(str) {
- if (/\s/.test(str)) {
+ if ((/\s/).test(str)) {
throw new Error('class has illegal whitespace characters');
}
}
@@ -40,6 +40,17 @@ function classRegExp(className) {
return new RegExp('(^|\\s)' + className + '($|\\s)');
}
+/**
+ * Determines, via duck typing, whether or not a value is a DOM element.
+ *
+ * @function isEl
+ * @param {Mixed} value
+ * @return {Boolean}
+ */
+export function isEl(value) {
+ return !!value && typeof value === 'object' && value.nodeType === 1;
+}
+
/**
* Creates functions to query the DOM using a given method.
*
@@ -49,7 +60,7 @@ function classRegExp(className) {
* @return {Function}
*/
function createQuerier(method) {
- return function (selector, context) {
+ return function(selector, context) {
if (!isNonBlankString(selector)) {
return document[method](null);
}
@@ -68,7 +79,7 @@ function createQuerier(method) {
* @return {Element} Element with supplied ID
* @function getEl
*/
-export function getEl(id){
+export function getEl(id) {
if (id.indexOf('#') === 0) {
id = id.slice(1);
}
@@ -85,11 +96,11 @@ export function getEl(id){
* @return {Element}
* @function createEl
*/
-export function createEl(tagName='div', properties={}, attributes={}){
- let el = document.createElement(tagName);
+export function createEl(tagName = 'div', properties = {}, attributes = {}) {
+ const el = document.createElement(tagName);
- Object.getOwnPropertyNames(properties).forEach(function(propName){
- let val = properties[propName];
+ Object.getOwnPropertyNames(properties).forEach(function(propName) {
+ const val = properties[propName];
// See #2176
// We originally were accepting both properties and attributes in the
@@ -104,8 +115,7 @@ export function createEl(tagName='div', properties={}, attributes={}){
}
});
- Object.getOwnPropertyNames(attributes).forEach(function(attrName){
- let val = attributes[attrName];
+ Object.getOwnPropertyNames(attributes).forEach(function(attrName) {
el.setAttribute(attrName, attributes[attrName]);
});
@@ -136,7 +146,7 @@ export function textContent(el, text) {
* @private
* @function insertElFirst
*/
-export function insertElFirst(child, parent){
+export function insertElFirst(child, parent) {
if (parent.firstChild) {
parent.insertBefore(child, parent.firstChild);
} else {
@@ -210,7 +220,7 @@ export function hasElData(el) {
* @function removeElData
*/
export function removeElData(el) {
- let id = el[elIdAttr];
+ const id = el[elIdAttr];
if (!id) {
return;
@@ -222,7 +232,7 @@ export function removeElData(el) {
// Remove the elIdAttr property from the DOM node
try {
delete el[elIdAttr];
- } catch(e) {
+ } catch (e) {
if (el.removeAttribute) {
el.removeAttribute(elIdAttr);
} else {
@@ -242,10 +252,9 @@ export function removeElData(el) {
export function hasElClass(element, classToCheck) {
if (element.classList) {
return element.classList.contains(classToCheck);
- } else {
- throwIfWhitespace(classToCheck);
- return classRegExp(classToCheck).test(element.className);
}
+ throwIfWhitespace(classToCheck);
+ return classRegExp(classToCheck).test(element.className);
}
/**
@@ -305,7 +314,7 @@ export function toggleElClass(element, classToToggle, predicate) {
// This CANNOT use `classList` internally because IE does not support the
// second parameter to the `classList.toggle()` method! Which is fine because
// `classList` will be used by the add/remove functions.
- let has = hasElClass(element, classToToggle);
+ const has = hasElClass(element, classToToggle);
if (typeof predicate === 'function') {
predicate = predicate(element, classToToggle);
@@ -339,8 +348,8 @@ export function toggleElClass(element, classToToggle, predicate) {
* @function setElAttributes
*/
export function setElAttributes(el, attributes) {
- Object.getOwnPropertyNames(attributes).forEach(function(attrName){
- let attrValue = attributes[attrName];
+ Object.getOwnPropertyNames(attributes).forEach(function(attrName) {
+ const attrValue = attributes[attrName];
if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
el.removeAttribute(attrName);
@@ -362,25 +371,23 @@ export function setElAttributes(el, attributes) {
* @function getElAttributes
*/
export function getElAttributes(tag) {
- var obj, knownBooleans, attrs, attrName, attrVal;
-
- obj = {};
+ const obj = {};
// known boolean attributes
// we can check for matching boolean properties, but older browsers
// won't know about HTML5 boolean attributes that we still read from
- knownBooleans = ','+'autoplay,controls,loop,muted,default'+',';
+ const knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ',';
if (tag && tag.attributes && tag.attributes.length > 0) {
- attrs = tag.attributes;
+ const attrs = tag.attributes;
- for (var i = attrs.length - 1; i >= 0; i--) {
- attrName = attrs[i].name;
- attrVal = attrs[i].value;
+ for (let i = attrs.length - 1; i >= 0; i--) {
+ const attrName = attrs[i].name;
+ let attrVal = attrs[i].value;
// check for known booleans
// the matching element property will return a value for typeof
- if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(','+attrName+',') !== -1) {
+ if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {
// the value of an included boolean attribute is typically an empty
// string ('') which would equal false if we just check for a false value.
// we also don't want support bad code like autoplay='false'
@@ -471,13 +478,13 @@ export function findElPosition(el) {
* @return {Object} This object will have x and y coordinates corresponding to the mouse position
*/
export function getPointerPosition(el, event) {
- let position = {};
- let box = findElPosition(el);
- let boxW = el.offsetWidth;
- let boxH = el.offsetHeight;
+ const position = {};
+ const box = findElPosition(el);
+ const boxW = el.offsetWidth;
+ const boxH = el.offsetHeight;
- let boxY = box.top;
- let boxX = box.left;
+ const boxY = box.top;
+ const boxX = box.left;
let pageY = event.pageY;
let pageX = event.pageX;
@@ -492,17 +499,6 @@ export function getPointerPosition(el, event) {
return position;
}
-/**
- * Determines, via duck typing, whether or not a value is a DOM element.
- *
- * @function isEl
- * @param {Mixed} value
- * @return {Boolean}
- */
-export function isEl(value) {
- return !!value && typeof value === 'object' && value.nodeType === 1;
-}
-
/**
* Determines, via duck typing, whether or not a value is a text node.
*
@@ -577,7 +573,7 @@ export function normalizeContent(content) {
return value;
}
- if (typeof value === 'string' && /\S/.test(value)) {
+ if (typeof value === 'string' && (/\S/).test(value)) {
return document.createTextNode(value);
}
}).filter(value => value);
diff --git a/src/js/utils/events.js b/src/js/utils/events.js
index 4c9ca211d1..febd27cc27 100644
--- a/src/js/utils/events.js
+++ b/src/js/utils/events.js
@@ -7,11 +7,193 @@
* 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';
+/**
+ * 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) {
+ const data = Dom.getElData(elem);
+
+ // Remove the events of a particular type if there are none left
+ if (data.handlers[type].length === 0) {
+ delete data.handlers[type];
+ // data.handlers[type] = null;
+ // Setting to null was causing an error with data.handlers
+
+ // Remove the meta-handler from the element
+ if (elem.removeEventListener) {
+ elem.removeEventListener(type, data.dispatcher, false);
+ } else if (elem.detachEvent) {
+ elem.detachEvent('on' + type, data.dispatcher);
+ }
+ }
+
+ // Remove the events object if there are no types left
+ if (Object.getOwnPropertyNames(data.handlers).length <= 0) {
+ delete data.handlers;
+ delete data.dispatcher;
+ delete data.disabled;
+ }
+
+ // Finally remove the element data if there is no data left
+ if (Object.getOwnPropertyNames(data).length === 0) {
+ Dom.removeElData(elem);
+ }
+}
+
+/**
+ * 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) {
+ // Call the event method for each one of the types
+ fn(elem, type, callback);
+ });
+}
+
+/**
+ * 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) {
+
+ function returnTrue() {
+ return true;
+ }
+
+ function returnFalse() {
+ return false;
+ }
+
+ // Test if fixing up is needed
+ // Used to check if !event.stopPropagation instead of isPropagationStopped
+ // But native events return true for stopPropagation, but don't have
+ // other expected methods like isPropagationStopped. Seems to be a problem
+ // with the Javascript Ninja code. So we're just overriding all events now.
+ if (!event || !event.isPropagationStopped) {
+ const old = event || window.event;
+
+ event = {};
+ // Clone the old object so that we can modify the values event = {};
+ // IE8 Doesn't like when you mess with native event properties
+ // Firefox returns false for event.hasOwnProperty('type') and other props
+ // which makes copying more difficult.
+ // TODO: Probably best to create a whitelist of event props
+ for (const key in old) {
+ // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
+ // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation
+ // and webkitMovementX/Y
+ if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' &&
+ key !== 'webkitMovementX' && key !== 'webkitMovementY') {
+ // Chrome 32+ warns if you try to copy deprecated returnValue, but
+ // we still want to if preventDefault isn't supported (IE8).
+ if (!(key === 'returnValue' && old.preventDefault)) {
+ event[key] = old[key];
+ }
+ }
+ }
+
+ // The event occurred on this element
+ if (!event.target) {
+ event.target = event.srcElement || document;
+ }
+
+ // Handle which other element the event is related to
+ if (!event.relatedTarget) {
+ event.relatedTarget = event.fromElement === event.target ?
+ event.toElement :
+ event.fromElement;
+ }
+
+ // Stop the default browser action
+ event.preventDefault = function() {
+ if (old.preventDefault) {
+ old.preventDefault();
+ }
+ event.returnValue = false;
+ old.returnValue = false;
+ event.defaultPrevented = true;
+ };
+
+ event.defaultPrevented = false;
+
+ // Stop the event from bubbling
+ event.stopPropagation = function() {
+ if (old.stopPropagation) {
+ old.stopPropagation();
+ }
+ event.cancelBubble = true;
+ old.cancelBubble = true;
+ event.isPropagationStopped = returnTrue;
+ };
+
+ event.isPropagationStopped = returnFalse;
+
+ // Stop the event from bubbling and executing other handlers
+ event.stopImmediatePropagation = function() {
+ if (old.stopImmediatePropagation) {
+ old.stopImmediatePropagation();
+ }
+ event.isImmediatePropagationStopped = returnTrue;
+ event.stopPropagation();
+ };
+
+ event.isImmediatePropagationStopped = returnFalse;
+
+ // Handle mouse position
+ if (event.clientX !== null && event.clientX !== undefined) {
+ const doc = document.documentElement;
+ const body = document.body;
+
+ event.pageX = event.clientX +
+ (doc && doc.scrollLeft || body && body.scrollLeft || 0) -
+ (doc && doc.clientLeft || body && body.clientLeft || 0);
+ event.pageY = event.clientY +
+ (doc && doc.scrollTop || body && body.scrollTop || 0) -
+ (doc && doc.clientTop || body && body.clientTop || 0);
+ }
+
+ // Handle key presses
+ event.which = event.charCode || event.keyCode;
+
+ // Fix button for mouse clicks:
+ // 0 == left; 1 == middle; 2 == right
+ if (event.button !== null && event.button !== undefined) {
+
+ // The following is disabled because it does not pass videojs-standard
+ // and... yikes.
+ /* eslint-disable */
+ event.button = (event.button & 1 ? 0 :
+ (event.button & 4 ? 1 :
+ (event.button & 2 ? 2 : 0)));
+ /* eslint-enable */
+ }
+ }
+
+ // Returns fixed-up instance
+ return event;
+}
+
/**
* Add an event listener to element
* It stores the handler function in a separate cache object
@@ -23,37 +205,46 @@ import document from 'global/document';
* @param {Function} fn Event listener.
* @method on
*/
-export function on(elem, type, fn){
+export function on(elem, type, fn) {
if (Array.isArray(type)) {
return _handleMultipleEvents(on, elem, type, fn);
}
- let data = Dom.getElData(elem);
+ const data = Dom.getElData(elem);
// We need a place to store all our handler data
- if (!data.handlers) data.handlers = {};
+ if (!data.handlers) {
+ data.handlers = {};
+ }
- if (!data.handlers[type]) data.handlers[type] = [];
+ if (!data.handlers[type]) {
+ data.handlers[type] = [];
+ }
- if (!fn.guid) fn.guid = Guid.newGUID();
+ if (!fn.guid) {
+ fn.guid = Guid.newGUID();
+ }
data.handlers[type].push(fn);
if (!data.dispatcher) {
data.disabled = false;
- data.dispatcher = function (event, hash){
+ data.dispatcher = function(event, hash) {
+
+ if (data.disabled) {
+ return;
+ }
- if (data.disabled) return;
event = fixEvent(event);
- var handlers = data.handlers[event.type];
+ const handlers = data.handlers[event.type];
if (handlers) {
// Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.
- var handlersCopy = handlers.slice(0);
+ const handlersCopy = handlers.slice(0);
- for (var m = 0, n = handlersCopy.length; m < n; m++) {
+ for (let m = 0, n = handlersCopy.length; m < n; m++) {
if (event.isImmediatePropagationStopped()) {
break;
} else {
@@ -83,33 +274,41 @@ export function on(elem, type, fn){
*/
export function off(elem, type, fn) {
// Don't want to add a cache object through getElData if not needed
- if (!Dom.hasElData(elem)) return;
+ if (!Dom.hasElData(elem)) {
+ return;
+ }
- let data = Dom.getElData(elem);
+ const data = Dom.getElData(elem);
// If no events exist, nothing to unbind
- if (!data.handlers) { return; }
+ if (!data.handlers) {
+ return;
+ }
if (Array.isArray(type)) {
return _handleMultipleEvents(off, elem, type, fn);
}
// Utility function
- var removeType = function(t){
- data.handlers[t] = [];
- _cleanUpEvents(elem,t);
+ const removeType = function(t) {
+ data.handlers[t] = [];
+ _cleanUpEvents(elem, t);
};
// Are we removing all bound events?
if (!type) {
- for (let t in data.handlers) removeType(t);
+ for (const t in data.handlers) {
+ removeType(t);
+ }
return;
}
- var handlers = data.handlers[type];
+ const handlers = data.handlers[type];
// If no handlers exist, nothing to unbind
- if (!handlers) return;
+ if (!handlers) {
+ return;
+ }
// If no listener was provided, remove all listeners for type
if (!fn) {
@@ -142,14 +341,14 @@ export function trigger(elem, event, hash) {
// Fetches element data and a reference to the parent (for bubbling).
// Don't want to add a data object to cache for every parent,
// so checking hasElData first.
- var elemData = (Dom.hasElData(elem)) ? Dom.getElData(elem) : {};
- var parent = elem.parentNode || elem.ownerDocument;
+ const elemData = (Dom.hasElData(elem)) ? Dom.getElData(elem) : {};
+ const parent = elem.parentNode || elem.ownerDocument;
// type = event.type || event,
// handler;
// If an event name was passed as a string, creates an event out of it
if (typeof event === 'string') {
- event = { type:event, target:elem };
+ event = {type: event, target: elem};
}
// Normalizes the event properties.
event = fixEvent(event);
@@ -160,13 +359,13 @@ export function trigger(elem, event, hash) {
}
// Unless explicitly stopped or the event does not bubble (e.g. media events)
- // recursively calls this function to bubble the event up the DOM.
- if (parent && !event.isPropagationStopped() && event.bubbles === true) {
- trigger.call(null, parent, event, hash);
+ // recursively calls this function to bubble the event up the DOM.
+ if (parent && !event.isPropagationStopped() && event.bubbles === true) {
+ trigger.call(null, parent, event, hash);
// If at the top of the DOM, triggers the default action unless disabled.
} else if (!parent && !event.defaultPrevented) {
- var targetData = Dom.getElData(event.target);
+ const targetData = Dom.getElData(event.target);
// Checks if the target has a default action for this event.
if (event.target[event.type]) {
@@ -197,182 +396,12 @@ export function one(elem, type, fn) {
if (Array.isArray(type)) {
return _handleMultipleEvents(one, elem, type, fn);
}
- var func = function(){
+ const func = function() {
off(elem, type, func);
fn.apply(this, arguments);
};
+
// copy the guid to the new function so it can removed using the original function's ID
func.guid = fn.guid = fn.guid || Guid.newGUID();
on(elem, type, func);
}
-
-/**
- * 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) {
-
- function returnTrue() { return true; }
- function returnFalse() { return false; }
-
- // Test if fixing up is needed
- // Used to check if !event.stopPropagation instead of isPropagationStopped
- // But native events return true for stopPropagation, but don't have
- // other expected methods like isPropagationStopped. Seems to be a problem
- // with the Javascript Ninja code. So we're just overriding all events now.
- if (!event || !event.isPropagationStopped) {
- var old = event || window.event;
-
- event = {};
- // Clone the old object so that we can modify the values event = {};
- // IE8 Doesn't like when you mess with native event properties
- // Firefox returns false for event.hasOwnProperty('type') and other props
- // which makes copying more difficult.
- // TODO: Probably best to create a whitelist of event props
- for (var key in old) {
- // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
- // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation
- // and webkitMovementX/Y
- if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' &&
- key !== 'webkitMovementX' && key !== 'webkitMovementY') {
- // Chrome 32+ warns if you try to copy deprecated returnValue, but
- // we still want to if preventDefault isn't supported (IE8).
- if (!(key === 'returnValue' && old.preventDefault)) {
- event[key] = old[key];
- }
- }
- }
-
- // The event occurred on this element
- if (!event.target) {
- event.target = event.srcElement || document;
- }
-
- // Handle which other element the event is related to
- if (!event.relatedTarget) {
- event.relatedTarget = event.fromElement === event.target ?
- event.toElement :
- event.fromElement;
- }
-
- // Stop the default browser action
- event.preventDefault = function () {
- if (old.preventDefault) {
- old.preventDefault();
- }
- event.returnValue = false;
- old.returnValue = false;
- event.defaultPrevented = true;
- };
-
- event.defaultPrevented = false;
-
- // Stop the event from bubbling
- event.stopPropagation = function () {
- if (old.stopPropagation) {
- old.stopPropagation();
- }
- event.cancelBubble = true;
- old.cancelBubble = true;
- event.isPropagationStopped = returnTrue;
- };
-
- event.isPropagationStopped = returnFalse;
-
- // Stop the event from bubbling and executing other handlers
- event.stopImmediatePropagation = function () {
- if (old.stopImmediatePropagation) {
- old.stopImmediatePropagation();
- }
- event.isImmediatePropagationStopped = returnTrue;
- event.stopPropagation();
- };
-
- event.isImmediatePropagationStopped = returnFalse;
-
- // Handle mouse position
- if (event.clientX != null) {
- var doc = document.documentElement, body = document.body;
-
- event.pageX = event.clientX +
- (doc && doc.scrollLeft || body && body.scrollLeft || 0) -
- (doc && doc.clientLeft || body && body.clientLeft || 0);
- event.pageY = event.clientY +
- (doc && doc.scrollTop || body && body.scrollTop || 0) -
- (doc && doc.clientTop || body && body.clientTop || 0);
- }
-
- // Handle key presses
- event.which = event.charCode || event.keyCode;
-
- // Fix button for mouse clicks:
- // 0 == left; 1 == middle; 2 == right
- if (event.button != null) {
- event.button = (event.button & 1 ? 0 :
- (event.button & 4 ? 1 :
- (event.button & 2 ? 2 : 0)));
- }
- }
-
- // Returns fixed-up instance
- return 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);
-
- // Remove the events of a particular type if there are none left
- if (data.handlers[type].length === 0) {
- delete data.handlers[type];
- // data.handlers[type] = null;
- // Setting to null was causing an error with data.handlers
-
- // Remove the meta-handler from the element
- if (elem.removeEventListener) {
- elem.removeEventListener(type, data.dispatcher, false);
- } else if (elem.detachEvent) {
- elem.detachEvent('on' + type, data.dispatcher);
- }
- }
-
- // Remove the events object if there are no types left
- if (Object.getOwnPropertyNames(data.handlers).length <= 0) {
- delete data.handlers;
- delete data.dispatcher;
- delete data.disabled;
- }
-
- // Finally remove the element data if there is no data left
- if (Object.getOwnPropertyNames(data).length === 0) {
- Dom.removeElData(elem);
- }
-}
-
-/**
- * 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) {
- //Call the event method for each one of the types
- fn(elem, type, callback);
- });
-}
diff --git a/src/js/utils/fn.js b/src/js/utils/fn.js
index 69bbe83ad8..a492fe1d50 100644
--- a/src/js/utils/fn.js
+++ b/src/js/utils/fn.js
@@ -16,10 +16,12 @@ import { newGUID } from './guid.js';
*/
export const bind = function(context, fn, uid) {
// Make sure the function has a unique ID
- if (!fn.guid) { fn.guid = newGUID(); }
+ if (!fn.guid) {
+ fn.guid = newGUID();
+ }
// Create the new function that changes the context
- let ret = function() {
+ const ret = function() {
return fn.apply(context, arguments);
};
diff --git a/src/js/utils/format-time.js b/src/js/utils/format-time.js
index dc6182c9c4..bd47c68079 100644
--- a/src/js/utils/format-time.js
+++ b/src/js/utils/format-time.js
@@ -11,7 +11,7 @@
* @private
* @function formatTime
*/
-function formatTime(seconds, guide=seconds) {
+function formatTime(seconds, guide = seconds) {
seconds = seconds < 0 ? 0 : seconds;
let s = Math.floor(seconds % 60);
let m = Math.floor(seconds / 60 % 60);
diff --git a/src/js/utils/guid.js b/src/js/utils/guid.js
index e832e7088b..3a124d8fc7 100644
--- a/src/js/utils/guid.js
+++ b/src/js/utils/guid.js
@@ -10,7 +10,7 @@ let _guid = 1;
/**
* Get the next unique ID
*
- * @return {String}
+ * @return {String}
* @function newGUID
*/
export function newGUID() {
diff --git a/src/js/utils/log.js b/src/js/utils/log.js
index 332cda6e73..fca15985b2 100644
--- a/src/js/utils/log.js
+++ b/src/js/utils/log.js
@@ -4,6 +4,8 @@
import window from 'global/window';
import {IE_VERSION} from './browser';
+let log;
+
/**
* Log messages to the console and history based on the type of message
*
@@ -16,7 +18,6 @@ import {IE_VERSION} from './browser';
* but this is exposed as a parameter to facilitate testing.
*/
export const logByType = (type, args, stringify = !!IE_VERSION && IE_VERSION < 11) => {
- const console = window.console;
// If there's no console then don't try to output messages, but they will
// still be stored in `log.history`.
@@ -24,7 +25,7 @@ export const logByType = (type, args, stringify = !!IE_VERSION && IE_VERSION < 1
// Was setting these once outside of this function, but containing them
// in the function makes it easier to test cases where console doesn't exist
// when the module is executed.
- const fn = console && console[type] || function(){};
+ const fn = window.console && window.console[type] || function() {};
if (type !== 'log') {
@@ -45,7 +46,9 @@ export const logByType = (type, args, stringify = !!IE_VERSION && IE_VERSION < 1
if (a && typeof a === 'object' || Array.isArray(a)) {
try {
return JSON.stringify(a);
- } catch (x) {}
+ } catch (x) {
+ return String(a);
+ }
}
// Cast to string before joining, so we get null and undefined explicitly
@@ -68,9 +71,9 @@ export const logByType = (type, args, stringify = !!IE_VERSION && IE_VERSION < 1
*
* @function log
*/
-function log(...args) {
+log = function(...args) {
logByType('log', args);
-}
+};
/**
* Keep a history of log messages
@@ -93,5 +96,4 @@ log.error = (...args) => logByType('error', args);
*/
log.warn = (...args) => logByType('warn', args);
-
export default log;
diff --git a/src/js/utils/merge-options.js b/src/js/utils/merge-options.js
index ac3558a9ed..91dea8fb9a 100644
--- a/src/js/utils/merge-options.js
+++ b/src/js/utils/merge-options.js
@@ -4,10 +4,10 @@
import merge from 'lodash-compat/object/merge';
function isPlain(obj) {
- return !!obj
- && typeof obj === 'object'
- && obj.toString() === '[object Object]'
- && obj.constructor === Object;
+ return !!obj &&
+ typeof obj === 'object' &&
+ obj.toString() === '[object Object]' &&
+ obj.constructor === Object;
}
/**
@@ -15,7 +15,7 @@ function isPlain(obj) {
* (like arrays) instead of attempting to overlay them.
* @see https://lodash.com/docs#merge
*/
-const customizer = function(destination, source) {
+function customizer(destination, source) {
// If we're not working with a plain object, copy the value as is
// If source is an array, for instance, it will replace destination
if (!isPlain(source)) {
@@ -30,7 +30,7 @@ const customizer = function(destination, source) {
if (!isPlain(destination)) {
return mergeOptions(source);
}
-};
+}
/**
* Merge one or more options objects, recursively merging **only**
@@ -44,7 +44,7 @@ const customizer = function(destination, source) {
export default function mergeOptions() {
// contruct the call dynamically to handle the variable number of
// objects to merge
- let args = Array.prototype.slice.call(arguments);
+ const args = Array.prototype.slice.call(arguments);
// unshift an empty object into the front of the call as the target
// of the merge
diff --git a/src/js/utils/stylesheet.js b/src/js/utils/stylesheet.js
index b06f2bc3d8..bef2da4081 100644
--- a/src/js/utils/stylesheet.js
+++ b/src/js/utils/stylesheet.js
@@ -1,13 +1,14 @@
import document from 'global/document';
-export let createStyleElement = function(className) {
- let style = document.createElement('style');
+export const createStyleElement = function(className) {
+ const style = document.createElement('style');
+
style.className = className;
return style;
};
-export let setTextContent = function(el, content) {
+export const setTextContent = function(el, content) {
if (el.styleSheet) {
el.styleSheet.cssText = content;
} else {
diff --git a/src/js/utils/time-ranges.js b/src/js/utils/time-ranges.js
index 1f17619665..f81c71db1c 100644
--- a/src/js/utils/time-ranges.js
+++ b/src/js/utils/time-ranges.js
@@ -1,37 +1,28 @@
import log from './log.js';
-/**
- * @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|Array)} Start of a single range or an array of ranges
- * @param {Number} End of a single range
- * @private
- * @method createTimeRanges
- */
-export function createTimeRanges(start, end){
- if (Array.isArray(start)) {
- return createTimeRangesObj(start);
- } else if (start === undefined || end === undefined) {
- return createTimeRangesObj();
+function rangeCheck(fnName, index, maxIndex) {
+ if (index < 0 || index > maxIndex) {
+ throw new Error(`Failed to execute '${fnName}' on 'TimeRanges': The index provided (${index}) is greater than or equal to the maximum bound (${maxIndex}).`);
}
- return createTimeRangesObj([[start, end]]);
}
-export { createTimeRanges as createTimeRange };
+function getRange(fnName, valueIndex, ranges, rangeIndex) {
+ if (rangeIndex === undefined) {
+ log.warn(`DEPRECATED: Function '${fnName}' on 'TimeRanges' called without an index argument.`);
+ rangeIndex = 0;
+ }
+ rangeCheck(fnName, rangeIndex, ranges.length - 1);
+ return ranges[rangeIndex][valueIndex];
+}
-function createTimeRangesObj(ranges){
+function createTimeRangesObj(ranges) {
if (ranges === undefined || ranges.length === 0) {
return {
length: 0,
- start: function() {
+ start() {
throw new Error('This TimeRanges object is empty');
},
- end: function() {
+ end() {
throw new Error('This TimeRanges object is empty');
}
};
@@ -43,17 +34,26 @@ function createTimeRangesObj(ranges){
};
}
-function getRange(fnName, valueIndex, ranges, rangeIndex){
- if (rangeIndex === undefined) {
- log.warn(`DEPRECATED: Function '${fnName}' on 'TimeRanges' called without an index argument.`);
- rangeIndex = 0;
+/**
+ * @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|Array)} Start of a single range or an array of ranges
+ * @param {Number} End of a single range
+ * @private
+ * @method createTimeRanges
+ */
+export function createTimeRanges(start, end) {
+ if (Array.isArray(start)) {
+ return createTimeRangesObj(start);
+ } else if (start === undefined || end === undefined) {
+ return createTimeRangesObj();
}
- rangeCheck(fnName, rangeIndex, ranges.length - 1);
- return ranges[rangeIndex][valueIndex];
+ return createTimeRangesObj([[start, end]]);
}
-function rangeCheck(fnName, index, maxIndex){
- if (index < 0 || index > maxIndex) {
- throw new Error(`Failed to execute '${fnName}' on 'TimeRanges': The index provided (${index}) is greater than or equal to the maximum bound (${maxIndex}).`);
- }
-}
+export { createTimeRanges as createTimeRange };
diff --git a/src/js/utils/to-title-case.js b/src/js/utils/to-title-case.js
index f3984f8190..c9f97b88e1 100644
--- a/src/js/utils/to-title-case.js
+++ b/src/js/utils/to-title-case.js
@@ -8,7 +8,7 @@
* @private
* @method toTitleCase
*/
-function toTitleCase(string){
+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 6532c28fe4..d294273583 100644
--- a/src/js/utils/url.js
+++ b/src/js/utils/url.js
@@ -16,13 +16,15 @@ export const parseUrl = function(url) {
// add the url to an anchor and let the browser parse the URL
let a = document.createElement('a');
+
a.href = url;
// IE8 (and 9?) Fix
// ie8 doesn't parse the URL correctly until the anchor is actually
// added to the body, and an innerHTML is needed to trigger the parsing
- let addToBody = (a.host === '' && a.protocol !== 'file:');
+ const addToBody = (a.host === '' && a.protocol !== 'file:');
let div;
+
if (addToBody) {
div = document.createElement('div');
div.innerHTML = ``;
@@ -35,8 +37,9 @@ export const parseUrl = function(url) {
// Copy the specific URL properties to a new object
// This is also needed for IE8 because the anchor loses its
// properties when it's removed from the dom
- let details = {};
- for (var i = 0; i < props.length; i++) {
+ const details = {};
+
+ for (let i = 0; i < props.length; i++) {
details[props[i]] = a[props[i]];
}
@@ -45,6 +48,7 @@ export const parseUrl = function(url) {
if (details.protocol === 'http:') {
details.host = details.host.replace(/:80$/, '');
}
+
if (details.protocol === 'https:') {
details.host = details.host.replace(/:443$/, '');
}
@@ -65,11 +69,12 @@ export const parseUrl = function(url) {
* @private
* @method getAbsoluteURL
*/
-export const getAbsoluteURL = function(url){
+export const getAbsoluteURL = function(url) {
// Check if absolute URL
if (!url.match(/^https?:\/\//)) {
// Convert to absolute URL. Flash hosted off-site needs an absolute URL.
- let div = document.createElement('div');
+ const div = document.createElement('div');
+
div.innerHTML = `x`;
url = div.firstChild.href;
}
@@ -85,9 +90,9 @@ export const getAbsoluteURL = function(url){
* @method getFileExtension
*/
export const getFileExtension = function(path) {
- if(typeof path === 'string'){
- let splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i;
- let pathParts = splitPathRe.exec(path);
+ if (typeof path === 'string') {
+ const splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i;
+ const pathParts = splitPathRe.exec(path);
if (pathParts) {
return pathParts.pop().toLowerCase();
@@ -105,15 +110,15 @@ export const getFileExtension = function(path) {
* @method isCrossOrigin
*/
export const isCrossOrigin = function(url) {
- let winLoc = window.location;
- let urlInfo = parseUrl(url);
+ const winLoc = window.location;
+ const urlInfo = parseUrl(url);
// IE8 protocol relative urls will return ':' for protocol
- let srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol;
+ const srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol;
// Check if url is for another domain/origin
// IE8 doesn't know location.origin, so we won't rely on it here
- let crossOrigin = (srcProtocol + urlInfo.host) !== (winLoc.protocol + winLoc.host);
+ const crossOrigin = (srcProtocol + urlInfo.host) !== (winLoc.protocol + winLoc.host);
return crossOrigin;
};
diff --git a/src/js/video.js b/src/js/video.js
index e9ac832f47..5c8ed3eee5 100644
--- a/src/js/video.js
+++ b/src/js/video.js
@@ -1,6 +1,9 @@
/**
* @file video.js
*/
+
+/* global define */
+
import window from 'global/window';
import document from 'global/document';
import * as setup from './setup';
@@ -28,8 +31,6 @@ import xhr from 'xhr';
// Include the built-in techs
import Tech from './tech/tech.js';
-import Html5 from './tech/html5.js';
-import Flash from './tech/flash.js';
// HTML5 Element Shim for IE8
if (typeof HTMLVideoElement === 'undefined') {
@@ -53,8 +54,8 @@ if (typeof HTMLVideoElement === 'undefined') {
* @mixes videojs
* @method videojs
*/
-function videojs(id, options, ready){
- let tag; // Element of ID
+function videojs(id, options, ready) {
+ let tag;
// Allow for element or ID to be passed in
// String ID
@@ -78,11 +79,10 @@ function videojs(id, options, ready){
}
return videojs.getPlayers()[id];
+ }
// Otherwise get element for ID
- } else {
- tag = Dom.getEl(id);
- }
+ tag = Dom.getEl(id);
// ID is a media element
} else {
@@ -90,13 +90,14 @@ function videojs(id, options, ready){
}
// Check for a useable element
- if (!tag || !tag.nodeName) { // re: nodeName, could be a box div also
- throw new TypeError('The element or ID supplied is not valid. (videojs)'); // Returns
+ // re: nodeName, could be a box div also
+ if (!tag || !tag.nodeName) {
+ throw new TypeError('The element or ID supplied is not valid. (videojs)');
}
// Element may have a player attr referring to an already created player instance.
// If not, set up a new player and return the instance.
- return tag['player'] || Player.players[tag.playerId] || new Player(tag, options, ready);
+ return tag.player || Player.players[tag.playerId] || new Player(tag, options, ready);
}
// Add default styles
@@ -105,7 +106,8 @@ if (window.VIDEOJS_NO_DYNAMIC_STYLE !== true) {
if (!style) {
style = stylesheet.createStyleElement('vjs-styles-defaults');
- let head = Dom.$('head');
+ const head = Dom.$('head');
+
head.insertBefore(style, head.firstChild);
stylesheet.setTextContent(style, `
.video-js {
@@ -121,7 +123,8 @@ if (window.VIDEOJS_NO_DYNAMIC_STYLE !== true) {
}
// Run Auto-load players
-// 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)
+// 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);
/*
@@ -269,12 +272,12 @@ videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED;
* Mimics ES6 subclassing with the `extend` keyword
* ```js
* // Create a basic javascript 'class'
- * function MyClass(name){
+ * function MyClass(name) {
* // Set a property at initialization
* this.myName = name;
* }
* // Create an instance method
- * MyClass.prototype.sayMyName = function(){
+ * MyClass.prototype.sayMyName = function() {
* alert(this.myName);
* };
* // Subclass the exisitng class and change the name
@@ -337,12 +340,12 @@ videojs.mergeOptions = mergeOptions;
/**
* Change the context (this) of a function
*
- * videojs.bind(newContext, function(){
+ * videojs.bind(newContext, function() {
* this === newContext
* });
*
* NOTE: as of v5.0 we require an ES5 shim, so you should use the native
- * `function(){}.bind(newContext);` instead of this.
+ * `function() {}.bind(newContext);` instead of this.
*
* @param {*} context The object to bind as scope
* @param {Function} fn The function to be bound to a scope
@@ -365,7 +368,7 @@ videojs.bind = Fn.bind;
* var player = this;
* var alertText = myPluginOptions.text || 'Player is playing!'
*
- * player.on('play', function(){
+ * player.on('play', function() {
* alert(alertText);
* });
* });
@@ -410,7 +413,7 @@ videojs.plugin = plugin;
* @mixes videojs
* @method addLanguage
*/
-videojs.addLanguage = function(code, data){
+videojs.addLanguage = function(code, data) {
code = ('' + code).toLowerCase();
return merge(videojs.options.languages, { [code]: data })[code];
};
@@ -721,12 +724,12 @@ videojs.insertContent = Dom.insertContent;
* still support requirejs and browserify. This also needs to be closure
* compiler compatible, so string keys are used.
*/
-if (typeof define === 'function' && define['amd']) {
- define('videojs', [], function(){ return videojs; });
+if (typeof define === 'function' && define.amd) {
+ define('videojs', [], () => videojs);
// checking that module is an object too because of umdjs/umd#35
} else if (typeof exports === 'object' && typeof module === 'object') {
- module['exports'] = videojs;
+ module.exports = videojs;
}
export default videojs;
diff --git a/test/api/api.js b/test/api/api.js
index f75dfb4794..37a59a20e7 100644
--- a/test/api/api.js
+++ b/test/api/api.js
@@ -1,212 +1,231 @@
+/* eslint-env qunit */
/**
* These tests run on the minified, window.videojs and ensure the needed
* APIs still exist
*/
+import document from 'global/document';
+import window from 'global/window';
+const videojs = window.videojs;
-(function(){
-
-q.module('Player API');
-
-test('videojs should exist on the window', function() {
- ok(window.videojs, 'videojs exists on the window');
+QUnit.module('Player API');
+QUnit.test('videojs should exist on the window', function() {
+ QUnit.ok(window.videojs, 'videojs exists on the window');
});
-test('should be able to access expected player API methods', function() {
- var player = videojs.getComponent('Player').prototype;
+QUnit.test('should be able to access expected player API methods', function() {
+ const player = videojs.getComponent('Player').prototype;
// Native HTML5 Methods
- ok(player.error, 'error exists');
- ok(player.src, 'src exists');
- ok(player.currentSrc, 'currentSrc exists');
- ok(player.buffered, 'buffered exists');
- ok(player.load, 'load exists');
- ok(player.seeking, 'seeking exists');
- ok(player.currentTime, 'currentTime exists');
- ok(player.duration, 'duration exists');
- ok(player.paused, 'paused exists');
- ok(player.ended, 'ended exists');
- ok(player.autoplay, 'autoplay exists');
- ok(player.loop, 'loop exists');
- ok(player.play , 'play exists');
- ok(player.pause , 'pause exists');
- ok(player.controls, 'controls exists');
- ok(player.volume, 'volume exists');
- ok(player.muted, 'muted exists');
- ok(player.width, 'width exists');
- ok(player.height, 'height exists');
- ok(player.poster, 'poster exists');
- ok(player.textTracks, 'textTracks exists');
- ok(player.requestFullscreen, 'requestFullscreen exists');
- ok(player.exitFullscreen, 'exitFullscreen exists');
- ok(player.playbackRate, 'playbackRate exists');
- ok(player.networkState, 'networkState exists');
- ok(player.readyState, 'readyState exists');
+ QUnit.ok(player.error, 'error exists');
+ QUnit.ok(player.src, 'src exists');
+ QUnit.ok(player.currentSrc, 'currentSrc exists');
+ QUnit.ok(player.buffered, 'buffered exists');
+ QUnit.ok(player.load, 'load exists');
+ QUnit.ok(player.seeking, 'seeking exists');
+ QUnit.ok(player.currentTime, 'currentTime exists');
+ QUnit.ok(player.duration, 'duration exists');
+ QUnit.ok(player.paused, 'paused exists');
+ QUnit.ok(player.ended, 'ended exists');
+ QUnit.ok(player.autoplay, 'autoplay exists');
+ QUnit.ok(player.loop, 'loop exists');
+ QUnit.ok(player.play, 'play exists');
+ QUnit.ok(player.pause, 'pause exists');
+ QUnit.ok(player.controls, 'controls exists');
+ QUnit.ok(player.volume, 'volume exists');
+ QUnit.ok(player.muted, 'muted exists');
+ QUnit.ok(player.width, 'width exists');
+ QUnit.ok(player.height, 'height exists');
+ QUnit.ok(player.poster, 'poster exists');
+ QUnit.ok(player.textTracks, 'textTracks exists');
+ QUnit.ok(player.requestFullscreen, 'requestFullscreen exists');
+ QUnit.ok(player.exitFullscreen, 'exitFullscreen exists');
+ QUnit.ok(player.playbackRate, 'playbackRate exists');
+ QUnit.ok(player.networkState, 'networkState exists');
+ QUnit.ok(player.readyState, 'readyState exists');
// Unsupported Native HTML5 Methods
- // ok(player.canPlayType, 'canPlayType exists');
- // ok(player.startTime, 'startTime exists');
- // ok(player.defaultPlaybackRate, 'defaultPlaybackRate exists');
- // ok(player.playbackRate, 'playbackRate exists');
- // ok(player.played, 'played exists');
- // ok(player.seekable, 'seekable exists');
- // ok(player.videoWidth, 'videoWidth exists');
- // ok(player.videoHeight, 'videoHeight exists');
+ // QUnit.ok(player.canPlayType, 'canPlayType exists');
+ // QUnit.ok(player.startTime, 'startTime exists');
+ // QUnit.ok(player.defaultPlaybackRate, 'defaultPlaybackRate exists');
+ // QUnit.ok(player.playbackRate, 'playbackRate exists');
+ // QUnit.ok(player.played, 'played exists');
+ // QUnit.ok(player.seekable, 'seekable exists');
+ // QUnit.ok(player.videoWidth, 'videoWidth exists');
+ // QUnit.ok(player.videoHeight, 'videoHeight exists');
// Additional player methods
- ok(player.bufferedPercent, 'bufferedPercent exists');
- ok(player.reportUserActivity, 'reportUserActivity exists');
- ok(player.userActive, 'userActive exists');
- ok(player.usingNativeControls, 'usingNativeControls exists');
- ok(player.isFullscreen, 'isFullscreen exists');
+ QUnit.ok(player.bufferedPercent, 'bufferedPercent exists');
+ QUnit.ok(player.reportUserActivity, 'reportUserActivity exists');
+ QUnit.ok(player.userActive, 'userActive exists');
+ QUnit.ok(player.usingNativeControls, 'usingNativeControls exists');
+ QUnit.ok(player.isFullscreen, 'isFullscreen exists');
// Track methods
- ok(player.audioTracks, 'audioTracks exists');
- ok(player.videoTracks, 'videoTracks exists');
- ok(player.textTracks, 'textTracks exists');
- ok(player.remoteTextTrackEls, 'remoteTextTrackEls exists');
- ok(player.remoteTextTracks, 'remoteTextTracks exists');
- ok(player.addTextTrack, 'addTextTrack exists');
- ok(player.addRemoteTextTrack, 'addRemoteTextTrack exists');
- ok(player.removeRemoteTextTrack, 'removeRemoteTextTrack exists');
+ QUnit.ok(player.audioTracks, 'audioTracks exists');
+ QUnit.ok(player.videoTracks, 'videoTracks exists');
+ QUnit.ok(player.textTracks, 'textTracks exists');
+ QUnit.ok(player.remoteTextTrackEls, 'remoteTextTrackEls exists');
+ QUnit.ok(player.remoteTextTracks, 'remoteTextTracks exists');
+ QUnit.ok(player.addTextTrack, 'addTextTrack exists');
+ QUnit.ok(player.addRemoteTextTrack, 'addRemoteTextTrack exists');
+ QUnit.ok(player.removeRemoteTextTrack, 'removeRemoteTextTrack exists');
// Deprecated methods that should still exist
- ok(player.requestFullScreen, 'requestFullScreen exists');
- ok(player.isFullScreen, 'isFullScreen exists');
- ok(player.cancelFullScreen, 'cancelFullScreen exists');
+ QUnit.ok(player.requestFullScreen, 'requestFullScreen exists');
+ QUnit.ok(player.isFullScreen, 'isFullScreen exists');
+ QUnit.ok(player.cancelFullScreen, 'cancelFullScreen exists');
});
-test('should be able to access expected component API methods', function() {
- var Component = videojs.getComponent('Component');
- var comp = new Component({ id: function(){ return 1; }, reportUserActivity: function(){} });
+QUnit.test('should be able to access expected component API methods', function() {
+ const Component = videojs.getComponent('Component');
+ const comp = new Component({
+ id() {
+ return 1;
+ },
+ reportUserActivity() {}
+ });
// Component methods
- ok(comp.player, 'player exists');
- ok(comp.options, 'options exists');
- ok(comp.init, 'init exists');
- ok(comp.dispose, 'dispose exists');
- ok(comp.createEl, 'createEl exists');
- ok(comp.contentEl, 'contentEl exists');
- ok(comp.el, 'el exists');
- ok(comp.addChild, 'addChild exists');
- ok(comp.getChild, 'getChild exists');
- ok(comp.getChildById, 'getChildById exists');
- ok(comp.children, 'children exists');
- ok(comp.initChildren, 'initChildren exists');
- ok(comp.removeChild, 'removeChild exists');
- ok(comp.on, 'on exists');
- ok(comp.off, 'off exists');
- ok(comp.one, 'one exists');
- ok(comp.trigger, 'trigger exists');
- ok(comp.triggerReady, 'triggerReady exists');
- ok(comp.show, 'show exists');
- ok(comp.hide, 'hide exists');
- ok(comp.width, 'width exists');
- ok(comp.height, 'height exists');
- ok(comp.dimensions, 'dimensions exists');
- ok(comp.ready, 'ready exists');
- ok(comp.addClass, 'addClass exists');
- ok(comp.removeClass, 'removeClass exists');
- ok(comp.buildCSSClass, 'buildCSSClass exists');
- ok(comp.setInterval, 'setInterval exists');
- ok(comp.clearInterval, 'clearInterval exists');
- ok(comp.setTimeout, 'setTimeout exists');
- ok(comp.clearTimeout, 'clearTimeout exists');
+ QUnit.ok(comp.player, 'player exists');
+ QUnit.ok(comp.options, 'options exists');
+ QUnit.ok(comp.init, 'init exists');
+ QUnit.ok(comp.dispose, 'dispose exists');
+ QUnit.ok(comp.createEl, 'createEl exists');
+ QUnit.ok(comp.contentEl, 'contentEl exists');
+ QUnit.ok(comp.el, 'el exists');
+ QUnit.ok(comp.addChild, 'addChild exists');
+ QUnit.ok(comp.getChild, 'getChild exists');
+ QUnit.ok(comp.getChildById, 'getChildById exists');
+ QUnit.ok(comp.children, 'children exists');
+ QUnit.ok(comp.initChildren, 'initChildren exists');
+ QUnit.ok(comp.removeChild, 'removeChild exists');
+ QUnit.ok(comp.on, 'on exists');
+ QUnit.ok(comp.off, 'off exists');
+ QUnit.ok(comp.one, 'one exists');
+ QUnit.ok(comp.trigger, 'trigger exists');
+ QUnit.ok(comp.triggerReady, 'triggerReady exists');
+ QUnit.ok(comp.show, 'show exists');
+ QUnit.ok(comp.hide, 'hide exists');
+ QUnit.ok(comp.width, 'width exists');
+ QUnit.ok(comp.height, 'height exists');
+ QUnit.ok(comp.dimensions, 'dimensions exists');
+ QUnit.ok(comp.ready, 'ready exists');
+ QUnit.ok(comp.addClass, 'addClass exists');
+ QUnit.ok(comp.removeClass, 'removeClass exists');
+ QUnit.ok(comp.buildCSSClass, 'buildCSSClass exists');
+ QUnit.ok(comp.setInterval, 'setInterval exists');
+ QUnit.ok(comp.clearInterval, 'clearInterval exists');
+ QUnit.ok(comp.setTimeout, 'setTimeout exists');
+ QUnit.ok(comp.clearTimeout, 'clearTimeout exists');
});
-test('should be able to access expected MediaTech API methods', function() {
- var media = videojs.getComponent('Tech');
- var mediaProto = media.prototype;
- var html5 = videojs.getComponent('Html5');
- var html5Proto = html5.prototype;
- var flash = videojs.getComponent('Flash');
- var flashProto = flash.prototype;
+QUnit.test('should be able to access expected MediaTech API methods', function() {
+ const media = videojs.getComponent('Tech');
+ const mediaProto = media.prototype;
+ const html5 = videojs.getComponent('Html5');
+ const html5Proto = html5.prototype;
+ const flash = videojs.getComponent('Flash');
+ const flashProto = flash.prototype;
- ok(mediaProto.setPoster, 'setPoster should exist on the Media tech');
- ok(html5Proto.setPoster, 'setPoster should exist on the HTML5 tech');
- ok(flashProto.setPoster, 'setPoster should exist on the Flash tech');
+ QUnit.ok(mediaProto.setPoster, 'setPoster should exist on the Media tech');
+ QUnit.ok(html5Proto.setPoster, 'setPoster should exist on the HTML5 tech');
+ QUnit.ok(flashProto.setPoster, 'setPoster should exist on the Flash tech');
- ok(html5.patchCanPlayType, 'patchCanPlayType should exist for HTML5');
- ok(html5.unpatchCanPlayType, 'unpatchCanPlayType should exist for HTML5');
+ QUnit.ok(html5.patchCanPlayType, 'patchCanPlayType should exist for HTML5');
+ QUnit.ok(html5.unpatchCanPlayType, 'unpatchCanPlayType should exist for HTML5');
// Source Handler Functions
- ok(media.withSourceHandlers, 'withSourceHandlers should exist for Media Tech');
-
- ok(html5.canPlaySource, 'canPlaySource should exist for HTML5');
- ok(html5.registerSourceHandler, 'registerSourceHandler should exist for Html5');
- ok(html5.selectSourceHandler, 'selectSourceHandler should exist for Html5');
- ok(html5.prototype.setSource, 'setSource should exist for Html5');
- ok(html5.prototype.disposeSourceHandler, 'disposeSourceHandler should exist for Html5');
-
- ok(flash.canPlaySource, 'canPlaySource should exist for Flash');
- ok(flash.registerSourceHandler, 'registerSourceHandler should exist for Flash');
- ok(flash.selectSourceHandler, 'selectSourceHandler should exist for Flash');
- ok(flash.prototype.setSource, 'setSource should exist for Flash');
- ok(flash.prototype.disposeSourceHandler, 'disposeSourceHandler should exist for Flash');
+ QUnit.ok(media.withSourceHandlers, 'withSourceHandlers should exist for Media Tech');
+
+ QUnit.ok(html5.canPlaySource, 'canPlaySource should exist for HTML5');
+ QUnit.ok(html5.registerSourceHandler, 'registerSourceHandler should exist for Html5');
+ QUnit.ok(html5.selectSourceHandler, 'selectSourceHandler should exist for Html5');
+ QUnit.ok(html5.prototype.setSource, 'setSource should exist for Html5');
+ QUnit.ok(html5.prototype.disposeSourceHandler,
+ 'disposeSourceHandler should exist for Html5');
+
+ QUnit.ok(flash.canPlaySource, 'canPlaySource should exist for Flash');
+ QUnit.ok(flash.registerSourceHandler, 'registerSourceHandler should exist for Flash');
+ QUnit.ok(flash.selectSourceHandler, 'selectSourceHandler should exist for Flash');
+ QUnit.ok(flash.prototype.setSource, 'setSource should exist for Flash');
+ QUnit.ok(flash.prototype.disposeSourceHandler,
+ 'disposeSourceHandler should exist for Flash');
});
-test('should export ready api call to public', function() {
- var videoTag = testHelperMakeTag();
+QUnit.test('should export ready api call to public', function() {
+ const videoTag = testHelperMakeTag();
+ const fixture = document.getElementById('qunit-fixture');
- var fixture = document.getElementById('qunit-fixture');
fixture.appendChild(videoTag);
- var player = videojs('example_1');
- ok(player.ready !== undefined, 'ready callback is defined');
+ const player = videojs('example_1');
+
+ QUnit.ok(player.ready !== undefined, 'ready callback is defined');
player.dispose();
});
-test('should export useful components to the public', function () {
- ok(videojs.browser.TOUCH_ENABLED !== undefined, 'Touch detection should be public');
- ok(videojs.getComponent('ControlBar'), 'ControlBar should be public');
- ok(videojs.getComponent('Button'), 'Button should be public');
- ok(videojs.getComponent('PlayToggle'), 'PlayToggle should be public');
- ok(videojs.getComponent('FullscreenToggle'), 'FullscreenToggle should be public');
- ok(videojs.getComponent('BigPlayButton'), 'BigPlayButton should be public');
- ok(videojs.getComponent('LoadingSpinner'), 'LoadingSpinner should be public');
- ok(videojs.getComponent('CurrentTimeDisplay'), 'CurrentTimeDisplay should be public');
- ok(videojs.getComponent('DurationDisplay'), 'DurationDisplay should be public');
- ok(videojs.getComponent('TimeDivider'), 'TimeDivider should be public');
- ok(videojs.getComponent('RemainingTimeDisplay'), 'RemainingTimeDisplay should be public');
- ok(videojs.getComponent('Slider'), 'Slider should be public');
- ok(videojs.getComponent('ProgressControl'), 'ProgressControl should be public');
- ok(videojs.getComponent('SeekBar'), 'SeekBar should be public');
- ok(videojs.getComponent('LoadProgressBar'), 'LoadProgressBar should be public');
- ok(videojs.getComponent('PlayProgressBar'), 'PlayProgressBar should be public');
- ok(videojs.getComponent('VolumeControl'), 'VolumeControl should be public');
- ok(videojs.getComponent('VolumeBar'), 'VolumeBar should be public');
- ok(videojs.getComponent('VolumeLevel'), 'VolumeLevel should be public');
- ok(videojs.getComponent('VolumeMenuButton'), 'VolumeMenuButton should be public');
- ok(videojs.getComponent('MuteToggle'), 'MuteToggle should be public');
- ok(videojs.getComponent('PosterImage'), 'PosterImage should be public');
- ok(videojs.getComponent('Menu'), 'Menu should be public');
- ok(videojs.getComponent('MenuItem'), 'MenuItem should be public');
- ok(videojs.getComponent('MenuButton'), 'MenuButton should be public');
- ok(videojs.getComponent('PlaybackRateMenuButton'), 'PlaybackRateMenuButton should be public');
-
- ok(videojs.getComponent('CaptionSettingsMenuItem'), 'CaptionSettingsMenuItem should be public');
- ok(videojs.getComponent('OffTextTrackMenuItem'), 'OffTextTrackMenuItem should be public');
- ok(videojs.getComponent('TextTrackMenuItem'), 'TextTrackMenuItem should be public');
- ok(videojs.getComponent('TextTrackDisplay'), 'TextTrackDisplay should be public');
- ok(videojs.getComponent('TextTrackButton'), 'TextTrackButton should be public');
- ok(videojs.getComponent('CaptionsButton'), 'CaptionsButton should be public');
- ok(videojs.getComponent('SubtitlesButton'), 'SubtitlesButton should be public');
- ok(videojs.getComponent('DescriptionsButton'), 'DescriptionsButton should be public');
- ok(videojs.getComponent('ChaptersButton'), 'ChaptersButton should be public');
- ok(videojs.getComponent('ChaptersTrackMenuItem'), 'ChaptersTrackMenuItem should be public');
-
- ok(videojs.mergeOptions, 'mergeOptions should be public');
+QUnit.test('should export useful components to the public', function() {
+ QUnit.ok(videojs.browser.TOUCH_ENABLED !== undefined,
+ 'Touch detection should be public');
+ QUnit.ok(videojs.getComponent('ControlBar'), 'ControlBar should be public');
+ QUnit.ok(videojs.getComponent('Button'), 'Button should be public');
+ QUnit.ok(videojs.getComponent('PlayToggle'), 'PlayToggle should be public');
+ QUnit.ok(videojs.getComponent('FullscreenToggle'), 'FullscreenToggle should be public');
+ QUnit.ok(videojs.getComponent('BigPlayButton'), 'BigPlayButton should be public');
+ QUnit.ok(videojs.getComponent('LoadingSpinner'), 'LoadingSpinner should be public');
+ QUnit.ok(videojs.getComponent('CurrentTimeDisplay'),
+ 'CurrentTimeDisplay should be public');
+ QUnit.ok(videojs.getComponent('DurationDisplay'), 'DurationDisplay should be public');
+ QUnit.ok(videojs.getComponent('TimeDivider'), 'TimeDivider should be public');
+ QUnit.ok(videojs.getComponent('RemainingTimeDisplay'),
+ 'RemainingTimeDisplay should be public');
+ QUnit.ok(videojs.getComponent('Slider'), 'Slider should be public');
+ QUnit.ok(videojs.getComponent('ProgressControl'), 'ProgressControl should be public');
+ QUnit.ok(videojs.getComponent('SeekBar'), 'SeekBar should be public');
+ QUnit.ok(videojs.getComponent('LoadProgressBar'), 'LoadProgressBar should be public');
+ QUnit.ok(videojs.getComponent('PlayProgressBar'), 'PlayProgressBar should be public');
+ QUnit.ok(videojs.getComponent('VolumeControl'), 'VolumeControl should be public');
+ QUnit.ok(videojs.getComponent('VolumeBar'), 'VolumeBar should be public');
+ QUnit.ok(videojs.getComponent('VolumeLevel'), 'VolumeLevel should be public');
+ QUnit.ok(videojs.getComponent('VolumeMenuButton'), 'VolumeMenuButton should be public');
+ QUnit.ok(videojs.getComponent('MuteToggle'), 'MuteToggle should be public');
+ QUnit.ok(videojs.getComponent('PosterImage'), 'PosterImage should be public');
+ QUnit.ok(videojs.getComponent('Menu'), 'Menu should be public');
+ QUnit.ok(videojs.getComponent('MenuItem'), 'MenuItem should be public');
+ QUnit.ok(videojs.getComponent('MenuButton'), 'MenuButton should be public');
+ QUnit.ok(videojs.getComponent('PlaybackRateMenuButton'),
+ 'PlaybackRateMenuButton should be public');
+
+ QUnit.ok(videojs.getComponent('CaptionSettingsMenuItem'),
+ 'CaptionSettingsMenuItem should be public');
+ QUnit.ok(videojs.getComponent('OffTextTrackMenuItem'),
+ 'OffTextTrackMenuItem should be public');
+ QUnit.ok(videojs.getComponent('TextTrackMenuItem'),
+ 'TextTrackMenuItem should be public');
+ QUnit.ok(videojs.getComponent('TextTrackDisplay'), 'TextTrackDisplay should be public');
+ QUnit.ok(videojs.getComponent('TextTrackButton'), 'TextTrackButton should be public');
+ QUnit.ok(videojs.getComponent('CaptionsButton'), 'CaptionsButton should be public');
+ QUnit.ok(videojs.getComponent('SubtitlesButton'), 'SubtitlesButton should be public');
+ QUnit.ok(videojs.getComponent('DescriptionsButton'),
+ 'DescriptionsButton should be public');
+ QUnit.ok(videojs.getComponent('ChaptersButton'), 'ChaptersButton should be public');
+ QUnit.ok(videojs.getComponent('ChaptersTrackMenuItem'),
+ 'ChaptersTrackMenuItem should be public');
+
+ QUnit.ok(videojs.mergeOptions, 'mergeOptions should be public');
});
-test('should be able to initialize player twice on the same tag using string reference', function() {
- var videoTag = testHelperMakeTag();
- var id = videoTag.id;
+QUnit.test('should be able to initialize player twice on the same tag using string reference', function() {
+ const videoTag = testHelperMakeTag();
+ const id = videoTag.id;
+ const fixture = document.getElementById('qunit-fixture');
- var fixture = document.getElementById('qunit-fixture');
fixture.appendChild(videoTag);
- var player = videojs('example_1');
+ const player = videojs('example_1');
+
player.dispose();
- ok(!document.getElementById(id), 'element is removed');
+ QUnit.ok(!document.getElementById(id), 'element is removed');
videoTag = testHelperMakeTag();
fixture.appendChild(videoTag);
@@ -215,66 +234,68 @@ test('should be able to initialize player twice on the same tag using string ref
player.dispose();
});
-test('videojs.getPlayers() should be available after minification', function() {
- var videoTag = testHelperMakeTag();
- var id = videoTag.id;
+QUnit.test('videojs.getPlayers() should be available after minification', function() {
+ const videoTag = testHelperMakeTag();
+ const id = videoTag.id;
+ const fixture = document.getElementById('qunit-fixture');
- var fixture = document.getElementById('qunit-fixture');
fixture.appendChild(videoTag);
- var player = videojs(id);
- ok(videojs.getPlayers()[id] === player, 'videojs.getPlayers() is available');
+ const player = videojs(id);
+
+ QUnit.ok(videojs.getPlayers()[id] === player, 'videojs.getPlayers() is available');
player.dispose();
});
-test('component can be subclassed externally', function(){
- var Component = videojs.getComponent('Component');
- var ControlBar = videojs.getComponent('ControlBar');
+QUnit.test('component can be subclassed externally', function() {
+ const Component = videojs.getComponent('Component');
+ const ControlBar = videojs.getComponent('ControlBar');
- var player = new (videojs.extend(Component, {
- reportUserActivity: function(){},
- textTracks: function(){ return {
+ const player = new (videojs.extend(Component, {
+ reportUserActivity() {},
+ textTracks() {
+ return {
addEventListener: Function.prototype,
removeEventListener: Function.prototype
};
}
}))({
- id: function(){},
- reportUserActivity: function(){}
+ id() {},
+ reportUserActivity() {}
});
- ok(new ControlBar(player), 'created a control bar without throwing');
+ QUnit.ok(new ControlBar(player), 'created a control bar without throwing');
});
-function testHelperMakeTag(){
- var videoTag = document.createElement('video');
+function testHelperMakeTag() {
+ const videoTag = document.createElement('video');
+
videoTag.id = 'example_1';
videoTag.className = 'video-js vjs-default-skin';
return videoTag;
}
-test('should extend Component', function(){
- var Component = videojs.getComponent('Component');
- var MyComponent = videojs.extend(Component, {
- constructor: function() {
+QUnit.test('should extend Component', function() {
+ const Component = videojs.getComponent('Component');
+ const MyComponent = videojs.extend(Component, {
+ constructor() {
this.bar = true;
},
- foo: function() {
+ foo() {
return true;
}
});
- var myComponent = new MyComponent();
- ok(myComponent instanceof Component, 'creates an instance of Component');
- ok(myComponent instanceof MyComponent, 'creates an instance of MyComponent');
- ok(myComponent.bar, 'the constructor function is used');
- ok(myComponent.foo(), 'instance methods are applied');
+ const myComponent = new MyComponent();
- var NoMethods = videojs.extend(Component);
- var noMethods = new NoMethods({});
- ok(noMethods.on, 'should extend component with no methods or constructor');
-});
+ QUnit.ok(myComponent instanceof Component, 'creates an instance of Component');
+ QUnit.ok(myComponent instanceof MyComponent, 'creates an instance of MyComponent');
+ QUnit.ok(myComponent.bar, 'the constructor function is used');
+ QUnit.ok(myComponent.foo(), 'instance methods are applied');
+ const NoMethods = videojs.extend(Component);
+ const noMethods = new NoMethods({});
-})();
+ QUnit.ok(noMethods.on, 'should extend component with no methods or constructor');
+});
diff --git a/test/globals-shim.js b/test/globals-shim.js
index b0ad8514bc..705f16bef9 100644
--- a/test/globals-shim.js
+++ b/test/globals-shim.js
@@ -1,3 +1,4 @@
+/* eslint-env qunit */
import 'es6-shim';
import document from 'global/document';
import window from 'global/window';
diff --git a/test/unit/button.test.js b/test/unit/button.test.js
index 10bb1c60ae..d5e82a9a6e 100644
--- a/test/unit/button.test.js
+++ b/test/unit/button.test.js
@@ -1,27 +1,27 @@
+/* eslint-env qunit */
import Button from '../../src/js/button.js';
import TestHelpers from './test-helpers.js';
-q.module('Button');
+QUnit.module('Button');
-test('should localize its text', function(){
- expect(3);
+QUnit.test('should localize its text', function() {
+ QUnit.expect(3);
- var player, testButton, el;
-
- player = TestHelpers.makePlayer({
- 'language': 'es',
- 'languages': {
- 'es': {
- 'Play': 'Juego'
+ const player = TestHelpers.makePlayer({
+ language: 'es',
+ languages: {
+ es: {
+ Play: 'Juego'
}
}
});
- testButton = new Button(player);
+ const testButton = new Button(player);
+
testButton.controlText_ = 'Play';
- el = testButton.createEl();
+ const el = testButton.createEl();
- ok(el.nodeName.toLowerCase().match('button'));
- ok(el.innerHTML.match(/vjs-control-text"?>Juego/));
- equal(el.getAttribute('title'), 'Juego');
+ QUnit.ok(el.nodeName.toLowerCase().match('button'));
+ QUnit.ok(el.innerHTML.match(/vjs-control-text"?>Juego/));
+ QUnit.equal(el.getAttribute('title'), 'Juego');
});
diff --git a/test/unit/clickable-component.test.js b/test/unit/clickable-component.test.js
index b83b6c62e3..322acb6883 100644
--- a/test/unit/clickable-component.test.js
+++ b/test/unit/clickable-component.test.js
@@ -1,39 +1,40 @@
+/* eslint-env qunit */
import ClickableComponent from '../../src/js/clickable-component.js';
import TestHelpers from './test-helpers.js';
-q.module('ClickableComponent');
+QUnit.module('ClickableComponent');
-q.test('should create a div with role="button"', function(){
- expect(2);
+QUnit.test('should create a div with role="button"', function() {
+ QUnit.expect(2);
- let player = TestHelpers.makePlayer({});
+ const player = TestHelpers.makePlayer({});
- let testClickableComponent = new ClickableComponent(player);
- let el = testClickableComponent.createEl();
+ const testClickableComponent = new ClickableComponent(player);
+ const el = testClickableComponent.createEl();
- equal(el.nodeName.toLowerCase(), 'div', 'the name of the element is "div"');
- equal(el.getAttribute('role').toLowerCase(), 'button', 'the role of the element is "button"');
+ QUnit.equal(el.nodeName.toLowerCase(), 'div', 'the name of the element is "div"');
+ QUnit.equal(el.getAttribute('role').toLowerCase(), 'button', 'the role of the element is "button"');
testClickableComponent.dispose();
player.dispose();
});
-q.test('should be enabled/disabled', function(){
- expect(3);
+QUnit.test('should be enabled/disabled', function() {
+ QUnit.expect(3);
- let player = TestHelpers.makePlayer({});
+ const player = TestHelpers.makePlayer({});
- let testClickableComponent = new ClickableComponent(player);
+ const testClickableComponent = new ClickableComponent(player);
- equal(testClickableComponent.hasClass('vjs-disabled'), false, 'ClickableComponent defaults to enabled');
+ QUnit.equal(testClickableComponent.hasClass('vjs-disabled'), false, 'ClickableComponent defaults to enabled');
testClickableComponent.disable();
- equal(testClickableComponent.hasClass('vjs-disabled'), true, 'ClickableComponent is disabled');
+ QUnit.equal(testClickableComponent.hasClass('vjs-disabled'), true, 'ClickableComponent is disabled');
testClickableComponent.enable();
- equal(testClickableComponent.hasClass('vjs-disabled'), false, 'ClickableComponent is enabled');
+ QUnit.equal(testClickableComponent.hasClass('vjs-disabled'), false, 'ClickableComponent is enabled');
testClickableComponent.dispose();
player.dispose();
diff --git a/test/unit/close-button.test.js b/test/unit/close-button.test.js
index bd02bbb7f4..646d3bf545 100644
--- a/test/unit/close-button.test.js
+++ b/test/unit/close-button.test.js
@@ -1,21 +1,23 @@
+/* eslint-env qunit */
import CloseButton from '../../src/js/close-button';
+import sinon from 'sinon';
import TestHelpers from './test-helpers';
-q.module('CloseButton', {
+QUnit.module('CloseButton', {
- beforeEach: function() {
+ beforeEach() {
this.player = TestHelpers.makePlayer();
this.btn = new CloseButton(this.player);
},
- afterEach: function() {
+ afterEach() {
this.player.dispose();
this.btn.dispose();
}
});
-q.test('should create the expected element', function(assert) {
- let elAssertions = TestHelpers.assertEl(assert, this.btn.el(), {
+QUnit.test('should create the expected element', function(assert) {
+ const elAssertions = TestHelpers.assertEl(assert, this.btn.el(), {
tagName: 'button',
classes: [
'vjs-button',
@@ -29,16 +31,16 @@ q.test('should create the expected element', function(assert) {
assert.strictEqual(this.btn.el().querySelector('.vjs-control-text').innerHTML, 'Close');
});
-q.test('should allow setting the controlText_ property as an option', function(assert) {
- var text = 'OK!';
- var btn = new CloseButton(this.player, {controlText: text});
+QUnit.test('should allow setting the controlText_ property as an option', function(assert) {
+ const text = 'OK!';
+ const btn = new CloseButton(this.player, {controlText: text});
assert.expect(1);
assert.strictEqual(btn.controlText_, text, 'set the controlText_ property');
});
-q.test('should trigger an event on activation', function(assert) {
- var spy = sinon.spy();
+QUnit.test('should trigger an event on activation', function(assert) {
+ const spy = sinon.spy();
this.btn.on('close', spy);
this.btn.trigger('click');
diff --git a/test/unit/component.test.js b/test/unit/component.test.js
index 38d7ff0842..2dc5ac8b41 100644
--- a/test/unit/component.test.js
+++ b/test/unit/component.test.js
@@ -1,8 +1,10 @@
+/* eslint-env qunit */
import Component from '../../src/js/component.js';
import * as Dom from '../../src/js/utils/dom.js';
import * as Events from '../../src/js/utils/events.js';
import * as browser from '../../src/js/utils/browser.js';
import document from 'global/document';
+import sinon from 'sinon';
import TestHelpers from './test-helpers.js';
class TestComponent1 extends Component {}
@@ -20,91 +22,96 @@ Component.registerComponent('TestComponent2', TestComponent2);
Component.registerComponent('TestComponent3', TestComponent3);
Component.registerComponent('TestComponent4', TestComponent4);
-q.module('Component', {
- 'setup': function() {
+QUnit.module('Component', {
+ setup() {
this.clock = sinon.useFakeTimers();
},
- 'teardown': function() {
+ teardown() {
this.clock.restore();
}
});
-var getFakePlayer = function(){
+const getFakePlayer = function() {
return {
// Fake player requries an ID
- id: function(){ return 'player_1'; },
- reportUserActivity: function(){}
+ id() {
+ return 'player_1';
+ },
+ reportUserActivity() {}
};
};
-test('should create an element', function(){
- var comp = new Component(getFakePlayer(), {});
+QUnit.test('should create an element', function() {
+ const comp = new Component(getFakePlayer(), {});
- ok(comp.el().nodeName);
+ QUnit.ok(comp.el().nodeName);
});
-test('should add a child component', function(){
- var comp = new Component(getFakePlayer());
+QUnit.test('should add a child component', function() {
+ const comp = new Component(getFakePlayer());
- var child = comp.addChild('component');
+ const child = comp.addChild('component');
- ok(comp.children().length === 1);
- ok(comp.children()[0] === child);
- ok(comp.el().childNodes[0] === child.el());
- ok(comp.getChild('component') === child);
- ok(comp.getChildById(child.id()) === child);
+ QUnit.ok(comp.children().length === 1);
+ QUnit.ok(comp.children()[0] === child);
+ QUnit.ok(comp.el().childNodes[0] === child.el());
+ QUnit.ok(comp.getChild('component') === child);
+ QUnit.ok(comp.getChildById(child.id()) === child);
});
-test('should add a child component to an index', function(){
- var comp = new Component(getFakePlayer());
+QUnit.test('should add a child component to an index', function() {
+ const comp = new Component(getFakePlayer());
+
+ const child = comp.addChild('component');
+
+ QUnit.ok(comp.children().length === 1);
+ QUnit.ok(comp.children()[0] === child);
+
+ const child0 = comp.addChild('component', {}, 0);
+
+ QUnit.ok(comp.children().length === 2);
+ QUnit.ok(comp.children()[0] === child0);
+ QUnit.ok(comp.children()[1] === child);
- var child = comp.addChild('component');
+ const child1 = comp.addChild('component', {}, '2');
- ok(comp.children().length === 1);
- ok(comp.children()[0] === child);
+ QUnit.ok(comp.children().length === 3);
+ QUnit.ok(comp.children()[2] === child1);
- var child0 = comp.addChild('component', {}, 0);
- ok(comp.children().length === 2);
- ok(comp.children()[0] === child0);
- ok(comp.children()[1] === child);
+ const child2 = comp.addChild('component', {}, undefined);
- var child1 = comp.addChild('component', {}, '2');
- ok(comp.children().length === 3);
- ok(comp.children()[2] === child1);
+ QUnit.ok(comp.children().length === 4);
+ QUnit.ok(comp.children()[3] === child2);
- var child2 = comp.addChild('component', {}, undefined);
- ok(comp.children().length === 4);
- ok(comp.children()[3] === child2);
+ const child3 = comp.addChild('component', {}, -1);
- var child3 = comp.addChild('component', {}, -1);
- ok(comp.children().length === 5);
- ok(comp.children()[3] === child3);
- ok(comp.children()[4] === child2);
+ QUnit.ok(comp.children().length === 5);
+ QUnit.ok(comp.children()[3] === child3);
+ QUnit.ok(comp.children()[4] === child2);
});
-test('addChild should throw if the child does not exist', function() {
- var comp = new Component(getFakePlayer());
+QUnit.test('addChild should throw if the child does not exist', function() {
+ const comp = new Component(getFakePlayer());
throws(function() {
- comp.addChild('non-existent-child');
+ comp.addChild('non-existent-child');
}, new Error('Component Non-existent-child does not exist'), 'addChild threw');
});
-
-test('should init child components from options', function(){
- var comp = new Component(getFakePlayer(), {
+QUnit.test('should init child components from options', function() {
+ const comp = new Component(getFakePlayer(), {
children: {
- 'component': {}
+ component: {}
}
});
- ok(comp.children().length === 1);
- ok(comp.el().childNodes.length === 1);
+ QUnit.ok(comp.children().length === 1);
+ QUnit.ok(comp.el().childNodes.length === 1);
});
-test('should init child components from simple children array', function(){
- var comp = new Component(getFakePlayer(), {
+QUnit.test('should init child components from simple children array', function() {
+ const comp = new Component(getFakePlayer(), {
children: [
'component',
'component',
@@ -112,157 +119,163 @@ test('should init child components from simple children array', function(){
]
});
- ok(comp.children().length === 3);
- ok(comp.el().childNodes.length === 3);
+ QUnit.ok(comp.children().length === 3);
+ QUnit.ok(comp.el().childNodes.length === 3);
});
-test('should init child components from children array of objects', function(){
- var comp = new Component(getFakePlayer(), {
+QUnit.test('should init child components from children array of objects', function() {
+ const comp = new Component(getFakePlayer(), {
children: [
- { 'name': 'component' },
- { 'name': 'component' },
- { 'name': 'component' }
+ { name: 'component' },
+ { name: 'component' },
+ { name: 'component' }
]
});
- ok(comp.children().length === 3);
- ok(comp.el().childNodes.length === 3);
+ QUnit.ok(comp.children().length === 3);
+ QUnit.ok(comp.el().childNodes.length === 3);
});
-test('should do a deep merge of child options', function(){
+QUnit.test('should do a deep merge of child options', function() {
// Create a default option for component
Component.prototype.options_ = {
- 'example': {
- 'childOne': { 'foo': 'bar', 'asdf': 'fdsa' },
- 'childTwo': {},
- 'childThree': {}
+ example: {
+ childOne: { foo: 'bar', asdf: 'fdsa' },
+ childTwo: {},
+ childThree: {}
}
};
- var comp = new Component(getFakePlayer(), {
- 'example': {
- 'childOne': { 'foo': 'baz', 'abc': '123' },
- 'childThree': false,
- 'childFour': {}
+ const comp = new Component(getFakePlayer(), {
+ example: {
+ childOne: { foo: 'baz', abc: '123' },
+ childThree: false,
+ childFour: {}
}
});
- var mergedOptions = comp.options_;
- var children = mergedOptions['example'];
+ const mergedOptions = comp.options_;
+ const children = mergedOptions.example;
- strictEqual(children['childOne']['foo'], 'baz', 'value three levels deep overridden');
- strictEqual(children['childOne']['asdf'], 'fdsa', 'value three levels deep maintained');
- strictEqual(children['childOne']['abc'], '123', 'value three levels deep added');
- ok(children['childTwo'], 'object two levels deep maintained');
- strictEqual(children['childThree'], false, 'object two levels deep removed');
- ok(children['childFour'], 'object two levels deep added');
+ QUnit.strictEqual(children.childOne.foo, 'baz', 'value three levels deep overridden');
+ QUnit.strictEqual(children.childOne.asdf, 'fdsa', 'value three levels deep maintained');
+ QUnit.strictEqual(children.childOne.abc, '123', 'value three levels deep added');
+ QUnit.ok(children.childTwo, 'object two levels deep maintained');
+ QUnit.strictEqual(children.childThree, false, 'object two levels deep removed');
+ QUnit.ok(children.childFour, 'object two levels deep added');
- strictEqual(Component.prototype.options_['example']['childOne']['foo'], 'bar', 'prototype options were not overridden');
+ QUnit.strictEqual(Component.prototype.options_.example.childOne.foo, 'bar',
+ 'prototype options were not overridden');
// Reset default component options to none
Component.prototype.options_ = null;
});
-test('should init child components from component options', function(){
- let testComp = new TestComponent1(TestHelpers.makePlayer(), {
+QUnit.test('should init child components from component options', function() {
+ const testComp = new TestComponent1(TestHelpers.makePlayer(), {
testComponent2: false,
testComponent4: {}
});
- ok(!testComp.childNameIndex_.testComponent2, 'we do not have testComponent2');
- ok(testComp.childNameIndex_.testComponent4, 'we have a testComponent4');
+ QUnit.ok(!testComp.childNameIndex_.testComponent2, 'we do not have testComponent2');
+ QUnit.ok(testComp.childNameIndex_.testComponent4, 'we have a testComponent4');
});
-test('should allows setting child options at the parent options level', function(){
- var parent, options;
+QUnit.test('should allows setting child options at the parent options level', function() {
+ let parent;
// using children array
- options = {
- 'children': [
+ let options = {
+ children: [
'component',
'nullComponent'
],
// parent-level option for child
- 'component': {
- 'foo': true
+ component: {
+ foo: true
},
- 'nullComponent': false
+ nullComponent: false
};
try {
parent = new Component(getFakePlayer(), options);
- } catch(err) {
- ok(false, 'Child with `false` option was initialized');
+ } catch (err) {
+ QUnit.ok(false, 'Child with `false` option was initialized');
}
- equal(parent.children()[0].options_['foo'], true, 'child options set when children array is used');
- equal(parent.children().length, 1, 'we should only have one child');
+ QUnit.equal(parent.children()[0].options_.foo, true, 'child options set when children array is used');
+ QUnit.equal(parent.children().length, 1, 'we should only have one child');
// using children object
options = {
- 'children': {
- 'component': {
- 'foo': false
+ children: {
+ component: {
+ foo: false
},
- 'nullComponent': {}
+ nullComponent: {}
},
// parent-level option for child
- 'component': {
- 'foo': true
+ component: {
+ foo: true
},
- 'nullComponent': false
+ nullComponent: false
};
try {
parent = new Component(getFakePlayer(), options);
- } catch(err) {
- ok(false, 'Child with `false` option was initialized');
+ } catch (err) {
+ QUnit.ok(false, 'Child with `false` option was initialized');
}
- equal(parent.children()[0].options_['foo'], true, 'child options set when children object is used');
- equal(parent.children().length, 1, 'we should only have one child');
+ QUnit.equal(parent.children()[0].options_.foo, true, 'child options set when children object is used');
+ QUnit.equal(parent.children().length, 1, 'we should only have one child');
});
-test('should dispose of component and children', function(){
- var comp = new Component(getFakePlayer());
+QUnit.test('should dispose of component and children', function() {
+ const comp = new Component(getFakePlayer());
// Add a child
- var child = comp.addChild('Component');
- ok(comp.children().length === 1);
+ const child = comp.addChild('Component');
+
+ QUnit.ok(comp.children().length === 1);
// Add a listener
- comp.on('click', function(){ return true; });
- var el = comp.el();
- var data = Dom.getElData(el);
+ comp.on('click', function() {
+ return true;
+ });
+ const el = comp.el();
+ const data = Dom.getElData(el);
+
+ let hasDisposed = false;
+ let bubbles = null;
- var hasDisposed = false;
- var bubbles = null;
- comp.on('dispose', function(event){
+ comp.on('dispose', function(event) {
hasDisposed = true;
bubbles = event.bubbles;
});
comp.dispose();
- ok(hasDisposed, 'component fired dispose event');
- ok(bubbles === false, 'dispose event does not bubble');
- ok(!comp.children(), 'component children were deleted');
- ok(!comp.el(), 'component element was deleted');
- ok(!child.children(), 'child children were deleted');
- ok(!child.el(), 'child element was deleted');
- ok(!Dom.hasElData(el), 'listener data nulled');
- ok(!Object.getOwnPropertyNames(data).length, 'original listener data object was emptied');
+ QUnit.ok(hasDisposed, 'component fired dispose event');
+ QUnit.ok(bubbles === false, 'dispose event does not bubble');
+ QUnit.ok(!comp.children(), 'component children were deleted');
+ QUnit.ok(!comp.el(), 'component element was deleted');
+ QUnit.ok(!child.children(), 'child children were deleted');
+ QUnit.ok(!child.el(), 'child element was deleted');
+ QUnit.ok(!Dom.hasElData(el), 'listener data nulled');
+ QUnit.ok(!Object.getOwnPropertyNames(data).length,
+ 'original listener data object was emptied');
});
-test('should add and remove event listeners to element', function(){
- var comp = new Component(getFakePlayer(), {});
+QUnit.test('should add and remove event listeners to element', function() {
+ const comp = new Component(getFakePlayer(), {});
// No need to make this async because we're triggering events inline.
// We're going to trigger the event after removing the listener,
// So if we get extra asserts that's a problem.
- expect(2);
+ QUnit.expect(2);
- var testListener = function(){
- ok(true, 'fired event once');
- ok(this === comp, 'listener has the component as context');
+ const testListener = function() {
+ QUnit.ok(true, 'fired event once');
+ QUnit.ok(this === comp, 'listener has the component as context');
};
comp.on('test-event', testListener);
@@ -271,13 +284,13 @@ test('should add and remove event listeners to element', function(){
comp.trigger('test-event');
});
-test('should trigger a listener once using one()', function(){
- var comp = new Component(getFakePlayer(), {});
+QUnit.test('should trigger a listener once using one()', function() {
+ const comp = new Component(getFakePlayer(), {});
- expect(1);
+ QUnit.expect(1);
- var testListener = function(){
- ok(true, 'fired event once');
+ const testListener = function() {
+ QUnit.ok(true, 'fired event once');
};
comp.one('test-event', testListener);
@@ -285,14 +298,15 @@ test('should trigger a listener once using one()', function(){
comp.trigger('test-event');
});
-test('should be possible to pass data when you trigger an event', function () {
- var comp = new Component(getFakePlayer(), {});
- var data1 = 'Data1';
- var data2 = {txt: 'Data2'};
- expect(3);
+QUnit.test('should be possible to pass data when you trigger an event', function() {
+ const comp = new Component(getFakePlayer(), {});
+ const data1 = 'Data1';
+ const data2 = {txt: 'Data2'};
+
+ QUnit.expect(3);
- var testListener = function(evt, hash){
- ok(true, 'fired event once');
+ const testListener = function(evt, hash) {
+ QUnit.ok(true, 'fired event once');
deepEqual(hash.d1, data1);
deepEqual(hash.d2, data2);
};
@@ -302,158 +316,160 @@ test('should be possible to pass data when you trigger an event', function () {
comp.trigger('test-event');
});
-test('should add listeners to other components and remove them', function(){
- var player = getFakePlayer(),
- comp1 = new Component(player),
- comp2 = new Component(player),
- listenerFired = 0,
- testListener;
+QUnit.test('should add listeners to other components and remove them', function() {
+ const player = getFakePlayer();
+ const comp1 = new Component(player);
+ const comp2 = new Component(player);
+ let listenerFired = 0;
- testListener = function(){
- equal(this, comp1, 'listener has the first component as context');
+ const testListener = function() {
+ QUnit.equal(this, comp1, 'listener has the first component as context');
listenerFired++;
};
comp1.on(comp2, 'test-event', testListener);
comp2.trigger('test-event');
- equal(listenerFired, 1, 'listener was fired once');
+ QUnit.equal(listenerFired, 1, 'listener was fired once');
listenerFired = 0;
comp1.off(comp2, 'test-event', testListener);
comp2.trigger('test-event');
- equal(listenerFired, 0, 'listener was not fired after being removed');
+ QUnit.equal(listenerFired, 0, 'listener was not fired after being removed');
// this component is disposed first
listenerFired = 0;
comp1.on(comp2, 'test-event', testListener);
comp1.dispose();
comp2.trigger('test-event');
- equal(listenerFired, 0, 'listener was removed when this component was disposed first');
- comp1.off = function(){ throw 'Comp1 off called'; };
+ QUnit.equal(listenerFired, 0, 'listener was removed when this component was disposed first');
+ comp1.off = function() {
+ throw new Error('Comp1 off called');
+ };
comp2.dispose();
- ok(true, 'this component removed dispose listeners from other component');
+ QUnit.ok(true, 'this component removed dispose listeners from other component');
});
-test('should add listeners to other components and remove when them other component is disposed', function(){
- var player = getFakePlayer(),
- comp1 = new Component(player),
- comp2 = new Component(player),
- listenerFired = 0,
- testListener;
+QUnit.test('should add listeners to other components and remove when them other component is disposed', function() {
+ const player = getFakePlayer();
+ const comp1 = new Component(player);
+ const comp2 = new Component(player);
+ let listenerFired = 0;
- testListener = function(){
- equal(this, comp1, 'listener has the first component as context');
+ const testListener = function() {
+ QUnit.equal(this, comp1, 'listener has the first component as context');
listenerFired++;
};
comp1.on(comp2, 'test-event', testListener);
comp2.dispose();
- comp2.off = function(){ throw 'Comp2 off called'; };
+ comp2.off = function() {
+ throw new Error('Comp2 off called');
+ };
comp1.dispose();
- ok(true, 'this component removed dispose listener from this component that referenced other component');
+ QUnit.ok(true, 'this component removed dispose listener from this component that referenced other component');
});
-test('should add listeners to other components that are fired once', function(){
- var player = getFakePlayer(),
- comp1 = new Component(player),
- comp2 = new Component(player),
- listenerFired = 0,
- testListener;
+QUnit.test('should add listeners to other components that are fired once', function() {
+ const player = getFakePlayer();
+ const comp1 = new Component(player);
+ const comp2 = new Component(player);
+ let listenerFired = 0;
- testListener = function(){
- equal(this, comp1, 'listener has the first component as context');
+ const testListener = function() {
+ QUnit.equal(this, comp1, 'listener has the first component as context');
listenerFired++;
};
comp1.one(comp2, 'test-event', testListener);
comp2.trigger('test-event');
- equal(listenerFired, 1, 'listener was executed once');
+ QUnit.equal(listenerFired, 1, 'listener was executed once');
comp2.trigger('test-event');
- equal(listenerFired, 1, 'listener was executed only once');
+ QUnit.equal(listenerFired, 1, 'listener was executed only once');
});
-test('should add listeners to other element and remove them', function(){
- var player = getFakePlayer(),
- comp1 = new Component(player),
- el = document.createElement('div'),
- listenerFired = 0,
- testListener;
+QUnit.test('should add listeners to other element and remove them', function() {
+ const player = getFakePlayer();
+ const comp1 = new Component(player);
+ const el = document.createElement('div');
+ let listenerFired = 0;
- testListener = function(){
- equal(this, comp1, 'listener has the first component as context');
+ const testListener = function() {
+ QUnit.equal(this, comp1, 'listener has the first component as context');
listenerFired++;
};
comp1.on(el, 'test-event', testListener);
Events.trigger(el, 'test-event');
- equal(listenerFired, 1, 'listener was fired once');
+ QUnit.equal(listenerFired, 1, 'listener was fired once');
listenerFired = 0;
comp1.off(el, 'test-event', testListener);
Events.trigger(el, 'test-event');
- equal(listenerFired, 0, 'listener was not fired after being removed from other element');
+ QUnit.equal(listenerFired, 0, 'listener was not fired after being removed from other element');
// this component is disposed first
listenerFired = 0;
comp1.on(el, 'test-event', testListener);
comp1.dispose();
Events.trigger(el, 'test-event');
- equal(listenerFired, 0, 'listener was removed when this component was disposed first');
- comp1.off = function(){ throw 'Comp1 off called'; };
+ QUnit.equal(listenerFired, 0, 'listener was removed when this component was disposed first');
+ comp1.off = function() {
+ throw new Error('Comp1 off called');
+ };
+
try {
Events.trigger(el, 'dispose');
- } catch(e) {
- ok(false, 'listener was not removed from other element');
+ } catch (e) {
+ QUnit.ok(false, 'listener was not removed from other element');
}
Events.trigger(el, 'dispose');
- ok(true, 'this component removed dispose listeners from other element');
+ QUnit.ok(true, 'this component removed dispose listeners from other element');
});
-test('should add listeners to other components that are fired once', function(){
- var player = getFakePlayer(),
- comp1 = new Component(player),
- el = document.createElement('div'),
- listenerFired = 0,
- testListener;
+QUnit.test('should add listeners to other components that are fired once', function() {
+ const player = getFakePlayer();
+ const comp1 = new Component(player);
+ const el = document.createElement('div');
+ let listenerFired = 0;
- testListener = function(){
- equal(this, comp1, 'listener has the first component as context');
+ const testListener = function() {
+ QUnit.equal(this, comp1, 'listener has the first component as context');
listenerFired++;
};
comp1.one(el, 'test-event', testListener);
Events.trigger(el, 'test-event');
- equal(listenerFired, 1, 'listener was executed once');
+ QUnit.equal(listenerFired, 1, 'listener was executed once');
Events.trigger(el, 'test-event');
- equal(listenerFired, 1, 'listener was executed only once');
+ QUnit.equal(listenerFired, 1, 'listener was executed only once');
});
-test('should trigger a listener when ready', function(){
+QUnit.test('should trigger a listener when ready', function() {
let initListenerFired;
let methodListenerFired;
let syncListenerFired;
- let comp = new Component(getFakePlayer(), {}, function(){
+ const comp = new Component(getFakePlayer(), {}, function() {
initListenerFired = true;
});
- comp.ready(function(){
+ comp.ready(function() {
methodListenerFired = true;
});
comp.triggerReady();
- comp.ready(function(){
+ comp.ready(function() {
syncListenerFired = true;
}, true);
- ok(!initListenerFired, 'init listener should NOT fire synchronously');
- ok(!methodListenerFired, 'method listener should NOT fire synchronously');
- ok(syncListenerFired, 'sync listener SHOULD fire synchronously if after ready');
+ QUnit.ok(!initListenerFired, 'init listener should NOT fire synchronously');
+ QUnit.ok(!methodListenerFired, 'method listener should NOT fire synchronously');
+ QUnit.ok(syncListenerFired, 'sync listener SHOULD fire synchronously if after ready');
this.clock.tick(1);
- ok(initListenerFired, 'init listener should fire asynchronously');
- ok(methodListenerFired, 'method listener should fire asynchronously');
+ QUnit.ok(initListenerFired, 'init listener should fire asynchronously');
+ QUnit.ok(methodListenerFired, 'method listener should fire asynchronously');
// Listeners should only be fired once and then removed
initListenerFired = false;
@@ -463,16 +479,17 @@ test('should trigger a listener when ready', function(){
comp.triggerReady();
this.clock.tick(1);
- ok(!initListenerFired, 'init listener should be removed');
- ok(!methodListenerFired, 'method listener should be removed');
- ok(!syncListenerFired, 'sync listener should be removed');
+ QUnit.ok(!initListenerFired, 'init listener should be removed');
+ QUnit.ok(!methodListenerFired, 'method listener should be removed');
+ QUnit.ok(!syncListenerFired, 'sync listener should be removed');
});
-test('should not retrigger a listener when the listener calls triggerReady', function(){
- var timesCalled = 0;
- var selfTriggered = false;
+QUnit.test('should not retrigger a listener when the listener calls triggerReady', function() {
+ let timesCalled = 0;
+ let selfTriggered = false;
+ const comp = new Component(getFakePlayer(), {});
- var readyListener = function(){
+ const readyListener = function() {
timesCalled++;
// Don't bother calling again if we have
@@ -483,71 +500,70 @@ test('should not retrigger a listener when the listener calls triggerReady', fun
}
};
- var comp = new Component(getFakePlayer(), {});
-
comp.ready(readyListener);
comp.triggerReady();
this.clock.tick(100);
- equal(timesCalled, 1, 'triggerReady from inside a ready handler does not result in an infinite loop');
+ QUnit.equal(timesCalled, 1, 'triggerReady from inside a ready handler does not result in an infinite loop');
});
-test('should add and remove a CSS class', function(){
- var comp = new Component(getFakePlayer(), {});
+QUnit.test('should add and remove a CSS class', function() {
+ const comp = new Component(getFakePlayer(), {});
comp.addClass('test-class');
- ok(comp.el().className.indexOf('test-class') !== -1);
+ QUnit.ok(comp.el().className.indexOf('test-class') !== -1);
comp.removeClass('test-class');
- ok(comp.el().className.indexOf('test-class') === -1);
+ QUnit.ok(comp.el().className.indexOf('test-class') === -1);
comp.toggleClass('test-class');
- ok(comp.el().className.indexOf('test-class') !== -1);
+ QUnit.ok(comp.el().className.indexOf('test-class') !== -1);
comp.toggleClass('test-class');
- ok(comp.el().className.indexOf('test-class') === -1);
+ QUnit.ok(comp.el().className.indexOf('test-class') === -1);
});
-test('should show and hide an element', function(){
- var comp = new Component(getFakePlayer(), {});
+QUnit.test('should show and hide an element', function() {
+ const comp = new Component(getFakePlayer(), {});
comp.hide();
- ok(comp.hasClass('vjs-hidden') === true);
+ QUnit.ok(comp.hasClass('vjs-hidden') === true);
comp.show();
- ok(comp.hasClass('vjs-hidden') === false);
+ QUnit.ok(comp.hasClass('vjs-hidden') === false);
});
-test('dimension() should treat NaN and null as zero', function() {
- var comp, width, height, newWidth, newHeight;
- width = 300;
- height = 150;
+QUnit.test('dimension() should treat NaN and null as zero', function() {
+ let newWidth;
- comp = new Component(getFakePlayer(), {}),
+ const width = 300;
+ const height = 150;
+
+ const comp = new Component(getFakePlayer(), {});
// set component dimension
comp.dimensions(width, height);
newWidth = comp.dimension('width', null);
- notEqual(newWidth, width, 'new width and old width are not the same');
- equal(newWidth, comp, 'we set a value, so, return value is component');
- equal(comp.width(), 0, 'the new width is zero');
+ QUnit.notEqual(newWidth, width, 'new width and old width are not the same');
+ QUnit.equal(newWidth, comp, 'we set a value, so, return value is component');
+ QUnit.equal(comp.width(), 0, 'the new width is zero');
- newHeight = comp.dimension('height', NaN);
+ const newHeight = comp.dimension('height', NaN);
- notEqual(newHeight, height, 'new height and old height are not the same');
- equal(newHeight, comp, 'we set a value, so, return value is component');
- equal(comp.height(), 0, 'the new height is zero');
+ QUnit.notEqual(newHeight, height, 'new height and old height are not the same');
+ QUnit.equal(newHeight, comp, 'we set a value, so, return value is component');
+ QUnit.equal(comp.height(), 0, 'the new height is zero');
comp.width(width);
newWidth = comp.dimension('width', undefined);
- equal(newWidth, width, 'we did not set the width with undefined');
+ QUnit.equal(newWidth, width, 'we did not set the width with undefined');
});
-test('should change the width and height of a component', function(){
- var container = document.createElement('div');
- var comp = new Component(getFakePlayer(), {});
- var el = comp.el();
- var fixture = document.getElementById('qunit-fixture');
+QUnit.test('should change the width and height of a component', function() {
+ const container = document.createElement('div');
+ const comp = new Component(getFakePlayer(), {});
+ const el = comp.el();
+ const fixture = document.getElementById('qunit-fixture');
fixture.appendChild(container);
container.appendChild(el);
@@ -558,21 +574,22 @@ test('should change the width and height of a component', function(){
comp.width('50%');
comp.height('123px');
- ok(comp.width() === 500, 'percent values working');
- var compStyle = TestHelpers.getComputedStyle(el, 'width');
- ok(compStyle === comp.width() + 'px', 'matches computed style');
- ok(comp.height() === 123, 'px values working');
+ QUnit.ok(comp.width() === 500, 'percent values working');
+ const compStyle = TestHelpers.getComputedStyle(el, 'width');
+
+ QUnit.ok(compStyle === comp.width() + 'px', 'matches computed style');
+ QUnit.ok(comp.height() === 123, 'px values working');
comp.width(321);
- ok(comp.width() === 321, 'integer values working');
+ QUnit.ok(comp.width() === 321, 'integer values working');
comp.width('auto');
comp.height('auto');
- ok(comp.width() === 1000, 'forced width was removed');
- ok(comp.height() === 0, 'forced height was removed');
+ QUnit.ok(comp.width() === 1000, 'forced width was removed');
+ QUnit.ok(comp.height() === 0, 'forced height was removed');
});
-test('should get the computed dimensions', function(){
+QUnit.test('should get the computed dimensions', function() {
const container = document.createElement('div');
const comp = new Component(getFakePlayer(), {});
const el = comp.el();
@@ -590,56 +607,57 @@ test('should get the computed dimensions', function(){
comp.width('50%');
comp.height('50%');
- equal(comp.currentWidth() + 'px', computedWidth, 'matches computed width');
- equal(comp.currentHeight() + 'px', computedHeight, 'matches computed height');
+ QUnit.equal(comp.currentWidth() + 'px', computedWidth, 'matches computed width');
+ QUnit.equal(comp.currentHeight() + 'px', computedHeight, 'matches computed height');
- equal(comp.currentDimension('width') + 'px', computedWidth, 'matches computed width');
- equal(comp.currentDimension('height') + 'px', computedHeight, 'matches computed height');
+ QUnit.equal(comp.currentDimension('width') + 'px', computedWidth, 'matches computed width');
+ QUnit.equal(comp.currentDimension('height') + 'px', computedHeight, 'matches computed height');
- equal(comp.currentDimensions()['width'] + 'px', computedWidth, 'matches computed width');
- equal(comp.currentDimensions()['height'] + 'px', computedHeight, 'matches computed width');
+ QUnit.equal(comp.currentDimensions().width + 'px', computedWidth, 'matches computed width');
+ QUnit.equal(comp.currentDimensions().height + 'px', computedHeight, 'matches computed width');
});
-test('should use a defined content el for appending children', function(){
+QUnit.test('should use a defined content el for appending children', function() {
class CompWithContent extends Component {}
- CompWithContent.prototype.createEl = function(){
+ CompWithContent.prototype.createEl = function() {
// Create the main componenent element
- var el = Dom.createEl('div');
+ const el = Dom.createEl('div');
+
// Create the element where children will be appended
- this.contentEl_ = Dom.createEl('div', { 'id': 'contentEl' });
+ this.contentEl_ = Dom.createEl('div', { id: 'contentEl' });
el.appendChild(this.contentEl_);
return el;
};
- var comp = new CompWithContent(getFakePlayer());
- var child = comp.addChild('component');
+ const comp = new CompWithContent(getFakePlayer());
+ const child = comp.addChild('component');
- ok(comp.children().length === 1);
- ok(comp.el().childNodes[0]['id'] === 'contentEl');
- ok(comp.el().childNodes[0].childNodes[0] === child.el());
+ QUnit.ok(comp.children().length === 1);
+ QUnit.ok(comp.el().childNodes[0].id === 'contentEl');
+ QUnit.ok(comp.el().childNodes[0].childNodes[0] === child.el());
comp.removeChild(child);
- ok(comp.children().length === 0, 'Length should now be zero');
- ok(comp.el().childNodes[0]['id'] === 'contentEl', 'Content El should still exist');
- ok(comp.el().childNodes[0].childNodes[0] !== child.el(), 'Child el should be removed.');
+ QUnit.ok(comp.children().length === 0, 'Length should now be zero');
+ QUnit.ok(comp.el().childNodes[0].id === 'contentEl', 'Content El should still exist');
+ QUnit.ok(comp.el().childNodes[0].childNodes[0] !== child.el(),
+ 'Child el should be removed.');
});
-test('should emit a tap event', function(){
- expect(3);
+QUnit.test('should emit a tap event', function() {
+ const comp = new Component(getFakePlayer());
+ let singleTouch = {};
+ const origTouch = browser.TOUCH_ENABLED;
+ QUnit.expect(3);
// Fake touch support. Real touch support isn't needed for this test.
- var origTouch = browser.TOUCH_ENABLED;
browser.TOUCH_ENABLED = true;
- var comp = new Component(getFakePlayer());
- var singleTouch = {};
-
comp.emitTapEvents();
- comp.on('tap', function(){
- ok(true, 'Tap event emitted');
+ comp.on('tap', function() {
+ QUnit.ok(true, 'Tap event emitted');
});
// A touchstart followed by touchend should trigger a tap
@@ -686,31 +704,30 @@ test('should emit a tap event', function(){
browser.TOUCH_ENABLED = origTouch;
});
-test('should provide timeout methods that automatically get cleared on component disposal', function() {
- expect(4);
+QUnit.test('should provide timeout methods that automatically get cleared on component disposal', function() {
+ const comp = new Component(getFakePlayer());
+ let timeoutsFired = 0;
+ const timeoutToClear = comp.setTimeout(function() {
+ timeoutsFired++;
+ QUnit.ok(false, 'Timeout should have been manually cleared');
+ }, 500);
- var comp = new Component(getFakePlayer());
- var timeoutsFired = 0;
+ QUnit.expect(4);
comp.setTimeout(function() {
timeoutsFired++;
- equal(this, comp, 'Timeout fn has the component as its context');
- ok(true, 'Timeout created and fired.');
+ QUnit.equal(this, comp, 'Timeout fn has the component as its context');
+ QUnit.ok(true, 'Timeout created and fired.');
}, 100);
- var timeoutToClear = comp.setTimeout(function() {
- timeoutsFired++;
- ok(false, 'Timeout should have been manually cleared');
- }, 500);
-
comp.setTimeout(function() {
timeoutsFired++;
- ok(false, 'Timeout should have been disposed');
+ QUnit.ok(false, 'Timeout should have been disposed');
}, 1000);
this.clock.tick(100);
- ok(timeoutsFired === 1, 'One timeout should have fired by this point');
+ QUnit.ok(timeoutsFired === 1, 'One timeout should have fired by this point');
comp.clearTimeout(timeoutToClear);
@@ -720,47 +737,48 @@ test('should provide timeout methods that automatically get cleared on component
this.clock.tick(1000);
- ok(timeoutsFired === 1, 'One timeout should have fired overall');
+ QUnit.ok(timeoutsFired === 1, 'One timeout should have fired overall');
});
-test('should provide interval methods that automatically get cleared on component disposal', function() {
- expect(13);
+QUnit.test('should provide interval methods that automatically get cleared on component disposal', function() {
+ const comp = new Component(getFakePlayer());
- var comp = new Component(getFakePlayer());
- var intervalsFired = 0;
+ let intervalsFired = 0;
- var interval = comp.setInterval(function() {
+ const interval = comp.setInterval(function() {
intervalsFired++;
- equal(this, comp, 'Interval fn has the component as its context');
- ok(true, 'Interval created and fired.');
+ QUnit.equal(this, comp, 'Interval fn has the component as its context');
+ QUnit.ok(true, 'Interval created and fired.');
}, 100);
+ QUnit.expect(13);
+
comp.setInterval(function() {
intervalsFired++;
- ok(false, 'Interval should have been disposed');
+ QUnit.ok(false, 'Interval should have been disposed');
}, 1200);
this.clock.tick(500);
- ok(intervalsFired === 5, 'Component interval fired 5 times');
+ QUnit.ok(intervalsFired === 5, 'Component interval fired 5 times');
comp.clearInterval(interval);
this.clock.tick(600);
- ok(intervalsFired === 5, 'Interval was manually cleared');
+ QUnit.ok(intervalsFired === 5, 'Interval was manually cleared');
comp.dispose();
this.clock.tick(1200);
- ok(intervalsFired === 5, 'Interval was cleared when component was disposed');
+ QUnit.ok(intervalsFired === 5, 'Interval was cleared when component was disposed');
});
-test('$ and $$ functions', function() {
- var comp = new Component(getFakePlayer());
- var contentEl = document.createElement('div');
- var children = [
+QUnit.test('$ and $$ functions', function() {
+ const comp = new Component(getFakePlayer());
+ const contentEl = document.createElement('div');
+ const children = [
document.createElement('div'),
document.createElement('div')
];
@@ -768,6 +786,6 @@ test('$ and $$ functions', function() {
comp.contentEl_ = contentEl;
children.forEach(child => contentEl.appendChild(child));
- strictEqual(comp.$('div'), children[0], '$ defaults to contentEl as scope');
- strictEqual(comp.$$('div').length, children.length, '$$ defaults to contentEl as scope');
+ QUnit.strictEqual(comp.$('div'), children[0], '$ defaults to contentEl as scope');
+ QUnit.strictEqual(comp.$$('div').length, children.length, '$$ defaults to contentEl as scope');
});
diff --git a/test/unit/controls.test.js b/test/unit/controls.test.js
index d57e45e437..e2a8efc2fc 100644
--- a/test/unit/controls.test.js
+++ b/test/unit/controls.test.js
@@ -1,3 +1,4 @@
+/* eslint-env qunit */
import VolumeControl from '../../src/js/control-bar/volume-control/volume-control.js';
import MuteToggle from '../../src/js/control-bar/mute-toggle.js';
import PlaybackRateMenuButton from '../../src/js/control-bar/playback-rate-menu/playback-rate-menu-button.js';
@@ -5,110 +6,107 @@ import Slider from '../../src/js/slider/slider.js';
import TestHelpers from './test-helpers.js';
import document from 'global/document';
-q.module('Controls');
+QUnit.module('Controls');
-test('should hide volume control if it\'s not supported', function(){
- expect(2);
-
- var noop, player, volumeControl, muteToggle;
- noop = function(){};
- player = {
+QUnit.test('should hide volume control if it\'s not supported', function() {
+ QUnit.expect(2);
+ const noop = function() {};
+ const player = {
id: noop,
on: noop,
ready: noop,
tech_: {
- 'featuresVolumeControl': false
+ featuresVolumeControl: false
},
- volume: function(){},
- muted: function(){},
- reportUserActivity: function(){}
+ volume() {},
+ muted() {},
+ reportUserActivity() {}
};
- volumeControl = new VolumeControl(player);
- muteToggle = new MuteToggle(player);
+ const volumeControl = new VolumeControl(player);
+ const muteToggle = new MuteToggle(player);
- ok(volumeControl.el().className.indexOf('vjs-hidden') >= 0, 'volumeControl is not hidden');
- ok(muteToggle.el().className.indexOf('vjs-hidden') >= 0, 'muteToggle is not hidden');
+ QUnit.ok(volumeControl.el().className.indexOf('vjs-hidden') >= 0, 'volumeControl is not hidden');
+ QUnit.ok(muteToggle.el().className.indexOf('vjs-hidden') >= 0, 'muteToggle is not hidden');
});
-test('should test and toggle volume control on `loadstart`', function(){
- var noop, listeners, player, volumeControl, muteToggle, i;
- noop = function(){};
- listeners = [];
- player = {
+QUnit.test('should test and toggle volume control on `loadstart`', function() {
+ const noop = function() {};
+ const listeners = [];
+ const player = {
id: noop,
- on: function(event, callback){
+ on(event, callback) {
// don't fire dispose listeners
if (event !== 'dispose') {
listeners.push(callback);
}
},
ready: noop,
- volume: function(){
+ volume() {
return 1;
},
- muted: function(){
+ muted() {
return false;
},
tech_: {
- 'featuresVolumeControl': true
+ featuresVolumeControl: true
},
- reportUserActivity: function(){}
+ reportUserActivity() {}
};
- volumeControl = new VolumeControl(player);
- muteToggle = new MuteToggle(player);
+ const volumeControl = new VolumeControl(player);
+ const muteToggle = new MuteToggle(player);
- equal(volumeControl.hasClass('vjs-hidden'), false, 'volumeControl is hidden initially');
- equal(muteToggle.hasClass('vjs-hidden'), false, 'muteToggle is hidden initially');
+ QUnit.equal(volumeControl.hasClass('vjs-hidden'), false, 'volumeControl is hidden initially');
+ QUnit.equal(muteToggle.hasClass('vjs-hidden'), false, 'muteToggle is hidden initially');
- player.tech_['featuresVolumeControl'] = false;
- for (i = 0; i < listeners.length; i++) {
+ player.tech_.featuresVolumeControl = false;
+ for (let i = 0; i < listeners.length; i++) {
listeners[i]();
}
- equal(volumeControl.hasClass('vjs-hidden'), true, 'volumeControl does not hide itself');
- equal(muteToggle.hasClass('vjs-hidden'), true, 'muteToggle does not hide itself');
+ QUnit.equal(volumeControl.hasClass('vjs-hidden'), true, 'volumeControl does not hide itself');
+ QUnit.equal(muteToggle.hasClass('vjs-hidden'), true, 'muteToggle does not hide itself');
- player.tech_['featuresVolumeControl'] = true;
- for (i = 0; i < listeners.length; i++) {
+ player.tech_.featuresVolumeControl = true;
+ for (let i = 0; i < listeners.length; i++) {
listeners[i]();
}
- equal(volumeControl.hasClass('vjs-hidden'), false, 'volumeControl does not show itself');
- equal(muteToggle.hasClass('vjs-hidden'), false, 'muteToggle does not show itself');
+ QUnit.equal(volumeControl.hasClass('vjs-hidden'), false, 'volumeControl does not show itself');
+ QUnit.equal(muteToggle.hasClass('vjs-hidden'), false, 'muteToggle does not show itself');
});
-test('calculateDistance should use changedTouches, if available', function() {
- var noop, player, slider, event;
- noop = function(){};
- player = {
+QUnit.test('calculateDistance should use changedTouches, if available', function() {
+ const noop = function() {};
+ const player = {
id: noop,
on: noop,
ready: noop,
reportUserActivity: noop
};
- slider = new Slider(player);
+ const slider = new Slider(player);
+
document.body.appendChild(slider.el_);
slider.el_.style.position = 'absolute';
slider.el_.style.width = '200px';
slider.el_.style.left = '0px';
- event = {
+ const event = {
pageX: 10,
changedTouches: [{
pageX: 100
}]
};
- equal(slider.calculateDistance(event), 0.5, 'we should have touched exactly in the center, so, the ratio should be half');
+ QUnit.equal(slider.calculateDistance(event), 0.5, 'we should have touched exactly in the center, so, the ratio should be half');
});
-test('should hide playback rate control if it\'s not supported', function(){
- expect(1);
+QUnit.test('should hide playback rate control if it\'s not supported', function() {
+ QUnit.expect(1);
- var player = TestHelpers.makePlayer();
- var playbackRate = new PlaybackRateMenuButton(player);
+ const player = TestHelpers.makePlayer();
+ const playbackRate = new PlaybackRateMenuButton(player);
- ok(playbackRate.el().className.indexOf('vjs-hidden') >= 0, 'playbackRate is not hidden');
+ QUnit.ok(playbackRate.el().className.indexOf('vjs-hidden') >= 0, 'playbackRate is not hidden');
});
diff --git a/test/unit/events.test.js b/test/unit/events.test.js
index 1083c095d4..1f1add911e 100644
--- a/test/unit/events.test.js
+++ b/test/unit/events.test.js
@@ -1,28 +1,31 @@
+/* eslint-env qunit */
import * as Events from '../../src/js/utils/events.js';
import document from 'global/document';
-q.module('Events');
+QUnit.module('Events');
-test('should add and remove an event listener to an element', function(){
- expect(1);
+QUnit.test('should add and remove an event listener to an element', function() {
+ QUnit.expect(1);
- var el = document.createElement('div');
- var listener = function(){
- ok(true, 'Click Triggered');
+ const el = document.createElement('div');
+ const listener = function() {
+ QUnit.ok(true, 'Click Triggered');
};
Events.on(el, 'click', listener);
- Events.trigger(el, 'click'); // 1 click
+ // 1 click
+ Events.trigger(el, 'click');
Events.off(el, 'click', listener);
- Events.trigger(el, 'click'); // No click should happen.
+ // No click should happen.
+ Events.trigger(el, 'click');
});
-test('should add and remove multiple event listeners to an element with a single call', function(){
- expect(6);
+QUnit.test('should add and remove multiple event listeners to an element with a single call', function() {
+ QUnit.expect(6);
- var el = document.createElement('div');
- var listener = function(){
- ok(true, 'Callback triggered');
+ const el = document.createElement('div');
+ const listener = function() {
+ QUnit.ok(true, 'Callback triggered');
};
Events.on(el, ['click', 'event1', 'event2'], listener);
@@ -30,92 +33,101 @@ test('should add and remove multiple event listeners to an element with a single
Events.trigger(el, 'click');
Events.trigger(el, 'click');
Events.off(el, 'click', listener);
- Events.trigger(el, 'click'); // No click should happen.
+ // No click should happen.
+ Events.trigger(el, 'click');
Events.trigger(el, 'event1');
Events.trigger(el, 'event1');
Events.off(el, 'event1', listener);
- Events.trigger(el, 'event1'); // No event1 should happen.
+ // No event1 should happen.
+ Events.trigger(el, 'event1');
Events.trigger(el, 'event2');
Events.trigger(el, 'event2');
Events.off(el, 'event2', listener);
- Events.trigger(el, 'event2'); // No event2 should happen.
+ // No event2 should happen.
+ Events.trigger(el, 'event2');
});
-test('should be possible to pass data when you trigger an event', function () {
- expect(6);
- var el = document.createElement('div');
- var fakeData1 = 'Fake Data 1';
- var fakeData2 = {txt: 'Fake Data 2'};
+QUnit.test('should be possible to pass data when you trigger an event', function() {
+ QUnit.expect(6);
+ const el = document.createElement('div');
+ const fakeData1 = 'Fake Data 1';
+ const fakeData2 = {txt: 'Fake Data 2'};
- var listener = function(evt, hash){
- ok(true, 'Callback triggered');
+ const listener = function(evt, hash) {
+ QUnit.ok(true, 'Callback triggered');
deepEqual(fakeData1, hash.d1, 'Shoulbe be passed to the handler');
deepEqual(fakeData2, hash.d2, 'Shoulbe be passed to the handler');
};
Events.on(el, ['event1', 'event2'], listener);
- Events.trigger(el, 'event1', { d1: fakeData1, d2:fakeData2});
- Events.trigger(el, 'event2', { d1: fakeData1, d2:fakeData2});
+ Events.trigger(el, 'event1', { d1: fakeData1, d2: fakeData2});
+ Events.trigger(el, 'event2', { d1: fakeData1, d2: fakeData2});
});
-test('should remove all listeners of a type', function(){
- var el = document.createElement('div');
- var clicks = 0;
- var listener = function(){
+QUnit.test('should remove all listeners of a type', function() {
+ const el = document.createElement('div');
+ let clicks = 0;
+ const listener = function() {
clicks++;
};
- var listener2 = function(){
+ const listener2 = function() {
clicks++;
};
Events.on(el, 'click', listener);
Events.on(el, 'click', listener2);
- Events.trigger(el, 'click'); // 2 clicks
+ // 2 clicks
+ Events.trigger(el, 'click');
- ok(clicks === 2, 'both click listeners fired');
+ QUnit.ok(clicks === 2, 'both click listeners fired');
Events.off(el, 'click');
- Events.trigger(el, 'click'); // No click should happen.
+ // No click should happen.
+ Events.trigger(el, 'click');
- ok(clicks === 2, 'no click listeners fired');
+ QUnit.ok(clicks === 2, 'no click listeners fired');
});
-test('should remove all listeners of an array of types', function(){
- var el = document.createElement('div');
- var calls = 0;
- var listener = function(){
+QUnit.test('should remove all listeners of an array of types', function() {
+ const el = document.createElement('div');
+ let calls = 0;
+ const listener = function() {
calls++;
};
- var listener2 = function(){
+ const listener2 = function() {
calls++;
};
Events.on(el, ['click', 'event1'], listener);
Events.on(el, ['click', 'event1'], listener2);
- Events.trigger(el, 'click'); // 2 calls
- Events.trigger(el, 'event1'); // 2 calls
+ // 2 calls
+ Events.trigger(el, 'click');
+ // 2 calls
+ Events.trigger(el, 'event1');
- ok(calls === 4, 'both click listeners fired');
+ QUnit.ok(calls === 4, 'both click listeners fired');
Events.off(el, ['click', 'event1']);
- Events.trigger(el, 'click'); // No click should happen.
- Events.trigger(el, 'event1'); // No event1 should happen.
+ // No click should happen.
+ Events.trigger(el, 'click');
+ // No event1 should happen.
+ Events.trigger(el, 'event1');
- ok(calls === 4, 'no event listeners fired');
+ QUnit.ok(calls === 4, 'no event listeners fired');
});
-test('should remove all listeners from an element', function(){
- expect(2);
+QUnit.test('should remove all listeners from an element', function() {
+ QUnit.expect(2);
- var el = document.createElement('div');
- var listener = function(){
- ok(true, 'Fake1 Triggered');
+ const el = document.createElement('div');
+ const listener = function() {
+ QUnit.ok(true, 'Fake1 Triggered');
};
- var listener2 = function(){
- ok(true, 'Fake2 Triggered');
+ const listener2 = function() {
+ QUnit.ok(true, 'Fake2 Triggered');
};
Events.on(el, 'fake1', listener);
@@ -131,111 +143,119 @@ test('should remove all listeners from an element', function(){
Events.trigger(el, 'fake2');
});
-test('should listen only once', function(){
- expect(1);
+QUnit.test('should listen only once', function() {
+ QUnit.expect(1);
- var el = document.createElement('div');
- var listener = function(){
- ok(true, 'Click Triggered');
+ const el = document.createElement('div');
+ const listener = function() {
+ QUnit.ok(true, 'Click Triggered');
};
Events.one(el, 'click', listener);
- Events.trigger(el, 'click'); // 1 click
- Events.trigger(el, 'click'); // No click should happen.
+ // 1 click
+ Events.trigger(el, 'click');
+ // No click should happen.
+ Events.trigger(el, 'click');
});
-test( 'should listen only once in multiple events from a single call', function(){
- expect(3);
+QUnit.test('should listen only once in multiple events from a single call', function() {
+ QUnit.expect(3);
- var el = document.createElement('div');
- var listener = function(){
- ok(true, 'Callback Triggered');
+ const el = document.createElement('div');
+ const listener = function() {
+ QUnit.ok(true, 'Callback Triggered');
};
Events.one(el, ['click', 'event1', 'event2'], listener);
- Events.trigger(el, 'click'); // 1 click
- Events.trigger(el, 'click'); // No click should happen.
- Events.trigger(el, 'event1'); // event1 must be handled.
- Events.trigger(el, 'event1'); // No event1 should be handled.
- Events.trigger(el, 'event2'); // event2 must be handled.
- Events.trigger(el, 'event2'); // No event2 should be handled.
+ // 1 click
+ Events.trigger(el, 'click');
+ // No click should happen.
+ Events.trigger(el, 'click');
+ // event1 must be handled.
+ Events.trigger(el, 'event1');
+ // No event1 should be handled.
+ Events.trigger(el, 'event1');
+ // event2 must be handled.
+ Events.trigger(el, 'event2');
+ // No event2 should be handled.
+ Events.trigger(el, 'event2');
});
-test('should stop immediate propagtion', function(){
- expect(1);
+QUnit.test('should stop immediate propagtion', function() {
+ QUnit.expect(1);
- var el = document.createElement('div');
+ const el = document.createElement('div');
- Events.on(el, 'test', function(e){
- ok(true, 'First listener fired');
+ Events.on(el, 'test', function(e) {
+ QUnit.ok(true, 'First listener fired');
e.stopImmediatePropagation();
});
- Events.on(el, 'test', function(e){
- ok(false, 'Second listener fired');
+ Events.on(el, 'test', function(e) {
+ QUnit.ok(false, 'Second listener fired');
});
Events.trigger(el, 'test');
});
-test('should bubble up DOM unless bubbles == false', function(){
- expect(3);
+QUnit.test('should bubble up DOM unless bubbles == false', function() {
+ QUnit.expect(3);
- var outer = document.createElement('div');
- var inner = outer.appendChild(document.createElement('div'));
+ const outer = document.createElement('div');
+ const inner = outer.appendChild(document.createElement('div'));
// Verify that if bubbles === true, event bubbles up dom.
- Events.on(inner, 'bubbles', function(e){
- ok(true, 'Inner listener fired');
+ Events.on(inner, 'bubbles', function(e) {
+ QUnit.ok(true, 'Inner listener fired');
});
- Events.on(outer, 'bubbles', function(e){
- ok(true, 'Outer listener fired');
+ Events.on(outer, 'bubbles', function(e) {
+ QUnit.ok(true, 'Outer listener fired');
});
- Events.trigger(inner, { type:'bubbles', target:inner, bubbles:true });
+ Events.trigger(inner, { type: 'bubbles', target: inner, bubbles: true });
// Only change 'bubbles' to false, and verify only inner handler is called.
- Events.on(inner, 'nobub', function(e){
- ok(true, 'Inner listener fired');
+ Events.on(inner, 'nobub', function(e) {
+ QUnit.ok(true, 'Inner listener fired');
});
- Events.on(outer, 'nobub', function(e){
- ok(false, 'Outer listener fired');
+ Events.on(outer, 'nobub', function(e) {
+ QUnit.ok(false, 'Outer listener fired');
});
- Events.trigger(inner, { type:'nobub', target:inner, bubbles:false });
+ Events.trigger(inner, { type: 'nobub', target: inner, bubbles: false });
});
-test('should have a defaultPrevented property on an event that was prevent from doing default action', function() {
- expect(2);
+QUnit.test('should have a defaultPrevented property on an event that was prevent from doing default action', function() {
+ QUnit.expect(2);
- var el = document.createElement('div');
+ const el = document.createElement('div');
- Events.on(el, 'test', function(e){
- ok(true, 'First listener fired');
+ Events.on(el, 'test', function(e) {
+ QUnit.ok(true, 'First listener fired');
e.preventDefault();
});
- Events.on(el, 'test', function(e){
- ok(e.defaultPrevented, 'Should have `defaultPrevented` to signify preventDefault being called');
+ Events.on(el, 'test', function(e) {
+ QUnit.ok(e.defaultPrevented, 'Should have `defaultPrevented` to signify preventDefault being called');
});
Events.trigger(el, 'test');
});
-test('should have relatedTarget correctly set on the event', function() {
- expect(2);
+QUnit.test('should have relatedTarget correctly set on the event', function() {
+ QUnit.expect(2);
- var el1 = document.createElement('div'),
- el2 = document.createElement('div'),
- relatedEl = document.createElement('div');
+ const el1 = document.createElement('div');
+ const el2 = document.createElement('div');
+ const relatedEl = document.createElement('div');
- Events.on(el1, 'click', function(e){
- equal(e.relatedTarget, relatedEl, 'relatedTarget is set for all browsers when related element is set on the event');
+ Events.on(el1, 'click', function(e) {
+ QUnit.equal(e.relatedTarget, relatedEl, 'relatedTarget is set for all browsers when related element is set on the event');
});
- Events.trigger(el1, { type:'click', relatedTarget:relatedEl });
+ Events.trigger(el1, { type: 'click', relatedTarget: relatedEl });
Events.on(el2, 'click', function(e) {
- equal(e.relatedTarget, null, 'relatedTarget is null when none is provided');
+ QUnit.equal(e.relatedTarget, null, 'relatedTarget is null when none is provided');
});
- Events.trigger(el2, { type:'click', relatedTarget:undefined });
+ Events.trigger(el2, { type: 'click', relatedTarget: undefined });
});
diff --git a/test/unit/extend.test.js b/test/unit/extend.test.js
index 12d8ae2894..3b5c7da469 100644
--- a/test/unit/extend.test.js
+++ b/test/unit/extend.test.js
@@ -1,16 +1,18 @@
+/* eslint-env qunit */
import extendFn from '../../src/js/extend.js';
-q.module('extend.js');
+QUnit.module('extend.js');
-test('should add implicit parent constructor call', function(){
- var superCalled = false;
- var Parent = function() {
+QUnit.test('should add implicit parent constructor call', function() {
+ let superCalled = false;
+ const Parent = function() {
superCalled = true;
};
- var Child = extendFn(Parent, {
- foo: 'bar'
+ const Child = extendFn(Parent, {
+ foo: 'bar'
});
- var child = new Child();
- ok(superCalled, 'super constructor called');
- ok(child.foo, 'child properties set');
+ const child = new Child();
+
+ QUnit.ok(superCalled, 'super constructor called');
+ QUnit.ok(child.foo, 'child properties set');
});
diff --git a/test/unit/menu.test.js b/test/unit/menu.test.js
index a7345e7ff9..12ec097f07 100644
--- a/test/unit/menu.test.js
+++ b/test/unit/menu.test.js
@@ -1,75 +1,75 @@
+/* eslint-env qunit */
import MenuButton from '../../src/js/menu/menu-button.js';
import TestHelpers from './test-helpers.js';
import * as Events from '../../src/js/utils/events.js';
-q.module('MenuButton');
+QUnit.module('MenuButton');
-q.test('should not throw an error when there is no children', function() {
- expect(0);
- let player = TestHelpers.makePlayer();
+QUnit.test('should not throw an error when there is no children', function() {
+ QUnit.expect(0);
+ const player = TestHelpers.makePlayer();
- let menuButton = new MenuButton(player);
- let el = menuButton.el();
+ const menuButton = new MenuButton(player);
+ const el = menuButton.el();
try {
Events.trigger(el, 'click');
} catch (error) {
- ok(!error, 'click should not throw anything');
+ QUnit.ok(!error, 'click should not throw anything');
}
player.dispose();
});
-q.test('should place title list item into ul', function() {
- var player, menuButton;
- player = TestHelpers.makePlayer();
+QUnit.test('should place title list item into ul', function() {
+ const player = TestHelpers.makePlayer();
- menuButton = new MenuButton(player, {
- 'title': 'testTitle'
+ const menuButton = new MenuButton(player, {
+ title: 'testTitle'
});
- let menuContentElement = menuButton.el().getElementsByTagName('UL')[0];
- let titleElement = menuContentElement.children[0];
+ const menuContentElement = menuButton.el().getElementsByTagName('UL')[0];
+ const titleElement = menuContentElement.children[0];
- ok(titleElement.innerHTML === 'TestTitle', 'title element placed in ul');
+ QUnit.ok(titleElement.innerHTML === 'TestTitle', 'title element placed in ul');
player.dispose();
});
-q.test('clicking should display the menu', function() {
- expect(6);
+QUnit.test('clicking should display the menu', function() {
+ QUnit.expect(6);
- let player = TestHelpers.makePlayer();
+ const player = TestHelpers.makePlayer();
// Make sure there's some content in the menu, even if it's just a title!
- let menuButton = new MenuButton(player, {
- 'title': 'testTitle'
+ const menuButton = new MenuButton(player, {
+ title: 'testTitle'
});
- let el = menuButton.el();
+ const el = menuButton.el();
- ok(menuButton.menu !== undefined, 'menu is created');
+ QUnit.ok(menuButton.menu !== undefined, 'menu is created');
- equal(menuButton.menu.hasClass('vjs-lock-showing'), false, 'menu defaults to hidden');
+ QUnit.equal(menuButton.menu.hasClass('vjs-lock-showing'), false, 'menu defaults to hidden');
Events.trigger(el, 'click');
- equal(menuButton.menu.hasClass('vjs-lock-showing'), true, 'clicking on the menu button shows the menu');
+ QUnit.equal(menuButton.menu.hasClass('vjs-lock-showing'), true, 'clicking on the menu button shows the menu');
Events.trigger(el, 'click');
- equal(menuButton.menu.hasClass('vjs-lock-showing'), false, 'clicking again on the menu button hides the menu');
+ QUnit.equal(menuButton.menu.hasClass('vjs-lock-showing'), false, 'clicking again on the menu button hides the menu');
menuButton.disable();
Events.trigger(el, 'click');
- equal(menuButton.menu.hasClass('vjs-lock-showing'), false, 'disable() prevents clicking from showing the menu');
+ QUnit.equal(menuButton.menu.hasClass('vjs-lock-showing'), false, 'disable() prevents clicking from showing the menu');
menuButton.enable();
Events.trigger(el, 'click');
- equal(menuButton.menu.hasClass('vjs-lock-showing'), true, 'enable() allows clicking to show the menu');
+ QUnit.equal(menuButton.menu.hasClass('vjs-lock-showing'), true, 'enable() allows clicking to show the menu');
player.dispose();
});
diff --git a/test/unit/modal-dialog.test.js b/test/unit/modal-dialog.test.js
index 1e04c994f5..8d094515f2 100644
--- a/test/unit/modal-dialog.test.js
+++ b/test/unit/modal-dialog.test.js
@@ -1,28 +1,29 @@
+/* eslint-env qunit */
import CloseButton from '../../src/js/close-button';
+import sinon from 'sinon';
import ModalDialog from '../../src/js/modal-dialog';
import * as Dom from '../../src/js/utils/dom';
-import * as Fn from '../../src/js/utils/fn';
import TestHelpers from './test-helpers';
-var ESC = 27;
+const ESC = 27;
-q.module('ModalDialog', {
+QUnit.module('ModalDialog', {
- beforeEach: function() {
+ beforeEach() {
this.player = TestHelpers.makePlayer();
this.modal = new ModalDialog(this.player, {temporary: false});
this.el = this.modal.el();
},
- afterEach: function() {
+ afterEach() {
this.player.dispose();
this.modal.dispose();
this.el = null;
}
});
-q.test('should create the expected element', function(assert) {
- let elAssertions = TestHelpers.assertEl(assert, this.el, {
+QUnit.test('should create the expected element', function(assert) {
+ const elAssertions = TestHelpers.assertEl(assert, this.el, {
tagName: 'div',
classes: [
'vjs-modal-dialog',
@@ -43,8 +44,8 @@ q.test('should create the expected element', function(assert) {
elAssertions();
});
-q.test('should create the expected description element', function(assert) {
- let elAssertions = TestHelpers.assertEl(assert, this.modal.descEl_, {
+QUnit.test('should create the expected description element', function(assert) {
+ const elAssertions = TestHelpers.assertEl(assert, this.modal.descEl_, {
tagName: 'p',
innerHTML: this.modal.description(),
classes: [
@@ -60,8 +61,8 @@ q.test('should create the expected description element', function(assert) {
elAssertions();
});
-q.test('should create the expected contentEl', function(assert) {
- let elAssertions = TestHelpers.assertEl(assert, this.modal.contentEl(), {
+QUnit.test('should create the expected contentEl', function(assert) {
+ const elAssertions = TestHelpers.assertEl(assert, this.modal.contentEl(), {
tagName: 'div',
classes: [
'vjs-modal-dialog-content'
@@ -75,8 +76,8 @@ q.test('should create the expected contentEl', function(assert) {
elAssertions();
});
-q.test('should create a close button by default', function(assert) {
- var btn = this.modal.getChild('closeButton');
+QUnit.test('should create a close button by default', function(assert) {
+ const btn = this.modal.getChild('closeButton');
// We only check the aspects of the button that relate to the modal. Other
// aspects of the button (classes, etc) are tested in their appropriate test
@@ -86,8 +87,8 @@ q.test('should create a close button by default', function(assert) {
assert.strictEqual(btn.el().parentNode, this.el, 'close button is a child of el');
});
-q.test('returns `this` for expected methods', function(assert) {
- var methods = ['close', 'empty', 'fill', 'fillWith', 'open'];
+QUnit.test('returns `this` for expected methods', function(assert) {
+ const methods = ['close', 'empty', 'fill', 'fillWith', 'open'];
assert.expect(methods.length);
methods.forEach(function(method) {
@@ -95,13 +96,13 @@ q.test('returns `this` for expected methods', function(assert) {
}, this.modal);
});
-q.test('open() triggers events', function(assert) {
- var modal = this.modal;
- var beforeModalOpenSpy = sinon.spy(function() {
+QUnit.test('open() triggers events', function(assert) {
+ const modal = this.modal;
+ const beforeModalOpenSpy = sinon.spy(function() {
assert.notOk(modal.opened(), 'modal is not opened before opening event');
});
- var modalOpenSpy = sinon.spy(function() {
+ const modalOpenSpy = sinon.spy(function() {
assert.ok(modal.opened(), 'modal is opened on opening event');
});
@@ -116,15 +117,15 @@ q.test('open() triggers events', function(assert) {
assert.strictEqual(modalOpenSpy.callCount, 1, 'modalopen spy was called');
});
-q.test('open() removes "vjs-hidden" class', function(assert) {
+QUnit.test('open() removes "vjs-hidden" class', function(assert) {
assert.expect(2);
assert.ok(this.modal.hasClass('vjs-hidden'), 'modal starts hidden');
this.modal.open();
assert.notOk(this.modal.hasClass('vjs-hidden'), 'modal is not hidden after opening');
});
-q.test('open() cannot be called on an opened modal', function(assert) {
- var spy = sinon.spy();
+QUnit.test('open() cannot be called on an opened modal', function(assert) {
+ const spy = sinon.spy();
this.modal.on('modalopen', spy).open().open();
@@ -132,13 +133,13 @@ q.test('open() cannot be called on an opened modal', function(assert) {
assert.strictEqual(spy.callCount, 1, 'modal was only opened once');
});
-q.test('close() triggers events', function(assert) {
- var modal = this.modal;
- var beforeModalCloseSpy = sinon.spy(function() {
+QUnit.test('close() triggers events', function(assert) {
+ const modal = this.modal;
+ const beforeModalCloseSpy = sinon.spy(function() {
assert.ok(modal.opened(), 'modal is not closed before closing event');
});
- var modalCloseSpy = sinon.spy(function() {
+ const modalCloseSpy = sinon.spy(function() {
assert.notOk(modal.opened(), 'modal is closed on closing event');
});
@@ -154,14 +155,14 @@ q.test('close() triggers events', function(assert) {
assert.strictEqual(modalCloseSpy.callCount, 1, 'modalclose spy was called');
});
-q.test('close() adds the "vjs-hidden" class', function(assert) {
+QUnit.test('close() adds the "vjs-hidden" class', function(assert) {
assert.expect(1);
this.modal.open().close();
assert.ok(this.modal.hasClass('vjs-hidden'), 'modal is hidden upon close');
});
-q.test('pressing ESC triggers close(), but only when the modal is opened', function(assert) {
- var spy = sinon.spy();
+QUnit.test('pressing ESC triggers close(), but only when the modal is opened', function(assert) {
+ const spy = sinon.spy();
this.modal.on('modalclose', spy).handleKeyPress({which: ESC});
assert.expect(2);
@@ -171,8 +172,8 @@ q.test('pressing ESC triggers close(), but only when the modal is opened', funct
assert.strictEqual(spy.callCount, 1, 'ESC closed the now-opened modal');
});
-q.test('close() cannot be called on a closed modal', function(assert) {
- var spy = sinon.spy();
+QUnit.test('close() cannot be called on a closed modal', function(assert) {
+ const spy = sinon.spy();
this.modal.on('modalclose', spy);
this.modal.open().close().close();
@@ -181,9 +182,9 @@ q.test('close() cannot be called on a closed modal', function(assert) {
assert.strictEqual(spy.callCount, 1, 'modal was only closed once');
});
-q.test('open() pauses playback, close() resumes', function(assert) {
- var playSpy = sinon.spy();
- var pauseSpy = sinon.spy();
+QUnit.test('open() pauses playback, close() resumes', function(assert) {
+ const playSpy = sinon.spy();
+ const pauseSpy = sinon.spy();
// Quick and dirty; make it looks like the player is playing.
this.player.paused = function() {
@@ -207,7 +208,7 @@ q.test('open() pauses playback, close() resumes', function(assert) {
assert.strictEqual(playSpy.callCount, 1, 'player is resumed when the modal closes');
});
-q.test('open() hides controls, close() shows controls', function(assert) {
+QUnit.test('open() hides controls, close() shows controls', function(assert) {
this.modal.open();
assert.expect(2);
@@ -217,9 +218,9 @@ q.test('open() hides controls, close() shows controls', function(assert) {
assert.ok(this.player.controls_, 'controls are no longer hidden');
});
-q.test('opened()', function(assert) {
- var openSpy = sinon.spy();
- var closeSpy = sinon.spy();
+QUnit.test('opened()', function(assert) {
+ const openSpy = sinon.spy();
+ const closeSpy = sinon.spy();
assert.expect(4);
assert.strictEqual(this.modal.opened(), false, 'the modal is closed');
@@ -238,23 +239,22 @@ q.test('opened()', function(assert) {
assert.strictEqual(closeSpy.callCount, 1, 'modal was closed only once');
});
-q.test('content()', function(assert) {
- var content;
-
+QUnit.test('content()', function(assert) {
assert.expect(3);
assert.strictEqual(typeof this.modal.content(), 'undefined', 'no content by default');
- content = this.modal.content(Dom.createEl());
+ const content = this.modal.content(Dom.createEl());
+
assert.ok(Dom.isEl(content), 'content was set from a single DOM element');
assert.strictEqual(this.modal.content(null), null, 'content was nullified');
});
-q.test('fillWith()', function(assert) {
- var contentEl = this.modal.contentEl();
- var children = [Dom.createEl(), Dom.createEl(), Dom.createEl()];
- var beforeFillSpy = sinon.spy();
- var fillSpy = sinon.spy();
+QUnit.test('fillWith()', function(assert) {
+ const contentEl = this.modal.contentEl();
+ const children = [Dom.createEl(), Dom.createEl(), Dom.createEl()];
+ const beforeFillSpy = sinon.spy();
+ const fillSpy = sinon.spy();
children.forEach(function(el) {
contentEl.appendChild(el);
@@ -278,9 +278,9 @@ q.test('fillWith()', function(assert) {
assert.strictEqual(fillSpy.getCall(0).thisValue, this.modal, 'the value of "this" is the modal');
});
-q.test('empty()', function(assert) {
- var beforeEmptySpy = sinon.spy();
- var emptySpy = sinon.spy();
+QUnit.test('empty()', function(assert) {
+ const beforeEmptySpy = sinon.spy();
+ const emptySpy = sinon.spy();
this.modal.
fillWith([Dom.createEl(), Dom.createEl()]).
@@ -296,8 +296,8 @@ q.test('empty()', function(assert) {
assert.strictEqual(emptySpy.getCall(0).thisValue, this.modal, 'the value of "this" is the modal');
});
-q.test('closeable()', function(assert) {
- let initialCloseButton = this.modal.getChild('closeButton');
+QUnit.test('closeable()', function(assert) {
+ const initialCloseButton = this.modal.getChild('closeButton');
assert.expect(8);
assert.strictEqual(this.modal.closeable(), true, 'the modal is closed');
@@ -322,13 +322,13 @@ q.test('closeable()', function(assert) {
assert.notOk(this.modal.opened(), 'the modal was closed by the ESC key');
});
-q.test('"content" option (fills on first open() invocation)', function(assert) {
- var modal = new ModalDialog(this.player, {
+QUnit.test('"content" option (fills on first open() invocation)', function(assert) {
+ const modal = new ModalDialog(this.player, {
content: Dom.createEl(),
temporary: false
});
- var spy = sinon.spy();
+ const spy = sinon.spy();
modal.on('modalfill', spy);
modal.open().close().open();
@@ -339,11 +339,11 @@ q.test('"content" option (fills on first open() invocation)', function(assert) {
assert.strictEqual(modal.contentEl().firstChild, modal.options_.content, 'has the expected content in the DOM');
});
-q.test('"temporary" option', function(assert) {
- var temp = new ModalDialog(this.player, {temporary: true});
- var tempSpy = sinon.spy();
- var perm = new ModalDialog(this.player, {temporary: false});
- var permSpy = sinon.spy();
+QUnit.test('"temporary" option', function(assert) {
+ const temp = new ModalDialog(this.player, {temporary: true});
+ const tempSpy = sinon.spy();
+ const perm = new ModalDialog(this.player, {temporary: false});
+ const permSpy = sinon.spy();
temp.on('dispose', tempSpy);
perm.on('dispose', permSpy);
@@ -355,14 +355,14 @@ q.test('"temporary" option', function(assert) {
assert.strictEqual(permSpy.callCount, 0, 'permanent modals are not disposed');
});
-q.test('"fillAlways" option', function(assert) {
- var modal = new ModalDialog(this.player, {
+QUnit.test('"fillAlways" option', function(assert) {
+ const modal = new ModalDialog(this.player, {
content: 'foo',
fillAlways: true,
temporary: false
});
- var spy = sinon.spy();
+ const spy = sinon.spy();
modal.on('modalfill', spy);
modal.open().close().open();
@@ -371,21 +371,21 @@ q.test('"fillAlways" option', function(assert) {
assert.strictEqual(spy.callCount, 2, 'the modal was filled on each open call');
});
-q.test('"label" option', function(assert) {
- var label = 'foo';
- var modal = new ModalDialog(this.player, {label: label});
+QUnit.test('"label" option', function(assert) {
+ const label = 'foo';
+ const modal = new ModalDialog(this.player, {label});
assert.expect(1);
assert.strictEqual(modal.el().getAttribute('aria-label'), label, 'uses the label as the aria-label');
});
-q.test('"uncloseable" option', function(assert) {
- var modal = new ModalDialog(this.player, {
+QUnit.test('"uncloseable" option', function(assert) {
+ const modal = new ModalDialog(this.player, {
temporary: false,
uncloseable: true
});
- var spy = sinon.spy();
+ const spy = sinon.spy();
modal.on('modalclose', spy);
diff --git a/test/unit/player.test.js b/test/unit/player.test.js
index fb906e6a76..6dc5af6933 100644
--- a/test/unit/player.test.js
+++ b/test/unit/player.test.js
@@ -1,3 +1,4 @@
+/* eslint-env qunit */
import Player from '../../src/js/player.js';
import videojs from '../../src/js/video.js';
import * as Dom from '../../src/js/utils/dom.js';
@@ -7,126 +8,134 @@ import MediaError from '../../src/js/media-error.js';
import Html5 from '../../src/js/tech/html5.js';
import TestHelpers from './test-helpers.js';
import document from 'global/document';
+import sinon from 'sinon';
import window from 'global/window';
import Tech from '../../src/js/tech/tech.js';
import TechFaker from './tech/tech-faker.js';
-q.module('Player', {
- 'setup': function() {
+QUnit.module('Player', {
+ setup() {
this.clock = sinon.useFakeTimers();
},
- 'teardown': function() {
+ teardown() {
this.clock.restore();
}
});
-test('should create player instance that inherits from component and dispose it', function(){
- var player = TestHelpers.makePlayer();
+QUnit.test('should create player instance that inherits from component and dispose it', function() {
+ const player = TestHelpers.makePlayer();
- ok(player.el().nodeName === 'DIV');
- ok(player.on, 'component function exists');
+ QUnit.ok(player.el().nodeName === 'DIV');
+ QUnit.ok(player.on, 'component function exists');
player.dispose();
- ok(player.el() === null, 'element disposed');
+ QUnit.ok(player.el() === null, 'element disposed');
});
-test('dispose should not throw if styleEl is missing', function(){
- var player = TestHelpers.makePlayer();
+QUnit.test('dispose should not throw if styleEl is missing', function() {
+ const player = TestHelpers.makePlayer();
player.styleEl_.parentNode.removeChild(player.styleEl_);
player.dispose();
- ok(player.el() === null, 'element disposed');
+ QUnit.ok(player.el() === null, 'element disposed');
});
// technically, all uses of videojs.options should be replaced with
// Player.prototype.options_ in this file and a equivalent test using
// videojs.options should be made in video.test.js. Keeping this here
// until we make that move.
-test('should accept options from multiple sources and override in correct order', function(){
+QUnit.test('should accept options from multiple sources and override in correct order', function() {
// Set a global option
videojs.options.attr = 1;
- let tag0 = TestHelpers.makeTag();
- let player0 = new Player(tag0, { techOrder: ['techFaker'] });
+ const tag0 = TestHelpers.makeTag();
+ const player0 = new Player(tag0, { techOrder: ['techFaker'] });
- equal(player0.options_.attr, 1, 'global option was set');
+ QUnit.equal(player0.options_.attr, 1, 'global option was set');
player0.dispose();
// Set a tag level option
- let tag2 = TestHelpers.makeTag();
- tag2.setAttribute('attr', 'asdf'); // Attributes must be set as strings
+ const tag2 = TestHelpers.makeTag();
- let player2 = new Player(tag2, { techOrder: ['techFaker'] });
- equal(player2.options_.attr, 'asdf', 'Tag options overrode global options');
+ // Attributes must be set as strings
+ tag2.setAttribute('attr', 'asdf');
+
+ const player2 = new Player(tag2, { techOrder: ['techFaker'] });
+
+ QUnit.equal(player2.options_.attr, 'asdf', 'Tag options overrode global options');
player2.dispose();
// Set a tag level option
- let tag3 = TestHelpers.makeTag();
+ const tag3 = TestHelpers.makeTag();
+
tag3.setAttribute('attr', 'asdf');
- let player3 = new Player(tag3, { techOrder: ['techFaker'], 'attr': 'fdsa' });
- equal(player3.options_.attr, 'fdsa', 'Init options overrode tag and global options');
+ const player3 = new Player(tag3, { techOrder: ['techFaker'], attr: 'fdsa' });
+
+ QUnit.equal(player3.options_.attr, 'fdsa', 'Init options overrode tag and global options');
player3.dispose();
});
-test('should get tag, source, and track settings', function(){
+QUnit.test('should get tag, source, and track settings', function() {
// Partially tested in lib->getElAttributes
- var fixture = document.getElementById('qunit-fixture');
+ const fixture = document.getElementById('qunit-fixture');
- var html = '';
+ let html = '';
fixture.innerHTML += html;
- var tag = document.getElementById('example_1');
- var player = TestHelpers.makePlayer({}, tag);
+ const tag = document.getElementById('example_1');
+ const player = TestHelpers.makePlayer({}, tag);
- equal(player.options_.autoplay, true, 'autoplay is set to true');
- equal(player.options_.preload, 'none', 'preload is set to none');
- equal(player.options_.id, 'example_1', 'id is set to example_1');
- equal(player.options_.sources.length, 2, 'we have two sources');
- equal(player.options_.sources[0].src, 'http://google.com', 'first source is google.com');
- equal(player.options_.sources[0].type, 'video/mp4', 'first time is video/mp4');
- equal(player.options_.sources[1].type, 'video/webm', 'second type is video/webm');
- equal(player.options_.tracks.length, 1, 'we have one text track');
- equal(player.options_.tracks[0].kind, 'captions', 'the text track is a captions file');
- equal(player.options_.tracks[0].attrtest, '', 'we have an empty attribute called attrtest');
+ QUnit.equal(player.options_.autoplay, true, 'autoplay is set to true');
+ QUnit.equal(player.options_.preload, 'none', 'preload is set to none');
+ QUnit.equal(player.options_.id, 'example_1', 'id is set to example_1');
+ QUnit.equal(player.options_.sources.length, 2, 'we have two sources');
+ QUnit.equal(player.options_.sources[0].src, 'http://google.com', 'first source is google.com');
+ QUnit.equal(player.options_.sources[0].type, 'video/mp4', 'first time is video/mp4');
+ QUnit.equal(player.options_.sources[1].type, 'video/webm', 'second type is video/webm');
+ QUnit.equal(player.options_.tracks.length, 1, 'we have one text track');
+ QUnit.equal(player.options_.tracks[0].kind, 'captions', 'the text track is a captions file');
+ QUnit.equal(player.options_.tracks[0].attrtest, '', 'we have an empty attribute called attrtest');
- notEqual(player.el().className.indexOf('video-js'), -1, 'transferred class from tag to player div');
- equal(player.el().id,'example_1', 'transferred id from tag to player div');
+ QUnit.notEqual(player.el().className.indexOf('video-js'), -1, 'transferred class from tag to player div');
+ QUnit.equal(player.el().id, 'example_1', 'transferred id from tag to player div');
- equal(Player.players[player.id()], player, 'player referenceable from global list');
- notEqual(tag.id, player.id, 'tag ID no longer is the same as player ID');
- notEqual(tag.className, player.el().className, 'tag classname updated');
+ QUnit.equal(Player.players[player.id()], player, 'player referenceable from global list');
+ QUnit.notEqual(tag.id, player.id, 'tag ID no longer is the same as player ID');
+ QUnit.notEqual(tag.className, player.el().className, 'tag classname updated');
player.dispose();
- notEqual(tag['player'], player, 'tag player ref killed');
- ok(!Player.players['example_1'], 'global player ref killed');
- equal(player.el(), null, 'player el killed');
+ QUnit.notEqual(tag.player, player, 'tag player ref killed');
+ QUnit.ok(!Player.players.example_1, 'global player ref killed');
+ QUnit.equal(player.el(), null, 'player el killed');
});
-test('should asynchronously fire error events during source selection', function() {
- expect(2);
+QUnit.test('should asynchronously fire error events during source selection', function() {
+ QUnit.expect(2);
sinon.stub(log, 'error');
- var player = TestHelpers.makePlayer({
- 'techOrder': ['foo'],
- 'sources': [
- { 'src': 'http://vjs.zencdn.net/v/oceans.mp4', 'type': 'video/mp4' }
+ const player = TestHelpers.makePlayer({
+ techOrder: ['foo'],
+ sources: [
+ { src: 'http://vjs.zencdn.net/v/oceans.mp4', type: 'video/mp4' }
]
});
- ok(player.options_['techOrder'][0] === 'foo', 'Foo listed as the only tech');
+
+ QUnit.ok(player.options_.techOrder[0] === 'foo', 'Foo listed as the only tech');
player.on('error', function(e) {
- ok(player.error().code === 4, 'Source could not be played error thrown');
+ QUnit.ok(player.error().code === 4, 'Source could not be played error thrown');
});
this.clock.tick(1);
@@ -135,17 +144,17 @@ test('should asynchronously fire error events during source selection', function
log.error.restore();
});
-test('should set the width, height, and aspect ratio via a css class', function(){
- let player = TestHelpers.makePlayer();
- let getStyleText = function(styleEl){
+QUnit.test('should set the width, height, and aspect ratio via a css class', function() {
+ const player = TestHelpers.makePlayer();
+ const getStyleText = function(styleEl) {
return (styleEl.styleSheet && styleEl.styleSheet.cssText) || styleEl.innerHTML;
};
// NOTE: was using npm/css to parse the actual CSS ast
// but the css module doesn't support ie8
- let confirmSetting = function(prop, val) {
+ const confirmSetting = function(prop, val) {
let styleText = getStyleText(player.styleEl_);
- let re = new RegExp(prop+':\\s?'+val);
+ const re = new RegExp(prop + ':\\s?' + val);
// Lowercase string for IE8
styleText = styleText.toLowerCase();
@@ -154,86 +163,87 @@ test('should set the width, height, and aspect ratio via a css class', function(
};
// Initial state
- ok(!getStyleText(player.styleEl_), 'style element should be empty when the player is given no dimensions');
+ QUnit.ok(!getStyleText(player.styleEl_), 'style element should be empty when the player is given no dimensions');
// Set only the width
player.width(100);
- ok(confirmSetting('width', '100px'), 'style width should equal the supplied width in pixels');
- ok(confirmSetting('height', '56.25px'), 'style height should match the default aspect ratio of the width');
+ QUnit.ok(confirmSetting('width', '100px'), 'style width should equal the supplied width in pixels');
+ QUnit.ok(confirmSetting('height', '56.25px'), 'style height should match the default aspect ratio of the width');
// Set the height
player.height(200);
- ok(confirmSetting('height', '200px'), 'style height should match the supplied height in pixels');
+ QUnit.ok(confirmSetting('height', '200px'), 'style height should match the supplied height in pixels');
// Reset the width and height to defaults
player.width('');
player.height('');
- ok(confirmSetting('width', '300px'), 'supplying an empty string should reset the width');
- ok(confirmSetting('height', '168.75px'), 'supplying an empty string should reset the height');
+ QUnit.ok(confirmSetting('width', '300px'), 'supplying an empty string should reset the width');
+ QUnit.ok(confirmSetting('height', '168.75px'), 'supplying an empty string should reset the height');
// Switch to fluid mode
player.fluid(true);
- ok(player.hasClass('vjs-fluid'), 'the vjs-fluid class should be added to the player');
- ok(confirmSetting('padding-top', '56.25%'), 'fluid aspect ratio should match the default aspect ratio');
+ QUnit.ok(player.hasClass('vjs-fluid'), 'the vjs-fluid class should be added to the player');
+ QUnit.ok(confirmSetting('padding-top', '56.25%'), 'fluid aspect ratio should match the default aspect ratio');
// Change the aspect ratio
player.aspectRatio('4:1');
- ok(confirmSetting('padding-top', '25%'), 'aspect ratio percent should match the newly set aspect ratio');
+ QUnit.ok(confirmSetting('padding-top', '25%'), 'aspect ratio percent should match the newly set aspect ratio');
});
-test('should use an class name that begins with an alpha character', function(){
- let alphaPlayer = TestHelpers.makePlayer({ id: 'alpha1' });
- let numericPlayer = TestHelpers.makePlayer({ id: '1numeric' });
+QUnit.test('should use an class name that begins with an alpha character', function() {
+ const alphaPlayer = TestHelpers.makePlayer({ id: 'alpha1' });
+ const numericPlayer = TestHelpers.makePlayer({ id: '1numeric' });
- let getStyleText = function(styleEl){
+ const getStyleText = function(styleEl) {
return (styleEl.styleSheet && styleEl.styleSheet.cssText) || styleEl.innerHTML;
};
alphaPlayer.width(100);
numericPlayer.width(100);
- ok(/\s*\.alpha1-dimensions\s*\{/.test(getStyleText(alphaPlayer.styleEl_)), 'appends -dimensions to an alpha player ID');
- ok(/\s*\.dimensions-1numeric\s*\{/.test(getStyleText(numericPlayer.styleEl_)), 'prepends dimensions- to a numeric player ID');
+ QUnit.ok(/\s*\.alpha1-dimensions\s*\{/.test(getStyleText(alphaPlayer.styleEl_)), 'appends -dimensions to an alpha player ID');
+ QUnit.ok(/\s*\.dimensions-1numeric\s*\{/.test(getStyleText(numericPlayer.styleEl_)), 'prepends dimensions- to a numeric player ID');
});
-test('should wrap the original tag in the player div', function(){
- var tag = TestHelpers.makeTag();
- var container = document.createElement('div');
- var fixture = document.getElementById('qunit-fixture');
+QUnit.test('should wrap the original tag in the player div', function() {
+ const tag = TestHelpers.makeTag();
+ const container = document.createElement('div');
+ const fixture = document.getElementById('qunit-fixture');
container.appendChild(tag);
fixture.appendChild(container);
- var player = new Player(tag, { techOrder: ['techFaker'] });
- var el = player.el();
+ const player = new Player(tag, { techOrder: ['techFaker'] });
+ const el = player.el();
- ok(el.parentNode === container, 'player placed at same level as tag');
+ QUnit.ok(el.parentNode === container, 'player placed at same level as tag');
// Tag may be placed inside the player element or it may be removed from the DOM
- ok(tag.parentNode !== container, 'tag removed from original place');
+ QUnit.ok(tag.parentNode !== container, 'tag removed from original place');
player.dispose();
});
-test('should set and update the poster value', function(){
- var tag, poster, updatedPoster, player;
+QUnit.test('should set and update the poster value', function() {
+ const poster = '#';
+ const updatedPoster = 'http://example.com/updated-poster.jpg';
- poster = '#';
- updatedPoster = 'http://example.com/updated-poster.jpg';
+ const tag = TestHelpers.makeTag();
- tag = TestHelpers.makeTag();
tag.setAttribute('poster', poster);
- player = TestHelpers.makePlayer({}, tag);
- equal(player.poster(), poster, 'the poster property should equal the tag attribute');
+ const player = TestHelpers.makePlayer({}, tag);
+
+ QUnit.equal(player.poster(), poster, 'the poster property should equal the tag attribute');
- var pcEmitted = false;
- player.on('posterchange', function(){
+ let pcEmitted = false;
+
+ player.on('posterchange', function() {
pcEmitted = true;
});
player.poster(updatedPoster);
- ok(pcEmitted, 'posterchange event was emitted');
- equal(player.poster(), updatedPoster, 'the updated poster is returned');
+ QUnit.ok(pcEmitted, 'posterchange event was emitted');
+ QUnit.equal(player.poster(), updatedPoster, 'the updated poster is returned');
player.dispose();
});
@@ -241,26 +251,24 @@ test('should set and update the poster value', function(){
// hasStarted() is equivalent to the "show poster flag" in the
// standard, for the purpose of displaying the poster image
// https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play
-test('should hide the poster when play is called', function() {
- var player = TestHelpers.makePlayer({
+QUnit.test('should hide the poster when play is called', function() {
+ const player = TestHelpers.makePlayer({
poster: 'https://example.com/poster.jpg'
});
- equal(player.hasStarted(), false, 'the show poster flag is true before play');
+ QUnit.equal(player.hasStarted(), false, 'the show poster flag is true before play');
player.tech_.trigger('play');
- equal(player.hasStarted(), true, 'the show poster flag is false after play');
+ QUnit.equal(player.hasStarted(), true, 'the show poster flag is false after play');
player.tech_.trigger('loadstart');
- equal(player.hasStarted(),
- false,
- 'the resource selection algorithm sets the show poster flag to true');
+ QUnit.equal(player.hasStarted(), false, 'the resource selection algorithm sets the show poster flag to true');
player.tech_.trigger('play');
- equal(player.hasStarted(), true, 'the show poster flag is false after play');
+ QUnit.equal(player.hasStarted(), true, 'the show poster flag is false after play');
});
-test('should load a media controller', function(){
- var player = TestHelpers.makePlayer({
+QUnit.test('should load a media controller', function() {
+ const player = TestHelpers.makePlayer({
preload: 'none',
sources: [
{ src: 'http://google.com', type: 'video/mp4' },
@@ -268,135 +276,133 @@ test('should load a media controller', function(){
]
});
- ok(player.el().children[0].className.indexOf('vjs-tech') !== -1, 'media controller loaded');
+ QUnit.ok(player.el().children[0].className.indexOf('vjs-tech') !== -1, 'media controller loaded');
player.dispose();
});
-test('should be able to initialize player twice on the same tag using string reference', function() {
- var videoTag = TestHelpers.makeTag();
- var id = videoTag.id;
+QUnit.test('should be able to initialize player twice on the same tag using string reference', function() {
+ let videoTag = TestHelpers.makeTag();
+ const id = videoTag.id;
+
+ const fixture = document.getElementById('qunit-fixture');
- var fixture = document.getElementById('qunit-fixture');
fixture.appendChild(videoTag);
- var player = videojs(videoTag.id, { techOrder: ['techFaker'] });
- ok(player, 'player is created');
+ let player = videojs(videoTag.id, { techOrder: ['techFaker'] });
+
+ QUnit.ok(player, 'player is created');
player.dispose();
- ok(!document.getElementById(id), 'element is removed');
+ QUnit.ok(!document.getElementById(id), 'element is removed');
videoTag = TestHelpers.makeTag();
fixture.appendChild(videoTag);
- //here we receive cached version instead of real
+ // here we receive cached version instead of real
player = videojs(videoTag.id, { techOrder: ['techFaker'] });
- //here it triggers error, because player was destroyed already after first dispose
+ // here it triggers error, because player was destroyed already after first dispose
player.dispose();
});
-test('should set controls and trigger events', function() {
- //expect(6);
+QUnit.test('should set controls and trigger events', function() {
+ const player = TestHelpers.makePlayer({ controls: false });
+
+ QUnit.ok(player.controls() === false, 'controls set through options');
+ const hasDisabledClass = player.el().className.indexOf('vjs-controls-disabled');
- var player = TestHelpers.makePlayer({ 'controls': false });
- ok(player.controls() === false, 'controls set through options');
- var hasDisabledClass = player.el().className.indexOf('vjs-controls-disabled');
- ok(hasDisabledClass !== -1, 'Disabled class added to player');
+ QUnit.ok(hasDisabledClass !== -1, 'Disabled class added to player');
player.controls(true);
- ok(player.controls() === true, 'controls updated');
- var hasEnabledClass = player.el().className.indexOf('vjs-controls-enabled');
- ok(hasEnabledClass !== -1, 'Disabled class added to player');
+ QUnit.ok(player.controls() === true, 'controls updated');
+ const hasEnabledClass = player.el().className.indexOf('vjs-controls-enabled');
+
+ QUnit.ok(hasEnabledClass !== -1, 'Disabled class added to player');
- player.on('controlsenabled', function(){
- ok(true, 'enabled fired once');
+ player.on('controlsenabled', function() {
+ QUnit.ok(true, 'enabled fired once');
});
- player.on('controlsdisabled', function(){
- ok(true, 'disabled fired once');
+ player.on('controlsdisabled', function() {
+ QUnit.ok(true, 'disabled fired once');
});
player.controls(false);
- //player.controls(true);
- // Check for unnecessary events
- //player.controls(true);
player.dispose();
});
-test('should toggle user the user state between active and inactive', function(){
- var player = TestHelpers.makePlayer({});
+QUnit.test('should toggle user the user state between active and inactive', function() {
+ const player = TestHelpers.makePlayer({});
- expect(9);
+ QUnit.expect(9);
- ok(player.userActive(), 'User should be active at player init');
+ QUnit.ok(player.userActive(), 'User should be active at player init');
- player.on('userinactive', function(){
- ok(true, 'userinactive event triggered');
+ player.on('userinactive', function() {
+ QUnit.ok(true, 'userinactive event triggered');
});
- player.on('useractive', function(){
- ok(true, 'useractive event triggered');
+ player.on('useractive', function() {
+ QUnit.ok(true, 'useractive event triggered');
});
player.userActive(false);
- ok(player.userActive() === false, 'Player state changed to inactive');
- ok(player.el().className.indexOf('vjs-user-active') === -1, 'Active class removed');
- ok(player.el().className.indexOf('vjs-user-inactive') !== -1, 'Inactive class added');
+ QUnit.ok(player.userActive() === false, 'Player state changed to inactive');
+ QUnit.ok(player.el().className.indexOf('vjs-user-active') === -1, 'Active class removed');
+ QUnit.ok(player.el().className.indexOf('vjs-user-inactive') !== -1, 'Inactive class added');
player.userActive(true);
- ok(player.userActive() === true, 'Player state changed to active');
- ok(player.el().className.indexOf('vjs-user-inactive') === -1, 'Inactive class removed');
- ok(player.el().className.indexOf('vjs-user-active') !== -1, 'Active class added');
+ QUnit.ok(player.userActive() === true, 'Player state changed to active');
+ QUnit.ok(player.el().className.indexOf('vjs-user-inactive') === -1, 'Inactive class removed');
+ QUnit.ok(player.el().className.indexOf('vjs-user-active') !== -1, 'Active class added');
player.dispose();
});
-test('should add a touch-enabled classname when touch is supported', function(){
- var player;
-
- expect(1);
+QUnit.test('should add a touch-enabled classname when touch is supported', function() {
+ QUnit.expect(1);
// Fake touch support. Real touch support isn't needed for this test.
- var origTouch = browser.TOUCH_ENABLED;
- browser.TOUCH_ENABLED = true;
+ const origTouch = browser.TOUCH_ENABLED;
- player = TestHelpers.makePlayer({});
+ browser.TOUCH_ENABLED = true;
- ok(player.el().className.indexOf('vjs-touch-enabled'), 'touch-enabled classname added');
+ const player = TestHelpers.makePlayer({});
+ QUnit.ok(player.el().className.indexOf('vjs-touch-enabled'), 'touch-enabled classname added');
browser.TOUCH_ENABLED = origTouch;
player.dispose();
});
-test('should allow for tracking when native controls are used', function(){
- var player = TestHelpers.makePlayer({});
+QUnit.test('should allow for tracking when native controls are used', function() {
+ const player = TestHelpers.makePlayer({});
- expect(6);
+ QUnit.expect(6);
// Make sure native controls is false before starting test
player.usingNativeControls(false);
- player.on('usingnativecontrols', function(){
- ok(true, 'usingnativecontrols event triggered');
+ player.on('usingnativecontrols', function() {
+ QUnit.ok(true, 'usingnativecontrols event triggered');
});
- player.on('usingcustomcontrols', function(){
- ok(true, 'usingcustomcontrols event triggered');
+ player.on('usingcustomcontrols', function() {
+ QUnit.ok(true, 'usingcustomcontrols event triggered');
});
player.usingNativeControls(true);
- ok(player.usingNativeControls() === true, 'Using native controls is true');
- ok(player.el().className.indexOf('vjs-using-native-controls') !== -1, 'Native controls class added');
+ QUnit.ok(player.usingNativeControls() === true, 'Using native controls is true');
+ QUnit.ok(player.el().className.indexOf('vjs-using-native-controls') !== -1, 'Native controls class added');
player.usingNativeControls(false);
- ok(player.usingNativeControls() === false, 'Using native controls is false');
- ok(player.el().className.indexOf('vjs-using-native-controls') === -1, 'Native controls class removed');
+ QUnit.ok(player.usingNativeControls() === false, 'Using native controls is false');
+ QUnit.ok(player.el().className.indexOf('vjs-using-native-controls') === -1, 'Native controls class removed');
player.dispose();
});
-test('make sure that controls listeners do not get added too many times', function(){
- var player = TestHelpers.makePlayer({});
- var listeners = 0;
+QUnit.test('make sure that controls listeners do not get added too many times', function() {
+ const player = TestHelpers.makePlayer({});
+ let listeners = 0;
player.addTechControlsListeners_ = function() {
listeners++;
@@ -409,76 +415,82 @@ test('make sure that controls listeners do not get added too many times', functi
player.controls(true);
- equal(listeners, 0, 'addTechControlsListeners_ should not have gotten called yet');
+ QUnit.equal(listeners, 0, 'addTechControlsListeners_ should not have gotten called yet');
player.usingNativeControls(false);
player.controls(false);
player.controls(true);
- equal(listeners, 1, 'addTechControlsListeners_ should have gotten called once');
+ QUnit.equal(listeners, 1, 'addTechControlsListeners_ should have gotten called once');
player.dispose();
});
-test('should select the proper tech based on the the sourceOrder option',
- function() {
- let fixture = document.getElementById('qunit-fixture');
- let html =
+QUnit.test('should select the proper tech based on the the sourceOrder option', function() {
+ const fixture = document.getElementById('qunit-fixture');
+ const html =
'';
- // Extend TechFaker to create a tech that plays the only mime-type that TechFaker
- // will not play
- class PlaysUnsupported extends TechFaker {
- constructor(options, handleReady){
- super(options, handleReady);
- }
- // Support ONLY "video/unsupported-format"
- static isSupported() { return true; }
- static canPlayType(type) { return (type === 'video/unsupported-format' ? 'maybe' : ''); }
- static canPlaySource(srcObj) { return srcObj.type === 'video/unsupported-format'; }
+ // Extend TechFaker to create a tech that plays the only mime-type that TechFaker
+ // will not play
+ class PlaysUnsupported extends TechFaker {
+ constructor(options, handleReady) {
+ super(options, handleReady);
+ }
+ // Support ONLY "video/unsupported-format"
+ static isSupported() {
+ return true;
+ }
+ static canPlayType(type) {
+ return (type === 'video/unsupported-format' ? 'maybe' : '');
+ }
+ static canPlaySource(srcObj) {
+ return srcObj.type === 'video/unsupported-format';
}
- Tech.registerTech('PlaysUnsupported', PlaysUnsupported);
+ }
+ Tech.registerTech('PlaysUnsupported', PlaysUnsupported);
- fixture.innerHTML += html;
- let tag = document.getElementById('example_1');
+ fixture.innerHTML += html;
+ let tag = document.getElementById('example_1');
- let player = new Player(tag, { techOrder: ['techFaker', 'playsUnsupported'], sourceOrder: true });
- equal(player.techName_, 'PlaysUnsupported', 'selected the PlaysUnsupported tech when sourceOrder is truthy');
- player.dispose();
+ let player = new Player(tag, { techOrder: ['techFaker', 'playsUnsupported'], sourceOrder: true });
- fixture.innerHTML += html;
- tag = document.getElementById('example_1');
+ QUnit.equal(player.techName_, 'PlaysUnsupported', 'selected the PlaysUnsupported tech when sourceOrder is truthy');
+ player.dispose();
- player = new Player(tag, { techOrder: ['techFaker', 'playsUnsupported']});
- equal(player.techName_, 'TechFaker', 'selected the TechFaker tech when sourceOrder is falsey');
- player.dispose();
+ fixture.innerHTML += html;
+ tag = document.getElementById('example_1');
+
+ player = new Player(tag, { techOrder: ['techFaker', 'playsUnsupported']});
+ QUnit.equal(player.techName_, 'TechFaker', 'selected the TechFaker tech when sourceOrder is falsey');
+ player.dispose();
});
-test('should register players with generated ids', function(){
- var fixture, video, player, id;
- fixture = document.getElementById('qunit-fixture');
+QUnit.test('should register players with generated ids', function() {
+ const fixture = document.getElementById('qunit-fixture');
+
+ const video = document.createElement('video');
- video = document.createElement('video');
video.className = 'vjs-default-skin video-js';
fixture.appendChild(video);
- player = new Player(video, { techOrder: ['techFaker'] });
- id = player.el().id;
+ const player = new Player(video, { techOrder: ['techFaker'] });
+ const id = player.el().id;
- equal(player.el().id, player.id(), 'the player and element ids are equal');
- ok(Player.players[id], 'the generated id is registered');
+ QUnit.equal(player.el().id, player.id(), 'the player and element ids are equal');
+ QUnit.ok(Player.players[id], 'the generated id is registered');
});
-test('should not add multiple first play events despite subsequent loads', function() {
- expect(1);
+QUnit.test('should not add multiple first play events despite subsequent loads', function() {
+ QUnit.expect(1);
- var player = TestHelpers.makePlayer({});
+ const player = TestHelpers.makePlayer({});
- player.on('firstplay', function(){
- ok(true, 'First play should fire once.');
+ player.on('firstplay', function() {
+ QUnit.ok(true, 'First play should fire once.');
});
// Checking to make sure onLoadStart removes first play listener before adding a new one.
@@ -487,211 +499,210 @@ test('should not add multiple first play events despite subsequent loads', funct
player.tech_.trigger('play');
});
-test('should fire firstplay after resetting the player', function() {
- var player = TestHelpers.makePlayer({});
+QUnit.test('should fire firstplay after resetting the player', function() {
+ const player = TestHelpers.makePlayer({});
- var fpFired = false;
- player.on('firstplay', function(){
+ let fpFired = false;
+
+ player.on('firstplay', function() {
fpFired = true;
});
// init firstplay listeners
player.tech_.trigger('loadstart');
player.tech_.trigger('play');
- ok(fpFired, 'First firstplay fired');
+ QUnit.ok(fpFired, 'First firstplay fired');
// reset the player
player.tech_.trigger('loadstart');
fpFired = false;
player.tech_.trigger('play');
- ok(fpFired, 'Second firstplay fired');
+ QUnit.ok(fpFired, 'Second firstplay fired');
// the play event can fire before the loadstart event.
// in that case we still want the firstplay even to fire.
- player.tech_.paused = function(){ return false; };
+ player.tech_.paused = function() {
+ return false;
+ };
fpFired = false;
// reset the player
player.tech_.trigger('loadstart');
// player.tech_.trigger('play');
- ok(fpFired, 'Third firstplay fired');
+ QUnit.ok(fpFired, 'Third firstplay fired');
});
-test('should remove vjs-has-started class', function(){
- expect(3);
+QUnit.test('should remove vjs-has-started class', function() {
+ QUnit.expect(3);
- var player = TestHelpers.makePlayer({});
+ const player = TestHelpers.makePlayer({});
player.tech_.trigger('loadstart');
player.tech_.trigger('play');
- ok(player.el().className.indexOf('vjs-has-started') !== -1, 'vjs-has-started class added');
+ QUnit.ok(player.el().className.indexOf('vjs-has-started') !== -1, 'vjs-has-started class added');
player.tech_.trigger('loadstart');
- ok(player.el().className.indexOf('vjs-has-started') === -1, 'vjs-has-started class removed');
+ QUnit.ok(player.el().className.indexOf('vjs-has-started') === -1, 'vjs-has-started class removed');
player.tech_.trigger('play');
- ok(player.el().className.indexOf('vjs-has-started') !== -1, 'vjs-has-started class added again');
+ QUnit.ok(player.el().className.indexOf('vjs-has-started') !== -1, 'vjs-has-started class added again');
});
-test('should add and remove vjs-ended class', function() {
- expect(4);
+QUnit.test('should add and remove vjs-ended class', function() {
+ QUnit.expect(4);
- var player = TestHelpers.makePlayer({});
+ const player = TestHelpers.makePlayer({});
player.tech_.trigger('loadstart');
player.tech_.trigger('play');
player.tech_.trigger('ended');
- ok(player.el().className.indexOf('vjs-ended') !== -1, 'vjs-ended class added');
+ QUnit.ok(player.el().className.indexOf('vjs-ended') !== -1, 'vjs-ended class added');
player.tech_.trigger('play');
- ok(player.el().className.indexOf('vjs-ended') === -1, 'vjs-ended class removed');
+ QUnit.ok(player.el().className.indexOf('vjs-ended') === -1, 'vjs-ended class removed');
player.tech_.trigger('ended');
- ok(player.el().className.indexOf('vjs-ended') !== -1, 'vjs-ended class re-added');
+ QUnit.ok(player.el().className.indexOf('vjs-ended') !== -1, 'vjs-ended class re-added');
player.tech_.trigger('loadstart');
- ok(player.el().className.indexOf('vjs-ended') === -1, 'vjs-ended class removed');
+ QUnit.ok(player.el().className.indexOf('vjs-ended') === -1, 'vjs-ended class removed');
});
-test('player should handle different error types', function(){
- expect(8);
- var player = TestHelpers.makePlayer({});
- var testMsg = 'test message';
+QUnit.test('player should handle different error types', function() {
+ QUnit.expect(8);
+ const player = TestHelpers.makePlayer({});
+ const testMsg = 'test message';
// prevent error log messages in the console
sinon.stub(log, 'error');
// error code supplied
- function errCode(){
- equal(player.error().code, 1, 'error code is correct');
+ function errCode() {
+ QUnit.equal(player.error().code, 1, 'error code is correct');
}
player.on('error', errCode);
player.error(1);
player.off('error', errCode);
// error instance supplied
- function errInst(){
- equal(player.error().code, 2, 'MediaError code is correct');
- equal(player.error().message, testMsg, 'MediaError message is correct');
+ function errInst() {
+ QUnit.equal(player.error().code, 2, 'MediaError code is correct');
+ QUnit.equal(player.error().message, testMsg, 'MediaError message is correct');
}
player.on('error', errInst);
player.error(new MediaError({ code: 2, message: testMsg }));
player.off('error', errInst);
// error message supplied
- function errMsg(){
- equal(player.error().code, 0, 'error message code is correct');
- equal(player.error().message, testMsg, 'error message is correct');
+ function errMsg() {
+ QUnit.equal(player.error().code, 0, 'error message code is correct');
+ QUnit.equal(player.error().message, testMsg, 'error message is correct');
}
player.on('error', errMsg);
player.error(testMsg);
player.off('error', errMsg);
// error config supplied
- function errConfig(){
- equal(player.error().code, 3, 'error config code is correct');
- equal(player.error().message, testMsg, 'error config message is correct');
+ function errConfig() {
+ QUnit.equal(player.error().code, 3, 'error config code is correct');
+ QUnit.equal(player.error().message, testMsg, 'error config message is correct');
}
player.on('error', errConfig);
player.error({ code: 3, message: testMsg });
player.off('error', errConfig);
// check for vjs-error classname
- ok(player.el().className.indexOf('vjs-error') >= 0, 'player does not have vjs-error classname');
+ QUnit.ok(player.el().className.indexOf('vjs-error') >= 0, 'player does not have vjs-error classname');
// restore error logging
log.error.restore();
});
-test('Data attributes on the video element should persist in the new wrapper element', function() {
- var dataId, tag, player;
+QUnit.test('Data attributes on the video element should persist in the new wrapper element', function() {
+ const dataId = 123;
- dataId = 123;
+ const tag = TestHelpers.makeTag();
- tag = TestHelpers.makeTag();
tag.setAttribute('data-id', dataId);
- player = TestHelpers.makePlayer({}, tag);
+ const player = TestHelpers.makePlayer({}, tag);
- equal(player.el().getAttribute('data-id'), dataId, 'data-id should be available on the new player element after creation');
+ QUnit.equal(player.el().getAttribute('data-id'), dataId, 'data-id should be available on the new player element after creation');
});
-test('should restore attributes from the original video tag when creating a new element', function(){
- var tag, html5Mock, el;
-
+QUnit.test('should restore attributes from the original video tag when creating a new element', function() {
// simulate attributes stored from the original tag
- tag = Dom.createEl('video');
+ const tag = Dom.createEl('video');
+
tag.setAttribute('preload', 'auto');
tag.setAttribute('autoplay', '');
tag.setAttribute('webkit-playsinline', '');
- html5Mock = { options_: { tag: tag } };
+ const html5Mock = { options_: {tag} };
// set options that should override tag attributes
html5Mock.options_.preload = 'none';
// create the element
- el = Html5.prototype.createEl.call(html5Mock);
+ const el = Html5.prototype.createEl.call(html5Mock);
- equal(el.getAttribute('preload'), 'none', 'attribute was successful overridden by an option');
- equal(el.getAttribute('autoplay'), '', 'autoplay attribute was set properly');
- equal(el.getAttribute('webkit-playsinline'), '', 'webkit-playsinline attribute was set properly');
+ QUnit.equal(el.getAttribute('preload'), 'none', 'attribute was successful overridden by an option');
+ QUnit.equal(el.getAttribute('autoplay'), '', 'autoplay attribute was set properly');
+ QUnit.equal(el.getAttribute('webkit-playsinline'), '', 'webkit-playsinline attribute was set properly');
});
-test('should honor default inactivity timeout', function() {
- var player;
- var clock = sinon.useFakeTimers();
+QUnit.test('should honor default inactivity timeout', function() {
+ const clock = sinon.useFakeTimers();
- // default timeout is 2000ms
- player = TestHelpers.makePlayer({});
+ // default timeout is 2000ms
+ const player = TestHelpers.makePlayer({});
- equal(player.userActive(), true, 'User is active on creation');
- clock.tick(1800);
- equal(player.userActive(), true, 'User is still active');
- clock.tick(500);
- equal(player.userActive(), false, 'User is inactive after timeout expired');
+ QUnit.equal(player.userActive(), true, 'User is active on creation');
+ clock.tick(1800);
+ QUnit.equal(player.userActive(), true, 'User is still active');
+ clock.tick(500);
+ QUnit.equal(player.userActive(), false, 'User is inactive after timeout expired');
- clock.restore();
+ clock.restore();
});
-test('should honor configured inactivity timeout', function() {
- var player;
- var clock = sinon.useFakeTimers();
+QUnit.test('should honor configured inactivity timeout', function() {
+ const clock = sinon.useFakeTimers();
- // default timeout is 2000ms, set to shorter 200ms
- player = TestHelpers.makePlayer({
- 'inactivityTimeout': 200
- });
+ // default timeout is 2000ms, set to shorter 200ms
+ const player = TestHelpers.makePlayer({
+ inactivityTimeout: 200
+ });
- equal(player.userActive(), true, 'User is active on creation');
- clock.tick(150);
- equal(player.userActive(), true, 'User is still active');
- clock.tick(350);
- // make sure user is now inactive after 500ms
- equal(player.userActive(), false, 'User is inactive after timeout expired');
+ QUnit.equal(player.userActive(), true, 'User is active on creation');
+ clock.tick(150);
+ QUnit.equal(player.userActive(), true, 'User is still active');
+ clock.tick(350);
+ // make sure user is now inactive after 500ms
+ QUnit.equal(player.userActive(), false, 'User is inactive after timeout expired');
- clock.restore();
+ clock.restore();
});
-test('should honor disabled inactivity timeout', function() {
- var player;
- var clock = sinon.useFakeTimers();
+QUnit.test('should honor disabled inactivity timeout', function() {
+ const clock = sinon.useFakeTimers();
- // default timeout is 2000ms, disable by setting to zero
- player = TestHelpers.makePlayer({
- 'inactivityTimeout': 0
- });
+ // default timeout is 2000ms, disable by setting to zero
+ const player = TestHelpers.makePlayer({
+ inactivityTimeout: 0
+ });
- equal(player.userActive(), true, 'User is active on creation');
- clock.tick(5000);
- equal(player.userActive(), true, 'User is still active');
+ QUnit.equal(player.userActive(), true, 'User is active on creation');
+ clock.tick(5000);
+ QUnit.equal(player.userActive(), true, 'User is still active');
- clock.restore();
+ clock.restore();
});
-test('should clear pending errors on disposal', function() {
- var clock = sinon.useFakeTimers(), player;
+QUnit.test('should clear pending errors on disposal', function() {
+ const clock = sinon.useFakeTimers();
+
+ const player = TestHelpers.makePlayer();
- player = TestHelpers.makePlayer();
player.src({
src: 'http://example.com/movie.unsupported-format',
type: 'video/unsupported-format'
@@ -700,15 +711,16 @@ test('should clear pending errors on disposal', function() {
try {
clock.tick(5000);
} catch (e) {
- return ok(!e, 'threw an error: ' + e.message);
+ return QUnit.ok(!e, 'threw an error: ' + e.message);
}
- ok(true, 'did not throw an error after disposal');
+ QUnit.ok(true, 'did not throw an error after disposal');
});
-test('pause is called when player ended event is fired and player is not paused', function() {
- var video = document.createElement('video'),
- player = TestHelpers.makePlayer({}, video),
- pauses = 0;
+QUnit.test('pause is called when player ended event is fired and player is not paused', function() {
+ const video = document.createElement('video');
+ const player = TestHelpers.makePlayer({}, video);
+ let pauses = 0;
+
player.paused = function() {
return false;
};
@@ -716,13 +728,14 @@ test('pause is called when player ended event is fired and player is not paused'
pauses++;
};
player.tech_.trigger('ended');
- equal(pauses, 1, 'pause was called');
+ QUnit.equal(pauses, 1, 'pause was called');
});
-test('pause is not called if the player is paused and ended is fired', function() {
- var video = document.createElement('video'),
- player = TestHelpers.makePlayer({}, video),
- pauses = 0;
+QUnit.test('pause is not called if the player is paused and ended is fired', function() {
+ const video = document.createElement('video');
+ const player = TestHelpers.makePlayer({}, video);
+ let pauses = 0;
+
player.paused = function() {
return true;
};
@@ -730,64 +743,62 @@ test('pause is not called if the player is paused and ended is fired', function(
pauses++;
};
player.tech_.trigger('ended');
- equal(pauses, 0, 'pause was not called when ended fired');
+ QUnit.equal(pauses, 0, 'pause was not called when ended fired');
});
-test('should add an audio class if an audio el is used', function() {
- var audio = document.createElement('audio'),
- player = TestHelpers.makePlayer({}, audio),
- audioClass = 'vjs-audio';
+QUnit.test('should add an audio class if an audio el is used', function() {
+ const audio = document.createElement('audio');
+ const player = TestHelpers.makePlayer({}, audio);
+ const audioClass = 'vjs-audio';
- ok(player.el().className.indexOf(audioClass) !== -1, 'added '+ audioClass +' css class');
+ QUnit.ok(player.el().className.indexOf(audioClass) !== -1, 'added ' + audioClass + ' css class');
});
-test('should add a video player region if a video el is used', function() {
- var video = document.createElement('video'),
- player = TestHelpers.makePlayer({}, video),
- role = 'region',
- label = 'video player';
+QUnit.test('should add a video player region if a video el is used', function() {
+ const video = document.createElement('video');
+ const player = TestHelpers.makePlayer({}, video);
- ok(player.el().getAttribute('role') === 'region', 'region role is present');
- ok(player.el().getAttribute('aria-label') === 'video player', 'video player label present');
+ QUnit.ok(player.el().getAttribute('role') === 'region', 'region role is present');
+ QUnit.ok(player.el().getAttribute('aria-label') === 'video player', 'video player label present');
});
-test('should add an audio player region if an audio el is used', function() {
- var audio = document.createElement('audio'),
- player = TestHelpers.makePlayer({}, audio),
- role = 'region',
- label = 'audio player';
+QUnit.test('should add an audio player region if an audio el is used', function() {
+ const audio = document.createElement('audio');
+ const player = TestHelpers.makePlayer({}, audio);
- ok(player.el().getAttribute('role') === 'region', 'region role is present');
- ok(player.el().getAttribute('aria-label') === 'audio player', 'audio player label present');
+ QUnit.ok(player.el().getAttribute('role') === 'region', 'region role is present');
+ QUnit.ok(player.el().getAttribute('aria-label') === 'audio player', 'audio player label present');
});
-test('should not be scrubbing while not seeking', function(){
- var player = TestHelpers.makePlayer();
- equal(player.scrubbing(), false, 'player is not scrubbing');
- ok(player.el().className.indexOf('scrubbing') === -1, 'scrubbing class is not present');
+QUnit.test('should not be scrubbing while not seeking', function() {
+ const player = TestHelpers.makePlayer();
+
+ QUnit.equal(player.scrubbing(), false, 'player is not scrubbing');
+ QUnit.ok(player.el().className.indexOf('scrubbing') === -1, 'scrubbing class is not present');
player.scrubbing(false);
- equal(player.scrubbing(), false, 'player is not scrubbing');
+ QUnit.equal(player.scrubbing(), false, 'player is not scrubbing');
});
-test('should be scrubbing while seeking', function(){
- var player = TestHelpers.makePlayer();
+QUnit.test('should be scrubbing while seeking', function() {
+ const player = TestHelpers.makePlayer();
+
player.scrubbing(true);
- equal(player.scrubbing(), true, 'player is scrubbing');
- ok(player.el().className.indexOf('scrubbing') !== -1, 'scrubbing class is present');
+ QUnit.equal(player.scrubbing(), true, 'player is scrubbing');
+ QUnit.ok(player.el().className.indexOf('scrubbing') !== -1, 'scrubbing class is present');
});
-test('should throw on startup no techs are specified', function() {
+QUnit.test('should throw on startup no techs are specified', function() {
const techOrder = videojs.options.techOrder;
videojs.options.techOrder = null;
- q.throws(function() {
+ QUnit.throws(function() {
videojs(TestHelpers.makeTag());
}, 'a falsey techOrder should throw');
videojs.options.techOrder = techOrder;
});
-test('should have a sensible toJSON that is equivalent to player.options', function() {
+QUnit.test('should have a sensible toJSON that is equivalent to player.options', function() {
const playerOptions = {
html5: {
nativeTextTracks: false
@@ -796,7 +807,7 @@ test('should have a sensible toJSON that is equivalent to player.options', funct
const player = TestHelpers.makePlayer(playerOptions);
- deepEqual(player.toJSON(), player.options_, 'simple player options toJSON produces output equivalent to player.options_');
+ QUnit.deepEqual(player.toJSON(), player.options_, 'simple player options toJSON produces output equivalent to player.options_');
const playerOptions2 = {
tracks: [{
@@ -812,42 +823,42 @@ test('should have a sensible toJSON that is equivalent to player.options', funct
playerOptions2.tracks[0].player = player2;
const popts = player2.options_;
+
popts.tracks[0].player = undefined;
- deepEqual(player2.toJSON(), popts, 'no circular references');
+ QUnit.deepEqual(player2.toJSON(), popts, 'no circular references');
});
-test('should ignore case in language codes and try primary code', function() {
-expect(3);
+QUnit.test('should ignore case in language codes and try primary code', function() {
+ QUnit.expect(3);
- var player = TestHelpers.makePlayer({
- 'languages': {
+ const player = TestHelpers.makePlayer({
+ languages: {
'en-gb': {
- 'Good': 'Brilliant'
+ Good: 'Brilliant'
},
'EN': {
- 'Good': 'Awesome',
- 'Error': 'Problem'
+ Good: 'Awesome',
+ Error: 'Problem'
}
}
});
player.language('en-gb');
- strictEqual(player.localize('Good'), 'Brilliant', 'Used subcode specific localisation');
- strictEqual(player.localize('Error'), 'Problem', 'Used primary code localisation');
+ QUnit.strictEqual(player.localize('Good'), 'Brilliant', 'Used subcode specific localisation');
+ QUnit.strictEqual(player.localize('Error'), 'Problem', 'Used primary code localisation');
player.language('en-GB');
- strictEqual(player.localize('Good'), 'Brilliant', 'Ignored case');
+ QUnit.strictEqual(player.localize('Good'), 'Brilliant', 'Ignored case');
});
-test('inherits language from parent element', function() {
- var fixture = document.getElementById('qunit-fixture');
- var oldLang = fixture.getAttribute('lang');
- var player;
+QUnit.test('inherits language from parent element', function() {
+ const fixture = document.getElementById('qunit-fixture');
+ const oldLang = fixture.getAttribute('lang');
fixture.setAttribute('lang', 'x-test');
- player = TestHelpers.makePlayer();
+ const player = TestHelpers.makePlayer();
- equal(player.language(), 'x-test', 'player inherits parent element language');
+ QUnit.equal(player.language(), 'x-test', 'player inherits parent element language');
player.dispose();
if (oldLang) {
@@ -857,89 +868,93 @@ test('inherits language from parent element', function() {
}
});
-test('should return correct values for canPlayType', function(){
- var player = TestHelpers.makePlayer();
+QUnit.test('should return correct values for canPlayType', function() {
+ const player = TestHelpers.makePlayer();
- equal(player.canPlayType('video/mp4'), 'maybe', 'player can play mp4 files');
- equal(player.canPlayType('video/unsupported-format'), '', 'player can not play unsupported files');
+ QUnit.equal(player.canPlayType('video/mp4'), 'maybe', 'player can play mp4 files');
+ QUnit.equal(player.canPlayType('video/unsupported-format'), '', 'player can not play unsupported files');
player.dispose();
});
-test('createModal()', function() {
- var player = TestHelpers.makePlayer();
- var modal = player.createModal('foo');
- var spy = sinon.spy();
+QUnit.test('createModal()', function() {
+ const player = TestHelpers.makePlayer();
+ const modal = player.createModal('foo');
+ const spy = sinon.spy();
modal.on('dispose', spy);
- expect(5);
- strictEqual(modal.el().parentNode, player.el(), 'the modal is injected into the player');
- strictEqual(modal.content(), 'foo', 'content is set properly');
- ok(modal.opened(), 'modal is opened by default');
+ QUnit.expect(5);
+ QUnit.strictEqual(modal.el().parentNode, player.el(), 'the modal is injected into the player');
+ QUnit.strictEqual(modal.content(), 'foo', 'content is set properly');
+ QUnit.ok(modal.opened(), 'modal is opened by default');
modal.close();
- ok(spy.called, 'modal was disposed when closed');
- strictEqual(player.children().indexOf(modal), -1, 'modal was removed from player\'s children');
+ QUnit.ok(spy.called, 'modal was disposed when closed');
+ QUnit.strictEqual(player.children().indexOf(modal), -1, 'modal was removed from player\'s children');
});
-test('createModal() options object', function() {
- var player = TestHelpers.makePlayer();
- var modal = player.createModal('foo', {content: 'bar', label: 'boo'});
+QUnit.test('createModal() options object', function() {
+ const player = TestHelpers.makePlayer();
+ const modal = player.createModal('foo', {content: 'bar', label: 'boo'});
- expect(2);
- strictEqual(modal.content(), 'foo', 'content argument takes precedence');
- strictEqual(modal.options_.label, 'boo', 'modal options are set properly');
+ QUnit.expect(2);
+ QUnit.strictEqual(modal.content(), 'foo', 'content argument takes precedence');
+ QUnit.strictEqual(modal.options_.label, 'boo', 'modal options are set properly');
modal.close();
});
-test('you can clear error in the error event', function() {
- let player = TestHelpers.makePlayer();
+QUnit.test('you can clear error in the error event', function() {
+ const player = TestHelpers.makePlayer();
sinon.stub(log, 'error');
player.error({code: 4});
- ok(player.error(), 'we have an error');
+ QUnit.ok(player.error(), 'we have an error');
player.error(null);
player.one('error', function() {
player.error(null);
});
player.error({code: 4});
- ok(!player.error(), 'we no longer have an error');
+ QUnit.ok(!player.error(), 'we no longer have an error');
log.error.restore();
});
-test('Player#tech will return tech given the appropriate input', function() {
- let tech_ = {};
- let returnedTech = Player.prototype.tech.call({tech_}, {IWillNotUseThisInPlugins: true});
+QUnit.test('Player#tech will return tech given the appropriate input', function() {
+ const tech_ = {};
+ const returnedTech = Player.prototype.tech.call({tech_}, {IWillNotUseThisInPlugins: true});
- equal(returnedTech, tech_, 'We got back the tech we wanted');
+ QUnit.equal(returnedTech, tech_, 'We got back the tech we wanted');
});
-test('Player#tech alerts and throws without the appropriate input', function() {
+QUnit.test('Player#tech alerts and throws without the appropriate input', function() {
let alertCalled;
- let oldAlert = window.alert;
- window.alert = () => alertCalled = true;
+ const oldAlert = window.alert;
+
+ window.alert = () => {
+ alertCalled = true;
+ };
+
+ const tech_ = {};
- let tech_ = {};
throws(function() {
Player.prototype.tech.call({tech_});
}, new RegExp('https://github.com/videojs/video.js/issues/2617'),
'we threw an error');
- ok(alertCalled, 'we called an alert');
+ QUnit.ok(alertCalled, 'we called an alert');
window.alert = oldAlert;
});
-test('player#reset loads the Html5 tech and then techCalls reset', function() {
+QUnit.test('player#reset loads the Html5 tech and then techCalls reset', function() {
let loadedTech;
let loadedSource;
let techCallMethod;
- let testPlayer = {
+ const testPlayer = {
options_: {
- techOrder: ['html5', 'flash'],
+ techOrder: ['html5', 'flash']
},
loadTech_(tech, source) {
loadedTech = tech;
@@ -952,19 +967,19 @@ test('player#reset loads the Html5 tech and then techCalls reset', function() {
Player.prototype.reset.call(testPlayer);
- equal(loadedTech, 'Html5', 'we loaded the html5 tech');
- equal(loadedSource, null, 'with a null source');
- equal(techCallMethod, 'reset', 'we then reset the tech');
+ QUnit.equal(loadedTech, 'Html5', 'we loaded the html5 tech');
+ QUnit.equal(loadedSource, null, 'with a null source');
+ QUnit.equal(techCallMethod, 'reset', 'we then reset the tech');
});
-test('player#reset loads the first item in the techOrder and then techCalls reset', function() {
+QUnit.test('player#reset loads the first item in the techOrder and then techCalls reset', function() {
let loadedTech;
let loadedSource;
let techCallMethod;
- let testPlayer = {
+ const testPlayer = {
options_: {
- techOrder: ['flash', 'html5'],
+ techOrder: ['flash', 'html5']
},
loadTech_(tech, source) {
loadedTech = tech;
@@ -977,70 +992,78 @@ test('player#reset loads the first item in the techOrder and then techCalls rese
Player.prototype.reset.call(testPlayer);
- equal(loadedTech, 'Flash', 'we loaded the Flash tech');
- equal(loadedSource, null, 'with a null source');
- equal(techCallMethod, 'reset', 'we then reset the tech');
+ QUnit.equal(loadedTech, 'Flash', 'we loaded the Flash tech');
+ QUnit.equal(loadedSource, null, 'with a null source');
+ QUnit.equal(techCallMethod, 'reset', 'we then reset the tech');
});
-test('Remove waiting class on timeupdate after tech waiting', function() {
- let player = TestHelpers.makePlayer();
+QUnit.test('Remove waiting class on timeupdate after tech waiting', function() {
+ const player = TestHelpers.makePlayer();
+
player.tech_.trigger('waiting');
- ok(/vjs-waiting/.test(player.el().className), 'vjs-waiting is added to the player el on tech waiting');
+ QUnit.ok(/vjs-waiting/.test(player.el().className), 'vjs-waiting is added to the player el on tech waiting');
player.trigger('timeupdate');
- ok(!/vjs-waiting/.test(player.el().className), 'vjs-waiting is removed from the player el on timeupdate');
+ QUnit.ok(!(/vjs-waiting/).test(player.el().className), 'vjs-waiting is removed from the player el on timeupdate');
});
-test('Make sure that player\'s style el respects VIDEOJS_NO_DYNAMIC_STYLE option', function() {
+QUnit.test('Make sure that player\'s style el respects VIDEOJS_NO_DYNAMIC_STYLE option', function() {
// clear the HEAD before running this test
let styles = document.querySelectorAll('style');
let i = styles.length;
+
while (i--) {
- let style = styles[i];
+ const style = styles[i];
+
style.parentNode.removeChild(style);
}
let tag = TestHelpers.makeTag();
+
tag.id = 'vjs-no-base-theme-tag';
tag.width = 600;
tag.height = 300;
window.VIDEOJS_NO_DYNAMIC_STYLE = true;
- let player = TestHelpers.makePlayer({}, tag);
+ TestHelpers.makePlayer({}, tag);
+
styles = document.querySelectorAll('style');
- equal(styles.length, 0, 'we should not get any style elements included in the DOM');
+ QUnit.equal(styles.length, 0, 'we should not get any style elements included in the DOM');
window.VIDEOJS_NO_DYNAMIC_STYLE = false;
tag = TestHelpers.makeTag();
- player = TestHelpers.makePlayer({}, tag);
+ TestHelpers.makePlayer({}, tag);
styles = document.querySelectorAll('style');
- equal(styles.length, 1, 'we should have one style element in the DOM');
- equal(styles[0].className, 'vjs-styles-dimensions', 'the class name is the one we expected');
+ QUnit.equal(styles.length, 1, 'we should have one style element in the DOM');
+ QUnit.equal(styles[0].className, 'vjs-styles-dimensions', 'the class name is the one we expected');
});
-test('When VIDEOJS_NO_DYNAMIC_STYLE is set, apply sizing directly to the tech el', function() {
+QUnit.test('When VIDEOJS_NO_DYNAMIC_STYLE is set, apply sizing directly to the tech el', function() {
// clear the HEAD before running this test
- let styles = document.querySelectorAll('style');
+ const styles = document.querySelectorAll('style');
let i = styles.length;
+
while (i--) {
- let style = styles[i];
+ const style = styles[i];
+
style.parentNode.removeChild(style);
}
- let tag = TestHelpers.makeTag();
+ const tag = TestHelpers.makeTag();
+
tag.id = 'vjs-no-base-theme-tag';
tag.width = 600;
tag.height = 300;
window.VIDEOJS_NO_DYNAMIC_STYLE = true;
- let player = TestHelpers.makePlayer({}, tag);
+ const player = TestHelpers.makePlayer({}, tag);
player.width(300);
player.height(600);
- equal(player.tech_.el().width, 300, 'the width is equal to 300');
- equal(player.tech_.el().height, 600, 'the height is equal 600');
+ QUnit.equal(player.tech_.el().width, 300, 'the width is equal to 300');
+ QUnit.equal(player.tech_.el().height, 600, 'the height is equal 600');
player.width(600);
player.height(300);
- equal(player.tech_.el().width, 600, 'the width is equal to 600');
- equal(player.tech_.el().height, 300, 'the height is equal 300');
+ QUnit.equal(player.tech_.el().width, 600, 'the width is equal to 600');
+ QUnit.equal(player.tech_.el().height, 300, 'the height is equal 300');
});
diff --git a/test/unit/plugins.test.js b/test/unit/plugins.test.js
index 2e34713ea8..365fabe325 100644
--- a/test/unit/plugins.test.js
+++ b/test/unit/plugins.test.js
@@ -1,27 +1,29 @@
+/* eslint-env qunit */
import {IE_VERSION} from '../../src/js/utils/browser';
import registerPlugin from '../../src/js/plugins.js';
import Player from '../../src/js/player.js';
import TestHelpers from './test-helpers.js';
import window from 'global/window';
+import sinon from 'sinon';
-q.module('Plugins');
+QUnit.module('Plugins');
-test('Plugin should get initialized and receive options', function(){
- expect(2);
+QUnit.test('Plugin should get initialized and receive options', function() {
+ QUnit.expect(2);
- registerPlugin('myPlugin1', function(options){
- ok(true, 'Plugin initialized');
- ok(options['test'], 'Option passed through');
+ registerPlugin('myPlugin1', function(options) {
+ QUnit.ok(true, 'Plugin initialized');
+ QUnit.ok(options.test, 'Option passed through');
});
- registerPlugin('myPlugin2', function(options){
- ok(false, 'Plugin initialized and should not have been');
+ registerPlugin('myPlugin2', function(options) {
+ QUnit.ok(false, 'Plugin initialized and should not have been');
});
- var player = TestHelpers.makePlayer({
- 'plugins': {
- 'myPlugin1': {
- 'test': true
+ const player = TestHelpers.makePlayer({
+ plugins: {
+ myPlugin1: {
+ test: true
}
}
});
@@ -29,121 +31,122 @@ test('Plugin should get initialized and receive options', function(){
player.dispose();
});
-test('Plugin should have the option of being initilized outside of player init', function(){
- expect(3);
+QUnit.test('Plugin should have the option of being initilized outside of player init', function() {
+ QUnit.expect(3);
- registerPlugin('myPlugin3', function(options){
- ok(true, 'Plugin initialized after player init');
- ok(options['test'], 'Option passed through');
+ registerPlugin('myPlugin3', function(options) {
+ QUnit.ok(true, 'Plugin initialized after player init');
+ QUnit.ok(options.test, 'Option passed through');
});
- var player = TestHelpers.makePlayer({});
+ const player = TestHelpers.makePlayer({});
- ok(player['myPlugin3'], 'Plugin has direct access on player instance');
+ QUnit.ok(player.myPlugin3, 'Plugin has direct access on player instance');
- player['myPlugin3']({
- 'test': true
+ player.myPlugin3({
+ test: true
});
player.dispose();
});
-test('Plugin should be able to add a UI component', function(){
- expect(2);
+QUnit.test('Plugin should be able to add a UI component', function() {
+ QUnit.expect(2);
- registerPlugin('myPlugin4', function(options){
- ok((this instanceof Player), 'Plugin executed in player scope by default');
+ registerPlugin('myPlugin4', function(options) {
+ QUnit.ok((this instanceof Player), 'Plugin executed in player scope by default');
this.addChild('component');
});
- var player = TestHelpers.makePlayer({});
- player['myPlugin4']({
- 'test': true
+ const player = TestHelpers.makePlayer({});
+
+ player.myPlugin4({
+ test: true
});
- var comp = player.getChild('component');
- ok(comp, 'Plugin added a component to the player');
+ const comp = player.getChild('component');
+
+ QUnit.ok(comp, 'Plugin added a component to the player');
player.dispose();
});
-test('Plugin should overwrite plugin of same name', function(){
- var v1Called = 0,
- v2Called = 0,
- v3Called = 0;
+QUnit.test('Plugin should overwrite plugin of same name', function() {
+ let v1Called = 0;
+ let v2Called = 0;
+ let v3Called = 0;
// Create initial plugin
- registerPlugin('myPlugin5', function(options){
+ registerPlugin('myPlugin5', function(options) {
v1Called++;
});
- var player = TestHelpers.makePlayer({});
- player['myPlugin5']({});
+ const player = TestHelpers.makePlayer({});
+
+ player.myPlugin5({});
// Overwrite and create new player
- registerPlugin('myPlugin5', function(options){
+ registerPlugin('myPlugin5', function(options) {
v2Called++;
});
- var player2 = TestHelpers.makePlayer({});
- player2['myPlugin5']({});
+ const player2 = TestHelpers.makePlayer({});
+
+ player2.myPlugin5({});
// Overwrite and init new version on existing player
- registerPlugin('myPlugin5', function(options){
+ registerPlugin('myPlugin5', function(options) {
v3Called++;
});
- player2['myPlugin5']({});
+ player2.myPlugin5({});
- var comp = player.getChild('component');
- ok(v1Called === 1, 'First version of plugin called once');
- ok(v2Called === 1, 'Plugin overwritten for new player');
- ok(v3Called === 1, 'Plugin overwritten for existing player');
+ QUnit.ok(v1Called === 1, 'First version of plugin called once');
+ QUnit.ok(v2Called === 1, 'Plugin overwritten for new player');
+ QUnit.ok(v3Called === 1, 'Plugin overwritten for existing player');
player.dispose();
player2.dispose();
});
-
-test('Plugins should get events in registration order', function() {
- var order = [];
- var expectedOrder = [];
- var pluginName = 'orderPlugin';
- var i = 0;
- var name;
- var player = TestHelpers.makePlayer({});
- var plugin = function (name) {
- registerPlugin(name, function (opts) {
- this.on('test', function (event) {
+QUnit.test('Plugins should get events in registration order', function() {
+ const order = [];
+ const expectedOrder = [];
+ const pluginName = 'orderPlugin';
+ const player = TestHelpers.makePlayer({});
+ const plugin = function(name) {
+ registerPlugin(name, function(opts) {
+ this.on('test', function(event) {
order.push(name);
});
});
player[name]({});
};
- for (; i < 3; i++ ) {
- name = pluginName + i;
+ for (let i = 0; i < 3; i++) {
+ const name = pluginName + i;
+
expectedOrder.push(name);
plugin(name);
}
- registerPlugin('testerPlugin', function (opts) {
+ registerPlugin('testerPlugin', function(opts) {
this.trigger('test');
});
- player['testerPlugin']({});
+ player.testerPlugin({});
- deepEqual(order, expectedOrder, 'plugins should receive events in order of initialization');
+ QUnit.deepEqual(order,
+ expectedOrder,
+ 'plugins should receive events in order of initialization');
player.dispose();
});
-test('Plugins should not get events after stopImmediatePropagation is called', function () {
- var order = [];
- var expectedOrder = [];
- var pluginName = 'orderPlugin';
- var i = 0;
- var name;
- var player = TestHelpers.makePlayer({});
- var plugin = function (name) {
- registerPlugin(name, function (opts) {
- this.on('test', function (event) {
+QUnit.test('Plugins should not get events after stopImmediatePropagation is called', function() {
+ const order = [];
+ const expectedOrder = [];
+ const pluginName = 'orderPlugin';
+ const player = TestHelpers.makePlayer({});
+ const plugin = function(name) {
+ registerPlugin(name, function(opts) {
+ this.on('test', function(event) {
order.push(name);
event.stopImmediatePropagation();
});
@@ -151,56 +154,57 @@ test('Plugins should not get events after stopImmediatePropagation is called', f
player[name]({});
};
- for (; i < 3; i++ ) {
- name = pluginName + i;
+ for (let i = 0; i < 3; i++) {
+ const name = pluginName + i;
+
expectedOrder.push(name);
plugin(name);
}
- registerPlugin('testerPlugin', function (opts) {
+ registerPlugin('testerPlugin', function(opts) {
this.trigger('test');
});
- player['testerPlugin']({});
+ player.testerPlugin({});
- deepEqual(order, expectedOrder.slice(0, order.length), 'plugins should receive events in order of initialization, until stopImmediatePropagation');
+ QUnit.deepEqual(order,
+ expectedOrder.slice(0, order.length),
+ 'plugins should receive events in order of ' +
+ 'initialization, until stopImmediatePropagation');
- equal(order.length, 1, 'only one event listener should have triggered');
+ QUnit.equal(order.length, 1, 'only one event listener should have triggered');
player.dispose();
});
-test('Plugin that does not exist logs an error', function() {
+QUnit.test('Plugin that does not exist logs an error', function() {
// stub the global log functions
- var console, log, error, origConsole;
-
- origConsole = window.console;
-
- console = window.console = {
- log: function(){},
- warn: function(){},
- error: function(){}
+ const console = window.console = {
+ log() {},
+ warn() {},
+ error() {}
};
-
- log = sinon.stub(console, 'log');
- error = sinon.stub(console, 'error');
+ const log = sinon.stub(console, 'log');
+ const error = sinon.stub(console, 'error');
+ const origConsole = window.console;
// enable a non-existing plugin
TestHelpers.makePlayer({
plugins: {
- 'nonExistingPlugin': {
- 'foo': 'bar'
+ nonExistingPlugin: {
+ foo: 'bar'
}
}
});
- ok(error.called, 'error was called');
+ QUnit.ok(error.called, 'error was called');
if (IE_VERSION && IE_VERSION < 11) {
- equal(error.firstCall.args[0], 'VIDEOJS: ERROR: Unable to find plugin: nonExistingPlugin');
+ QUnit.equal(error.firstCall.args[0],
+ 'VIDEOJS: ERROR: Unable to find plugin: nonExistingPlugin');
} else {
- equal(error.firstCall.args[2], 'Unable to find plugin:');
- equal(error.firstCall.args[3], 'nonExistingPlugin');
+ QUnit.equal(error.firstCall.args[2], 'Unable to find plugin:');
+ QUnit.equal(error.firstCall.args[3], 'nonExistingPlugin');
}
// tear down logging stubs
diff --git a/test/unit/poster.test.js b/test/unit/poster.test.js
index 7e4217cf49..7470572aee 100644
--- a/test/unit/poster.test.js
+++ b/test/unit/poster.test.js
@@ -1,10 +1,11 @@
+/* eslint-env qunit */
import PosterImage from '../../src/js/poster-image.js';
import * as browser from '../../src/js/utils/browser.js';
import TestHelpers from './test-helpers.js';
import document from 'global/document';
-q.module('PosterImage', {
- 'setup': function(){
+QUnit.module('PosterImage', {
+ setup() {
// Store the original background support so we can test different vals
this.origVal = browser.BACKGROUND_SIZE_SUPPORTED;
this.poster1 = '#poster1';
@@ -13,69 +14,80 @@ q.module('PosterImage', {
// Create a mock player object that responds as a player would
this.mockPlayer = {
poster_: this.poster1,
- poster: function(){
+ poster() {
return this.poster_;
},
handler_: null,
- on: function(type, handler){
+ on(type, handler) {
this.handler_ = handler;
},
- trigger: function(type){
+ trigger(type) {
this.handler_.call();
}
};
},
- 'teardown': function(){
+ teardown() {
browser.BACKGROUND_SIZE_SUPPORTED = this.origVal;
}
});
-test('should create and update a poster image', function(){
+QUnit.test('should create and update a poster image', function() {
browser.BACKGROUND_SIZE_SUPPORTED = true;
- let posterImage = new PosterImage(this.mockPlayer);
+ const posterImage = new PosterImage(this.mockPlayer);
let backgroundImage = posterImage.el().style.backgroundImage;
- notEqual(backgroundImage.indexOf(this.poster1), -1, 'Background image used');
+
+ QUnit.notEqual(backgroundImage.indexOf(this.poster1), -1, 'Background image used');
// Update with a new poster source and check the new value
this.mockPlayer.poster_ = this.poster2;
this.mockPlayer.trigger('posterchange');
backgroundImage = posterImage.el().style.backgroundImage;
- notEqual(backgroundImage.indexOf(this.poster2), -1, 'Background image updated');
+ QUnit.notEqual(backgroundImage.indexOf(this.poster2), -1, 'Background image updated');
});
-test('should create and update a fallback image in older browsers', function(){
+QUnit.test('should create and update a fallback image in older browsers', function() {
browser.BACKGROUND_SIZE_SUPPORTED = false;
- let posterImage = new PosterImage(this.mockPlayer);
- notEqual(posterImage.fallbackImg_.src.indexOf(this.poster1), -1, 'Fallback image created');
+ const posterImage = new PosterImage(this.mockPlayer);
+
+ QUnit.notEqual(posterImage.fallbackImg_.src.indexOf(this.poster1),
+ -1,
+ 'Fallback image created');
// Update with a new poster source and check the new value
this.mockPlayer.poster_ = this.poster2;
this.mockPlayer.trigger('posterchange');
- notEqual(posterImage.fallbackImg_.src.indexOf(this.poster2), -1, 'Fallback image updated');
+ QUnit.notEqual(posterImage.fallbackImg_.src.indexOf(this.poster2),
+ -1,
+ 'Fallback image updated');
});
-test('should remove itself from the document flow when there is no poster', function(){
- let posterImage = new PosterImage(this.mockPlayer);
- equal(posterImage.el().style.display, '', 'Poster image shows by default');
+QUnit.test('should remove itself from the document flow when there is no poster', function() {
+ const posterImage = new PosterImage(this.mockPlayer);
+
+ QUnit.equal(posterImage.el().style.display, '', 'Poster image shows by default');
// Update with an empty string
this.mockPlayer.poster_ = '';
this.mockPlayer.trigger('posterchange');
- equal(posterImage.hasClass('vjs-hidden'), true, 'Poster image hides with an empty source');
+ QUnit.equal(posterImage.hasClass('vjs-hidden'),
+ true,
+ 'Poster image hides with an empty source');
// Updated with a valid source
this.mockPlayer.poster_ = this.poster2;
this.mockPlayer.trigger('posterchange');
- equal(posterImage.hasClass('vjs-hidden'), false, 'Poster image shows again when there is a source');
+ QUnit.equal(posterImage.hasClass('vjs-hidden'),
+ false,
+ 'Poster image shows again when there is a source');
});
-test('should hide the poster in the appropriate player states', function(){
- var posterImage = new PosterImage(this.mockPlayer);
- var playerDiv = document.createElement('div');
- var fixture = document.getElementById('qunit-fixture');
- var el = posterImage.el();
+QUnit.test('should hide the poster in the appropriate player states', function() {
+ const posterImage = new PosterImage(this.mockPlayer);
+ const playerDiv = document.createElement('div');
+ const fixture = document.getElementById('qunit-fixture');
+ const el = posterImage.el();
// Remove the source so when we add to the DOM it doesn't throw an error
// We want to poster to still think it has a real source so it doesn't hide itself
@@ -86,8 +98,12 @@ test('should hide the poster in the appropriate player states', function(){
fixture.appendChild(playerDiv);
playerDiv.className = 'video-js vjs-has-started';
- equal(TestHelpers.getComputedStyle(el, 'display'), 'none', 'The poster hides when the video has started (CSS may not be loaded)');
+ QUnit.equal(TestHelpers.getComputedStyle(el, 'display'),
+ 'none',
+ 'The poster hides when the video has started (CSS may not be loaded)');
playerDiv.className = 'video-js vjs-has-started vjs-audio';
- equal(TestHelpers.getComputedStyle(el, 'display'), 'block', 'The poster continues to show when playing audio');
+ QUnit.equal(TestHelpers.getComputedStyle(el, 'display'),
+ 'block',
+ 'The poster continues to show when playing audio');
});
diff --git a/test/unit/setup.test.js b/test/unit/setup.test.js
index db17db3085..7ea9e359b0 100644
--- a/test/unit/setup.test.js
+++ b/test/unit/setup.test.js
@@ -1,14 +1,17 @@
+/* eslint-env qunit */
import TestHelpers from './test-helpers.js';
-q.module('Setup');
+QUnit.module('Setup');
-test('should set options from data-setup even if autoSetup is not called before initialisation', function(){
- var el = TestHelpers.makeTag();
- el.setAttribute('data-setup', '{"controls": true, "autoplay": false, "preload": "auto"}');
+QUnit.test('should set options from data-setup even if autoSetup is not called before initialisation', function() {
+ const el = TestHelpers.makeTag();
- var player = TestHelpers.makePlayer({}, el);
+ el.setAttribute('data-setup',
+ '{"controls": true, "autoplay": false, "preload": "auto"}');
- ok(player.options_['controls'] === true);
- ok(player.options_['autoplay'] === false);
- ok(player.options_['preload'] === 'auto');
+ const player = TestHelpers.makePlayer({}, el);
+
+ QUnit.ok(player.options_.controls === true);
+ QUnit.ok(player.options_.autoplay === false);
+ QUnit.ok(player.options_.preload === 'auto');
});
diff --git a/test/unit/tech/flash-rtmp.test.js b/test/unit/tech/flash-rtmp.test.js
index a9a7bccd82..0d45ad1d39 100644
--- a/test/unit/tech/flash-rtmp.test.js
+++ b/test/unit/tech/flash-rtmp.test.js
@@ -1,54 +1,58 @@
+/* eslint-env qunit */
import Flash from '../../../src/js/tech/flash.js';
-q.module('Flash RTMP');
+QUnit.module('Flash RTMP');
+
+const streamToPartsAndBack = function(url) {
+ const parts = Flash.streamToParts(url);
-var streamToPartsAndBack = function(url) {
- var parts = Flash.streamToParts(url);
return Flash.streamFromParts(parts.connection, parts.stream);
};
-test('test using both streamToParts and streamFromParts', function() {
- ok('rtmp://myurl.com/&isthis' === streamToPartsAndBack('rtmp://myurl.com/isthis'));
- ok('rtmp://myurl.com/&isthis' === streamToPartsAndBack('rtmp://myurl.com/&isthis'));
- ok('rtmp://myurl.com/isthis/&andthis' === streamToPartsAndBack('rtmp://myurl.com/isthis/andthis'));
+QUnit.test('test using both streamToParts and streamFromParts', function() {
+ QUnit.ok(streamToPartsAndBack('rtmp://myurl.com/isthis') === 'rtmp://myurl.com/&isthis');
+ QUnit.ok(streamToPartsAndBack('rtmp://myurl.com/&isthis') === 'rtmp://myurl.com/&isthis');
+ QUnit.ok(streamToPartsAndBack('rtmp://myurl.com/isthis/andthis') === 'rtmp://myurl.com/isthis/&andthis');
});
-test('test streamToParts', function() {
- var parts = Flash.streamToParts('http://myurl.com/streaming&/is/fun');
- ok(parts.connection === 'http://myurl.com/streaming');
- ok(parts.stream === '/is/fun');
+QUnit.test('test streamToParts', function() {
+ let parts = Flash.streamToParts('http://myurl.com/streaming&/is/fun');
+
+ QUnit.ok(parts.connection === 'http://myurl.com/streaming');
+ QUnit.ok(parts.stream === '/is/fun');
parts = Flash.streamToParts('http://myurl.com/&streaming&/is/fun');
- ok(parts.connection === 'http://myurl.com/');
- ok(parts.stream === 'streaming&/is/fun');
+ QUnit.ok(parts.connection === 'http://myurl.com/');
+ QUnit.ok(parts.stream === 'streaming&/is/fun');
parts = Flash.streamToParts('http://myurl.com/really?streaming=fun&really=fun');
- ok(parts.connection === 'http://myurl.com/');
- ok(parts.stream === 'really?streaming=fun&really=fun');
+ QUnit.ok(parts.connection === 'http://myurl.com/');
+ QUnit.ok(parts.stream === 'really?streaming=fun&really=fun');
parts = Flash.streamToParts('http://myurl.com/streaming/is/fun');
- ok(parts.connection === 'http://myurl.com/streaming/is/');
- ok(parts.stream === 'fun');
+ QUnit.ok(parts.connection === 'http://myurl.com/streaming/is/');
+ QUnit.ok(parts.stream === 'fun');
parts = Flash.streamToParts('whatisgoingonhere');
- ok(parts.connection === 'whatisgoingonhere');
- ok(parts.stream === '');
+ QUnit.ok(parts.connection === 'whatisgoingonhere');
+ QUnit.ok(parts.stream === '');
parts = Flash.streamToParts();
- ok(parts.connection === '');
- ok(parts.stream === '');
+ QUnit.ok(parts.connection === '');
+ QUnit.ok(parts.stream === '');
});
-test('test isStreamingSrc', function() {
- var isStreamingSrc = Flash.isStreamingSrc;
- ok(isStreamingSrc('rtmp://streaming.is/fun'));
- ok(isStreamingSrc('rtmps://streaming.is/fun'));
- ok(isStreamingSrc('rtmpe://streaming.is/fun'));
- ok(isStreamingSrc('rtmpt://streaming.is/fun'));
+QUnit.test('test isStreamingSrc', function() {
+ const isStreamingSrc = Flash.isStreamingSrc;
+
+ QUnit.ok(isStreamingSrc('rtmp://streaming.is/fun'));
+ QUnit.ok(isStreamingSrc('rtmps://streaming.is/fun'));
+ QUnit.ok(isStreamingSrc('rtmpe://streaming.is/fun'));
+ QUnit.ok(isStreamingSrc('rtmpt://streaming.is/fun'));
// test invalid protocols
- ok(!isStreamingSrc('rtmp:streaming.is/fun'));
- ok(!isStreamingSrc('rtmpz://streaming.is/fun'));
- ok(!isStreamingSrc('http://streaming.is/fun'));
- ok(!isStreamingSrc('https://streaming.is/fun'));
- ok(!isStreamingSrc('file://streaming.is/fun'));
+ QUnit.ok(!isStreamingSrc('rtmp:streaming.is/fun'));
+ QUnit.ok(!isStreamingSrc('rtmpz://streaming.is/fun'));
+ QUnit.ok(!isStreamingSrc('http://streaming.is/fun'));
+ QUnit.ok(!isStreamingSrc('https://streaming.is/fun'));
+ QUnit.ok(!isStreamingSrc('file://streaming.is/fun'));
});
diff --git a/test/unit/tech/flash.test.js b/test/unit/tech/flash.test.js
index 229d78911b..1980b5253f 100644
--- a/test/unit/tech/flash.test.js
+++ b/test/unit/tech/flash.test.js
@@ -1,28 +1,38 @@
+/* eslint-env qunit */
import Flash from '../../../src/js/tech/flash.js';
import { createTimeRange } from '../../../src/js/utils/time-ranges.js';
import document from 'global/document';
+import sinon from 'sinon';
-q.module('Flash');
+// fake out the