diff --git a/.jshintrc b/.jshintrc index 363576e988..f1a9157487 100644 --- a/.jshintrc +++ b/.jshintrc @@ -23,8 +23,7 @@ "exports", "process", - "PlayerTest", - "TestHelpers", + "q", "asyncTest", "deepEqual", "equal", diff --git a/Gruntfile.js b/Gruntfile.js index 9f1645942b..1c94222d13 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -94,7 +94,7 @@ module.exports = function(grunt) { es6: ['test/es6.html'] }, watch: { - files: [ 'src/**/*', 'test/unit/*.js', 'Gruntfile.js' ], + files: [ 'src/**/*', 'test/unit/**/*.js', 'Gruntfile.js' ], tasks: 'dev' }, connect: { @@ -445,16 +445,12 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-browserify'); - // grunt.loadTasks('./docs/tasks/'); - // grunt.loadTasks('../videojs-doc-generator/tasks/'); - grunt.registerTask('pretask', ['jshint', 'less', 'vjslanguages', 'build', 'usebanner', 'uglify']); // Default task. grunt.registerTask('default', ['pretask', 'dist']); // Development watch task - grunt.registerTask('dev', ['jshint', 'less', 'vjslanguages', 'build', 'usebanner', 'qunit:source']); + grunt.registerTask('dev', ['jshint', 'less', 'vjslanguages', 'browserify:dist', 'usebanner', 'karma:chrome']); grunt.registerTask('test-qunit', ['pretask', 'qunit']); - grunt.registerTask('test-es6', ['browserify:test', 'qunit:es6']); grunt.registerTask('dist', 'Creating distribution', ['dist-copy', 'zip:dist']); diff --git a/package.json b/package.json index 5543220dad..1163ca9572 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "grunt-contrib-connect": "~0.7.1", "grunt-contrib-copy": "~0.3.2", "grunt-contrib-cssmin": "~0.6.0", - "grunt-contrib-jshint": "~0.11.0", + "grunt-contrib-jshint": "^0.11.0", "grunt-contrib-less": "~0.6.4", "grunt-contrib-qunit": "~0.2.1", "grunt-contrib-uglify": "^0.8.0", diff --git a/src/js/button.js b/src/js/button.js index 2034e6da2c..bf52254449 100644 --- a/src/js/button.js +++ b/src/js/button.js @@ -1,6 +1,6 @@ import Component from './component'; -import * as VjsLib from './lib'; -import * as VjsEvents from './events'; +import * as Lib from './lib'; +import * as Events from './events'; import document from 'global/document'; /* Button - Base class for all buttons @@ -33,7 +33,7 @@ Component.registerComponent('Button', Button); Button.prototype.createEl = function(type, props){ // Add standard Aria and Tabindex info - props = VjsLib.obj.merge({ + props = Lib.obj.merge({ className: this.buildCSSClass(), 'role': 'button', 'aria-live': 'polite', // let the screen reader user know that the text of the button may change @@ -44,11 +44,11 @@ Button.prototype.createEl = function(type, props){ // if innerHTML hasn't been overridden (bigPlayButton), add content elements if (!props.innerHTML) { - this.contentEl_ = VjsLib.createEl('div', { + this.contentEl_ = Lib.createEl('div', { className: 'vjs-control-content' }); - this.controlText_ = VjsLib.createEl('span', { + this.controlText_ = Lib.createEl('span', { className: 'vjs-control-text', innerHTML: this.localize(this.buttonText) || 'Need Text' }); @@ -70,7 +70,7 @@ Button.prototype.onClick = function(){}; // Focus - Add keyboard functionality to element Button.prototype.onFocus = function(){ - VjsEvents.on(document, 'keydown', VjsLib.bind(this, this.onKeyPress)); + Events.on(document, 'keydown', Lib.bind(this, this.onKeyPress)); }; // KeyPress (document level) - Trigger click when keys are pressed @@ -84,7 +84,7 @@ Button.prototype.onKeyPress = function(event){ // Blur - Remove keyboard triggers Button.prototype.onBlur = function(){ - VjsEvents.off(document, 'keydown', VjsLib.bind(this, this.onKeyPress)); + Events.off(document, 'keydown', Lib.bind(this, this.onKeyPress)); }; export default Button; diff --git a/src/js/component.js b/src/js/component.js index b10c5e2d64..0a9ee3d75b 100644 --- a/src/js/component.js +++ b/src/js/component.js @@ -4,9 +4,9 @@ */ import CoreObject from './core-object.js'; -import * as VjsLib from './lib.js'; +import * as Lib from './lib.js'; import * as VjsUtil from './util.js'; -import * as VjsEvents from './events.js'; +import * as Events from './events.js'; import window from 'global/window'; /** @@ -48,7 +48,7 @@ var Component = CoreObject.extend({ this.player_ = player; // Make a copy of prototype.options_ to protect against overriding global defaults - this.options_ = VjsLib.obj.copy(this.options_); + this.options_ = Lib.obj.copy(this.options_); // Updated options with supplied options options = this.options(options); @@ -59,7 +59,7 @@ var Component = CoreObject.extend({ // 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 - this.id_ = ((player.id && player.id()) || 'no_player') + '_component_' + VjsLib.guid++; + this.id_ = ((player.id && player.id()) || 'no_player') + '_component_' + Lib.guid++; } this.name_ = options['name'] || null; @@ -112,7 +112,7 @@ Component.prototype.dispose = function(){ this.el_.parentNode.removeChild(this.el_); } - VjsLib.removeData(this.el_); + Lib.removeData(this.el_); this.el_ = null; }; @@ -204,7 +204,7 @@ Component.prototype.el_; * @return {Element} */ Component.prototype.createEl = function(tagName, attributes){ - return VjsLib.createEl(tagName, attributes); + return Lib.createEl(tagName, attributes); }; Component.prototype.localize = function(string){ @@ -372,11 +372,13 @@ Component.prototype.addChild = function(child, options){ let componentName = child; // Make sure options is at least an empty object to protect against errors - options = options || {}; + if (!options || options === true) { + options = {}; + } // If no componentClass in options, assume componentClass is the name lowercased // (e.g. playButton) - let componentClassName = options['componentClass'] || VjsLib.capitalize(componentName); + let componentClassName = options['componentClass'] || Lib.capitalize(componentName); // Set name through options options['name'] = componentName; @@ -386,6 +388,7 @@ Component.prototype.addChild = function(child, options){ // Closure Compiler throws an 'incomplete alias' warning if we use the vjs variable directly. // Every class should be exported, so this should never be a problem here. let componentClass = Component.getComponent(componentClassName); + component = new componentClass(this.player_ || this, options); // child is a component instance @@ -511,7 +514,7 @@ Component.prototype.initChildren = function(){ }; // Allow for an array of children details to passed in the options - if (VjsLib.obj.isArray(children)) { + if (Lib.obj.isArray(children)) { for (var i = 0; i < children.length; i++) { let child = children[i]; @@ -529,7 +532,7 @@ Component.prototype.initChildren = function(){ handleAdd(name, opts); } } else { - VjsLib.obj.each(children, handleAdd); + Lib.obj.each(children, handleAdd); } } }; @@ -583,14 +586,14 @@ Component.prototype.buildCSSClass = function(){ Component.prototype.on = function(first, second, third){ var target, type, fn, removeOnDispose, cleanRemover, thisComponent; - if (typeof first === 'string' || VjsLib.obj.isArray(first)) { - VjsEvents.on(this.el_, first, VjsLib.bind(this, second)); + if (typeof first === 'string' || Lib.obj.isArray(first)) { + Events.on(this.el_, first, Lib.bind(this, second)); // Targeting another component or element } else { target = first; type = second; - fn = VjsLib.bind(this, third); + fn = Lib.bind(this, third); thisComponent = this; // When this component is disposed, remove the listener from the other component @@ -614,8 +617,8 @@ Component.prototype.on = function(first, second, third){ // Check if this is a DOM node if (first.nodeName) { // Add the listener to the other element - VjsEvents.on(target, type, fn); - VjsEvents.on(target, 'dispose', cleanRemover); + Events.on(target, type, fn); + Events.on(target, 'dispose', cleanRemover); // Should be a component // Not using `instanceof vjs.Component` because it makes mock players difficult @@ -652,13 +655,13 @@ Component.prototype.on = function(first, second, third){ Component.prototype.off = function(first, second, third){ var target, otherComponent, type, fn, otherEl; - if (!first || typeof first === 'string' || VjsLib.obj.isArray(first)) { - VjsEvents.off(this.el_, first, second); + if (!first || typeof first === 'string' || Lib.obj.isArray(first)) { + Events.off(this.el_, first, second); } else { target = first; type = second; // Ensure there's at least a guid, even if the function hasn't been used - fn = VjsLib.bind(this, third); + fn = Lib.bind(this, third); // Remove the dispose listener on this component, // which was given the same guid as the event listener @@ -666,9 +669,9 @@ Component.prototype.off = function(first, second, third){ if (first.nodeName) { // Remove the listener - VjsEvents.off(target, type, fn); + Events.off(target, type, fn); // Remove the listener for cleaning the dispose listener - VjsEvents.off(target, 'dispose', fn); + Events.off(target, 'dispose', fn); } else { target.off(type, fn); target.off('dispose', fn); @@ -697,12 +700,12 @@ Component.prototype.off = function(first, second, third){ Component.prototype.one = function(first, second, third) { var target, type, fn, thisComponent, newFunc; - if (typeof first === 'string' || VjsLib.obj.isArray(first)) { - VjsEvents.one(this.el_, first, VjsLib.bind(this, second)); + if (typeof first === 'string' || Lib.obj.isArray(first)) { + Events.one(this.el_, first, Lib.bind(this, second)); } else { target = first; type = second; - fn = VjsLib.bind(this, third); + fn = Lib.bind(this, third); thisComponent = this; newFunc = function(){ @@ -728,7 +731,7 @@ Component.prototype.one = function(first, second, third) { * @return {vjs.Component} self */ Component.prototype.trigger = function(event){ - VjsEvents.trigger(this.el_, event); + Events.trigger(this.el_, event); return this; }; @@ -820,7 +823,7 @@ Component.prototype.triggerReady = function(){ * @return {vjs.Component} */ Component.prototype.hasClass = function(classToCheck){ - return VjsLib.hasClass(this.el_, classToCheck); + return Lib.hasClass(this.el_, classToCheck); }; /** @@ -830,7 +833,7 @@ Component.prototype.hasClass = function(classToCheck){ * @return {vjs.Component} */ Component.prototype.addClass = function(classToAdd){ - VjsLib.addClass(this.el_, classToAdd); + Lib.addClass(this.el_, classToAdd); return this; }; @@ -841,7 +844,7 @@ Component.prototype.addClass = function(classToAdd){ * @return {vjs.Component} */ Component.prototype.removeClass = function(classToRemove){ - VjsLib.removeClass(this.el_, classToRemove); + Lib.removeClass(this.el_, classToRemove); return this; }; @@ -966,7 +969,8 @@ Component.prototype.dimensions = function(width, height){ */ Component.prototype.dimension = function(widthOrHeight, num, skipListeners){ if (num !== undefined) { - if (num === null || isNaN(num)) { + // Set to zero if null or literally NaN (NaN !== NaN) + if (num === null || num !== num) { num = 0; } @@ -1002,7 +1006,7 @@ Component.prototype.dimension = function(widthOrHeight, num, skipListeners){ // TODO: handle display:none and no dimension style using px } else { - return parseInt(this.el_['offset'+VjsLib.capitalize(widthOrHeight)], 10); + return parseInt(this.el_['offset'+Lib.capitalize(widthOrHeight)], 10); // ComputedStyle version. // Only difference is if the element is hidden it will return @@ -1053,7 +1057,7 @@ Component.prototype.emitTapEvents = function(){ this.on('touchstart', function(event) { // If more than one finger, don't consider treating this as a click if (event.touches.length === 1) { - firstTouch = VjsLib.obj.copy(event.touches[0]); + firstTouch = Lib.obj.copy(event.touches[0]); // Record start time so we can detect a tap vs. "touch and hold" touchStart = new Date().getTime(); // Reset couldBeTap tracking @@ -1136,7 +1140,7 @@ Component.prototype.enableTouchActivity = function() { } // listener for reporting that the user is active - report = VjsLib.bind(this.player(), this.player().reportUserActivity); + report = Lib.bind(this.player(), this.player().reportUserActivity); this.on('touchstart', function() { report(); @@ -1166,7 +1170,7 @@ Component.prototype.enableTouchActivity = function() { * @return {Number} Returns the timeout ID */ Component.prototype.setTimeout = function(fn, timeout) { - fn = VjsLib.bind(this, fn); + fn = Lib.bind(this, fn); // window.setTimeout would be preferable here, but due to some bizarre issue with Sinon and/or Phantomjs, we can't. var timeoutId = setTimeout(fn, timeout); @@ -1206,7 +1210,7 @@ Component.prototype.clearTimeout = function(timeoutId) { * @return {Number} Returns the interval ID */ Component.prototype.setInterval = function(fn, interval) { - fn = VjsLib.bind(this, fn); + fn = Lib.bind(this, fn); var intervalId = setInterval(fn, interval); @@ -1250,9 +1254,10 @@ Component.getComponent = function(name){ } if (window && window.videojs && window.videojs[name]) { - VjsLib.log.warn('The '+name+' component was added to the videojs object when it should be registered using videojs.registerComponent'); + Lib.log.warn('The '+name+' component was added to the videojs object when it should be registered using videojs.registerComponent'); return window.videojs[name]; } }; +Component.registerComponent('Component', Component); export default Component; diff --git a/src/js/control-bar/control-bar.js b/src/js/control-bar/control-bar.js index eb4e225bc6..0ac3ba830b 100644 --- a/src/js/control-bar/control-bar.js +++ b/src/js/control-bar/control-bar.js @@ -1,5 +1,5 @@ import Component from '../component'; -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; import PlayToggle from './play-toggle'; import CurrentTimeDisplay from './time-display'; @@ -7,6 +7,7 @@ import LiveDisplay from './live-display'; import ProgressControl from './progress-control'; import FullscreenToggle from './fullscreen-toggle'; import VolumeControl from './volume-control'; +import VolumeMenuButton from './volume-menu-button'; import MuteToggle from './mute-toggle'; import PlaybackRateMenuButton from './playback-rate-menu-button'; @@ -44,7 +45,7 @@ ControlBar.prototype.options_ = { }; ControlBar.prototype.createEl = function(){ - return VjsLib.createEl('div', { + return Lib.createEl('div', { className: 'vjs-control-bar' }); }; diff --git a/src/js/control-bar/live-display.js b/src/js/control-bar/live-display.js index a62e6adf40..723ab522a8 100644 --- a/src/js/control-bar/live-display.js +++ b/src/js/control-bar/live-display.js @@ -1,5 +1,5 @@ import Component from '../component'; -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; /** * Displays the live indicator @@ -21,7 +21,7 @@ LiveDisplay.prototype.createEl = function(){ className: 'vjs-live-controls vjs-control' }); - this.contentEl_ = VjsLib.createEl('div', { + this.contentEl_ = Lib.createEl('div', { className: 'vjs-live-display', innerHTML: '' + this.localize('Stream Type') + '' + this.localize('LIVE'), 'aria-live': 'off' diff --git a/src/js/control-bar/mute-toggle.js b/src/js/control-bar/mute-toggle.js index 0ce57fd968..0ba52fae37 100644 --- a/src/js/control-bar/mute-toggle.js +++ b/src/js/control-bar/mute-toggle.js @@ -1,6 +1,6 @@ import Button from '../button'; import Component from '../component'; -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; /** * A button component for muting the audio @@ -31,8 +31,6 @@ var MuteToggle = Button.extend({ } }); -Component.registerComponent('MuteToggle', MuteToggle); - MuteToggle.prototype.createEl = function(){ return Button.prototype.createEl.call(this, 'div', { className: 'vjs-mute-control vjs-control', @@ -71,9 +69,10 @@ MuteToggle.prototype.update = function(){ /* TODO improve muted icon classes */ for (var i = 0; i < 4; i++) { - VjsLib.removeClass(this.el_, 'vjs-vol-'+i); + Lib.removeClass(this.el_, 'vjs-vol-'+i); } - VjsLib.addClass(this.el_, 'vjs-vol-'+level); + Lib.addClass(this.el_, 'vjs-vol-'+level); }; +Component.registerComponent('MuteToggle', MuteToggle); export default MuteToggle; diff --git a/src/js/control-bar/play-toggle.js b/src/js/control-bar/play-toggle.js index 1a55b26669..b67036a98e 100644 --- a/src/js/control-bar/play-toggle.js +++ b/src/js/control-bar/play-toggle.js @@ -1,6 +1,6 @@ import Button from '../button'; import Component from '../component'; -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; /** * Button to toggle between play and pause diff --git a/src/js/control-bar/playback-rate-menu-button.js b/src/js/control-bar/playback-rate-menu-button.js index 7920d523a0..2ca3dce12f 100644 --- a/src/js/control-bar/playback-rate-menu-button.js +++ b/src/js/control-bar/playback-rate-menu-button.js @@ -1,6 +1,6 @@ import Component from '../component'; import Menu, { MenuButton, MenuItem } from '../menu'; -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; /** * The component for controlling the playback rate @@ -22,15 +22,13 @@ let PlaybackRateMenuButton = MenuButton.extend({ } }); -Component.registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton); - PlaybackRateMenuButton.prototype.buttonText = 'Playback Rate'; PlaybackRateMenuButton.prototype.className = 'vjs-playback-rate'; PlaybackRateMenuButton.prototype.createEl = function(){ let el = MenuButton.prototype.createEl.call(this); - this.labelEl_ = VjsLib.createEl('div', { + this.labelEl_ = Lib.createEl('div', { className: 'vjs-playback-rate-value', innerHTML: 1.0 }); @@ -109,7 +107,7 @@ PlaybackRateMenuButton.prototype.updateLabel = function(){ * * @constructor */ -let PlaybackRateMenuItem = MenuItem.extend({ +var PlaybackRateMenuItem = MenuItem.extend({ contentElType: 'button', /** @constructor */ init: function(player, options){ @@ -136,5 +134,6 @@ PlaybackRateMenuItem.prototype.update = function(){ this.selected(this.player().playbackRate() == this.rate); }; +Component.registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton); export default PlaybackRateMenuButton; export { PlaybackRateMenuItem }; diff --git a/src/js/control-bar/progress-control.js b/src/js/control-bar/progress-control.js index d471725822..f2afa48145 100644 --- a/src/js/control-bar/progress-control.js +++ b/src/js/control-bar/progress-control.js @@ -1,6 +1,6 @@ import Component from '../component'; import Slider, { SliderHandle } from '../slider'; -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; /** * The Progress Control component contains the seek bar, load progress, @@ -43,7 +43,7 @@ var SeekBar = Slider.extend({ init: function(player, options){ Slider.call(this, player, options); this.on(player, 'timeupdate', this.updateARIAAttributes); - player.ready(VjsLib.bind(this, this.updateARIAAttributes)); + player.ready(Lib.bind(this, this.updateARIAAttributes)); } }); @@ -71,8 +71,8 @@ SeekBar.prototype.createEl = function(){ SeekBar.prototype.updateARIAAttributes = function(){ // Allows for smooth scrubbing, when player can't keep up. let time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime(); - this.el_.setAttribute('aria-valuenow', VjsLib.round(this.getPercent()*100, 2)); // machine readable value of progress bar (percentage complete) - this.el_.setAttribute('aria-valuetext', VjsLib.formatTime(time, this.player_.duration())); // human readable value of progress bar (time complete) + this.el_.setAttribute('aria-valuenow', Lib.round(this.getPercent()*100, 2)); // machine readable value of progress bar (percentage complete) + this.el_.setAttribute('aria-valuetext', Lib.formatTime(time, this.player_.duration())); // human readable value of progress bar (time complete) }; SeekBar.prototype.getPercent = function(){ @@ -163,7 +163,7 @@ LoadProgressBar.prototype.update = function(){ let part = children[i]; if (!part) { - part = this.el_.appendChild(VjsLib.createEl()); + part = this.el_.appendChild(Lib.createEl()); } // set the percent based on the width of the progress bar (bufferedEnd) @@ -184,7 +184,7 @@ LoadProgressBar.prototype.update = function(){ * @param {Object=} options * @constructor */ -let PlayProgressBar = Component.extend({ +var PlayProgressBar = Component.extend({ /** @constructor */ init: function(player, options){ Component.call(this, player, options); @@ -235,7 +235,7 @@ SeekHandle.prototype.createEl = function() { SeekHandle.prototype.updateContent = function() { let time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime(); - this.el_.innerHTML = '' + VjsLib.formatTime(time, this.player_.duration()) + ''; + this.el_.innerHTML = '' + Lib.formatTime(time, this.player_.duration()) + ''; }; export default ProgressControl; diff --git a/src/js/control-bar/time-display.js b/src/js/control-bar/time-display.js index e597c74ae4..297df4202a 100644 --- a/src/js/control-bar/time-display.js +++ b/src/js/control-bar/time-display.js @@ -1,5 +1,5 @@ import Component from '../component'; -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; /** * Displays the current time @@ -23,7 +23,7 @@ CurrentTimeDisplay.prototype.createEl = function(){ className: 'vjs-current-time vjs-time-controls vjs-control' }); - this.contentEl_ = VjsLib.createEl('div', { + this.contentEl_ = Lib.createEl('div', { className: 'vjs-current-time-display', innerHTML: 'Current Time ' + '0:00', // label the current time for screen reader users 'aria-live': 'off' // tell screen readers not to automatically read the time as it changes @@ -36,7 +36,7 @@ CurrentTimeDisplay.prototype.createEl = function(){ CurrentTimeDisplay.prototype.updateContent = function(){ // Allows for smooth scrubbing, when player can't keep up. let time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime(); - this.contentEl_.innerHTML = '' + this.localize('Current Time') + ' ' + VjsLib.formatTime(time, this.player_.duration()); + this.contentEl_.innerHTML = '' + this.localize('Current Time') + ' ' + Lib.formatTime(time, this.player_.duration()); }; /** @@ -45,7 +45,7 @@ CurrentTimeDisplay.prototype.updateContent = function(){ * @param {Object=} options * @constructor */ -let DurationDisplay = Component.extend({ +var DurationDisplay = Component.extend({ /** @constructor */ init: function(player, options){ Component.call(this, player, options); @@ -66,7 +66,7 @@ DurationDisplay.prototype.createEl = function(){ className: 'vjs-duration vjs-time-controls vjs-control' }); - this.contentEl_ = VjsLib.createEl('div', { + this.contentEl_ = Lib.createEl('div', { className: 'vjs-duration-display', innerHTML: '' + this.localize('Duration Time') + ' ' + '0:00', // label the duration time for screen reader users 'aria-live': 'off' // tell screen readers not to automatically read the time as it changes @@ -79,7 +79,7 @@ DurationDisplay.prototype.createEl = function(){ DurationDisplay.prototype.updateContent = function(){ let duration = this.player_.duration(); if (duration) { - this.contentEl_.innerHTML = '' + this.localize('Duration Time') + ' ' + VjsLib.formatTime(duration); // label the duration time for screen reader users + this.contentEl_.innerHTML = '' + this.localize('Duration Time') + ' ' + Lib.formatTime(duration); // label the duration time for screen reader users } }; @@ -92,7 +92,7 @@ DurationDisplay.prototype.updateContent = function(){ * @param {Object=} options * @constructor */ -let TimeDivider = Component.extend({ +var TimeDivider = Component.extend({ /** @constructor */ init: function(player, options){ Component.call(this, player, options); @@ -114,7 +114,7 @@ TimeDivider.prototype.createEl = function(){ * @param {Object=} options * @constructor */ -let RemainingTimeDisplay = Component.extend({ +var RemainingTimeDisplay = Component.extend({ /** @constructor */ init: function(player, options){ Component.call(this, player, options); @@ -130,7 +130,7 @@ RemainingTimeDisplay.prototype.createEl = function(){ className: 'vjs-remaining-time vjs-time-controls vjs-control' }); - this.contentEl_ = VjsLib.createEl('div', { + this.contentEl_ = Lib.createEl('div', { className: 'vjs-remaining-time-display', innerHTML: '' + this.localize('Remaining Time') + ' ' + '-0:00', // label the remaining time for screen reader users 'aria-live': 'off' // tell screen readers not to automatically read the time as it changes @@ -142,7 +142,7 @@ RemainingTimeDisplay.prototype.createEl = function(){ RemainingTimeDisplay.prototype.updateContent = function(){ if (this.player_.duration()) { - this.contentEl_.innerHTML = '' + this.localize('Remaining Time') + ' ' + '-'+ VjsLib.formatTime(this.player_.remainingTime()); + this.contentEl_.innerHTML = '' + this.localize('Remaining Time') + ' ' + '-'+ Lib.formatTime(this.player_.remainingTime()); } // Allows for smooth scrubbing, when player can't keep up. diff --git a/src/js/control-bar/volume-control.js b/src/js/control-bar/volume-control.js index 66923090dc..7950948f31 100644 --- a/src/js/control-bar/volume-control.js +++ b/src/js/control-bar/volume-control.js @@ -1,5 +1,5 @@ import Component from '../component'; -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; import Slider, { SliderHandle } from '../slider'; /** @@ -49,12 +49,12 @@ VolumeControl.prototype.createEl = function(){ * @param {Object=} options * @constructor */ -let VolumeBar = Slider.extend({ +var VolumeBar = Slider.extend({ /** @constructor */ init: function(player, options){ Slider.call(this, player, options); this.on(player, 'volumechange', this.updateARIAAttributes); - player.ready(VjsLib.bind(this, this.updateARIAAttributes)); + player.ready(Lib.bind(this, this.updateARIAAttributes)); } }); @@ -62,8 +62,8 @@ Component.registerComponent('VolumeBar', VolumeBar); VolumeBar.prototype.updateARIAAttributes = function(){ // Current value of volume bar as a percentage - this.el_.setAttribute('aria-valuenow', VjsLib.round(this.player_.volume()*100, 2)); - this.el_.setAttribute('aria-valuetext', VjsLib.round(this.player_.volume()*100, 2)+'%'); + this.el_.setAttribute('aria-valuenow', Lib.round(this.player_.volume()*100, 2)); + this.el_.setAttribute('aria-valuetext', Lib.round(this.player_.volume()*100, 2)+'%'); }; VolumeBar.prototype.options_ = { @@ -115,7 +115,7 @@ VolumeBar.prototype.stepBack = function(){ * @param {Object=} options * @constructor */ -let VolumeLevel = Component.extend({ +var VolumeLevel = Component.extend({ /** @constructor */ init: function(player, options){ Component.call(this, player, options); @@ -138,7 +138,7 @@ VolumeLevel.prototype.createEl = function(){ * @param {Object=} options * @constructor */ -let VolumeHandle = SliderHandle.extend(); +var VolumeHandle = SliderHandle.extend(); Component.registerComponent('VolumeHandle', VolumeHandle); @@ -152,4 +152,4 @@ VolumeHandle.prototype.createEl = function(){ }; export default VolumeControl; -export { VolumeBar, VolumeLevel, VolumeHandle } +export { VolumeBar, VolumeLevel, VolumeHandle }; diff --git a/src/js/control-bar/volume-menu-button.js b/src/js/control-bar/volume-menu-button.js index 85ad3f9ae6..34f078d8cf 100644 --- a/src/js/control-bar/volume-menu-button.js +++ b/src/js/control-bar/volume-menu-button.js @@ -1,8 +1,8 @@ import Button from '../button'; import Component from '../component'; import Menu, { MenuButton } from '../menu'; -import MuteToggle from '../mute-toggle'; -import * as VjsLib from '../lib'; +import MuteToggle from './mute-toggle'; +import * as Lib from '../lib'; import { VolumeBar } from './volume-control'; /** @@ -32,8 +32,6 @@ let VolumeMenuButton = MenuButton.extend({ } }); -Component.registerComponent('VolumeMenuButton', VolumeMenuButton); - VolumeMenuButton.prototype.createMenu = function(){ let menu = new Menu(this.player_, { contentElType: 'div' @@ -63,4 +61,5 @@ VolumeMenuButton.prototype.createEl = function(){ VolumeMenuButton.prototype.volumeUpdate = MuteToggle.prototype.update; +Component.registerComponent('VolumeMenuButton', VolumeMenuButton); export default VolumeMenuButton; diff --git a/src/js/core-object.js b/src/js/core-object.js index c3f701486f..0e942efc1c 100644 --- a/src/js/core-object.js +++ b/src/js/core-object.js @@ -1,4 +1,4 @@ -import * as VjsLib from './lib'; +import * as Lib from './lib'; /** * Core Object/Class for objects that use inheritance + constructors @@ -89,7 +89,7 @@ CoreObject.extend = function(props){ }; // Inherit from this object's prototype - subObj.prototype = VjsLib.obj.create(this.prototype); + subObj.prototype = Lib.obj.create(this.prototype); // Reset the constructor property for subObj otherwise // instances of subObj would have the constructor of the parent Object subObj.prototype.constructor = subObj; @@ -119,7 +119,7 @@ CoreObject.extend = function(props){ */ CoreObject.create = function(){ // Create a new object that inherits from this object's prototype - var inst = VjsLib.obj.create(this.prototype); + var inst = Lib.obj.create(this.prototype); // Apply this constructor function to the new object this.apply(inst, arguments); diff --git a/src/js/core.js b/src/js/core.js index 8a63f322ad..a332c9fe45 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -5,7 +5,7 @@ import Player from './player'; import Plugins from './plugins'; import Options from './options'; -import * as VjsLib from './lib'; +import * as Lib from './lib'; import * as VjsUtil from './util'; import CoreObject from './core-object'; import document from 'global/document'; @@ -43,7 +43,7 @@ var videojs = function(id, options, ready){ // If options or ready funtion are passed, warn if (options) { - VjsLib.log.warn ('Player "' + id + '" is already initialised. Options will not be applied.'); + Lib.log.warn ('Player "' + id + '" is already initialised. Options will not be applied.'); } if (ready) { @@ -54,7 +54,7 @@ var videojs = function(id, options, ready){ // Otherwise get element for ID } else { - tag = VjsLib.el(id); + tag = Lib.el(id); } // ID is a media element diff --git a/src/js/error-display.js b/src/js/error-display.js index 6edc72a933..dc954f8908 100644 --- a/src/js/error-display.js +++ b/src/js/error-display.js @@ -1,5 +1,5 @@ import Component from './component'; -import * as VjsLib from './lib'; +import * as Lib from './lib'; /** * Display that an error has occurred making the video unplayable @@ -23,7 +23,7 @@ ErrorDisplay.prototype.createEl = function(){ className: 'vjs-error-display' }); - this.contentEl_ = VjsLib.createEl('div'); + this.contentEl_ = Lib.createEl('div'); el.appendChild(this.contentEl_); return el; diff --git a/src/js/event-emitter.js b/src/js/event-emitter.js index 1760c1f59d..1a33353a7a 100644 --- a/src/js/event-emitter.js +++ b/src/js/event-emitter.js @@ -1,5 +1,5 @@ -import * as VjsEvents from './events'; -import * as VjsLib from './lib'; +import * as Events from './events'; +import * as Lib from './lib'; var EventEmitter = function() {}; @@ -10,18 +10,18 @@ EventEmitter.prototype.on = function(type, fn) { // so we don't get into an infinite type loop let ael = this.addEventListener; this.addEventListener = Function.prototype; - VjsEvents.on(this, type, fn); + Events.on(this, type, fn); this.addEventListener = ael; }; EventEmitter.prototype.addEventListener = EventEmitter.prototype.on; EventEmitter.prototype.off = function(type, fn) { - VjsEvents.off(this, type, fn); + Events.off(this, type, fn); }; EventEmitter.prototype.removeEventListener = EventEmitter.prototype.off; EventEmitter.prototype.one = function(type, fn) { - VjsEvents.one(this, type, fn); + Events.one(this, type, fn); }; EventEmitter.prototype.trigger = function(event) { @@ -32,13 +32,13 @@ EventEmitter.prototype.trigger = function(event) { type: type }; } - event = VjsEvents.fixEvent(event); + event = Events.fixEvent(event); if (this.allowedEvents_[type] && this['on' + type]) { this['on' + type](event); } - VjsEvents.trigger(this, event); + Events.trigger(this, event); }; // The standard DOM EventTarget.dispatchEvent() is aliased to trigger() EventEmitter.prototype.dispatchEvent = EventEmitter.prototype.trigger; diff --git a/src/js/events.js b/src/js/events.js index 22a69240f7..6d811529cc 100644 --- a/src/js/events.js +++ b/src/js/events.js @@ -5,7 +5,7 @@ * robust as jquery's, so there's probably some differences. */ -import * as VjsLib from './lib'; +import * as Lib from './lib'; import window from 'global/window'; import document from 'global/document'; @@ -15,7 +15,7 @@ import document from 'global/document'; * @return {Object} * @private */ -let fixEvent = function(event) { +var fixEvent = function(event) { function returnTrue() { return true; } function returnFalse() { return false; } @@ -129,19 +129,19 @@ let fixEvent = function(event) { * @param {Function} fn Event listener. * @private */ -let on = function(elem, type, fn){ - if (VjsLib.obj.isArray(type)) { +var on = function(elem, type, fn){ + if (Lib.obj.isArray(type)) { return _handleMultipleEvents(on, elem, type, fn); } - let data = VjsLib.getData(elem); + let data = Lib.getData(elem); // We need a place to store all our handler data if (!data.handlers) data.handlers = {}; if (!data.handlers[type]) data.handlers[type] = []; - if (!fn.guid) fn.guid = VjsLib.guid++; + if (!fn.guid) fn.guid = Lib.guid++; data.handlers[type].push(fn); @@ -186,16 +186,16 @@ let on = function(elem, type, fn){ * @param {Function} fn Specific listener to remove. Don't include to remove listeners for an event type. * @private */ -let off = function(elem, type, fn) { +var off = function(elem, type, fn) { // Don't want to add a cache object through getData if not needed - if (!VjsLib.hasData(elem)) return; + if (!Lib.hasData(elem)) return; - let data = VjsLib.getData(elem); + let data = Lib.getData(elem); // If no events exist, nothing to unbind if (!data.handlers) { return; } - if (VjsLib.obj.isArray(type)) { + if (Lib.obj.isArray(type)) { return _handleMultipleEvents(off, elem, type, fn); } @@ -240,8 +240,8 @@ let off = function(elem, type, fn) { * @param {String} type Type of event to clean up * @private */ -let cleanUpEvents = function(elem, type) { - var data = VjsLib.getData(elem); +var cleanUpEvents = function(elem, type) { + var data = Lib.getData(elem); // Remove the events of a particular type if there are none left if (data.handlers[type].length === 0) { @@ -258,7 +258,7 @@ let cleanUpEvents = function(elem, type) { } // Remove the events object if there are no types left - if (VjsLib.isEmpty(data.handlers)) { + if (Lib.isEmpty(data.handlers)) { delete data.handlers; delete data.dispatcher; delete data.disabled; @@ -269,8 +269,8 @@ let cleanUpEvents = function(elem, type) { } // Finally remove the expando if there is no data left - if (VjsLib.isEmpty(data)) { - VjsLib.removeData(elem); + if (Lib.isEmpty(data)) { + Lib.removeData(elem); } }; @@ -280,11 +280,11 @@ let cleanUpEvents = function(elem, type) { * @param {Event|Object|String} event A string (the type) or an event object with a type attribute * @private */ -let trigger = function(elem, event) { +var trigger = function(elem, event) { // 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 hasData first. - var elemData = (VjsLib.hasData(elem)) ? VjsLib.getData(elem) : {}; + var elemData = (Lib.hasData(elem)) ? Lib.getData(elem) : {}; var parent = elem.parentNode || elem.ownerDocument; // type = event.type || event, // handler; @@ -308,7 +308,7 @@ let trigger = function(elem, event) { // If at the top of the DOM, triggers the default action unless disabled. } else if (!parent && !event.defaultPrevented) { - var targetData = VjsLib.getData(event.target); + var targetData = Lib.getData(event.target); // Checks if the target has a default action for this event. if (event.target[event.type]) { @@ -353,8 +353,8 @@ let trigger = function(elem, event) { * @param {Function} fn * @private */ -let one = function(elem, type, fn) { - if (VjsLib.obj.isArray(type)) { +var one = function(elem, type, fn) { + if (Lib.obj.isArray(type)) { return _handleMultipleEvents(one, elem, type, fn); } var func = function(){ @@ -362,7 +362,7 @@ let one = function(elem, type, fn) { 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 || VjsLib.guid++; + func.guid = fn.guid = fn.guid || Lib.guid++; on(elem, type, func); }; @@ -375,7 +375,7 @@ let one = function(elem, type, fn) { * @private */ function _handleMultipleEvents(fn, elem, type, callback) { - VjsLib.arr.forEach(type, function(type) { + Lib.arr.forEach(type, function(type) { fn(elem, type, callback); //Call the event method for each one of the types }); } diff --git a/src/js/json.js b/src/js/json.js index 09b954e14d..514ebee81d 100644 --- a/src/js/json.js +++ b/src/js/json.js @@ -5,7 +5,8 @@ */ import window from 'global/window'; -let JSON = window.JSON; +// Changing 'JSON' throws jshint errors +var json = window.JSON; /** * Javascript JSON implementation @@ -16,8 +17,8 @@ let JSON = window.JSON; * @namespace * @private */ -if (!(typeof JSON !== 'undefined' && typeof JSON.parse === 'function')) { - JSON = {}; +if (!(typeof json !== 'undefined' && typeof json.parse === 'function')) { + json = {}; var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; @@ -29,7 +30,7 @@ if (!(typeof JSON !== 'undefined' && typeof JSON.parse === 'function')) { * @param {Function=} [reviver] Optional function that can transform the results * @return {Object|Array} The parsed JSON */ - JSON.parse = function (text, reviver) { + json.parse = function (text, reviver) { var j; function walk(holder, key) { @@ -71,4 +72,4 @@ if (!(typeof JSON !== 'undefined' && typeof JSON.parse === 'function')) { }; } -export default JSON; +export default json; diff --git a/src/js/lib.js b/src/js/lib.js index e9808a66bd..13626979a6 100644 --- a/src/js/lib.js +++ b/src/js/lib.js @@ -11,7 +11,7 @@ let hasOwnProp = Object.prototype.hasOwnProperty; * @return {Element} * @private */ -let createEl = function(tagName, properties){ +var createEl = function(tagName, properties){ tagName = tagName || 'div'; properties = properties || {}; @@ -259,7 +259,7 @@ var hasData = function(el){ * @param {Element} el Remove data for an element * @private */ -let removeData = function(el){ +var removeData = function(el){ var id = el[expando]; if (!id) { return; } // Remove all stored data @@ -812,7 +812,7 @@ var findPosition = function(el) { * @type {Object} * @private */ -let arr = {}; +var arr = {}; /* * Loops through an array and runs a function for each item inside it. @@ -823,7 +823,7 @@ let arr = {}; * @private */ arr.forEach = function(array, callback, thisArg) { - thisArg = thisArg || videojs; + thisArg = thisArg || this; if (obj.isArray(array) && callback instanceof Function) { for (var i = 0, len = array.length; i < len; ++i) { diff --git a/src/js/media-error.js b/src/js/media-error.js index 7ba7330a0f..3d1970c0ae 100644 --- a/src/js/media-error.js +++ b/src/js/media-error.js @@ -1,4 +1,4 @@ -import * as VjsLib from './lib'; +import * as Lib from './lib'; /** * Custom MediaError to mimic the HTML5 MediaError @@ -11,7 +11,7 @@ let MediaError = function(code){ // default code is zero, so this is a custom error this.message = code; } else if (typeof code === 'object') { // object - VjsLib.obj.merge(this, code); + Lib.obj.merge(this, code); } if (!this.message) { diff --git a/src/js/media/flash.js b/src/js/media/flash.js index 5e4dcf3567..a5452b4fee 100644 --- a/src/js/media/flash.js +++ b/src/js/media/flash.js @@ -5,10 +5,11 @@ */ import MediaTechController from './media'; -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; import FlashRtmpDecorator from './flash-rtmp'; import Component from '../component'; import window from 'global/window'; +let navigator = window.navigator; /** * Flash Media Controller - Wrapper for fallback SWF API @@ -29,7 +30,7 @@ var Flash = MediaTechController.extend({ let parentEl = options['parentEl']; // Create a temporary element to be replaced by swf object - let placeHolder = this.el_ = VjsLib.createEl('div', { id: player.id() + '_temp_flash' }); + let placeHolder = this.el_ = Lib.createEl('div', { id: player.id() + '_temp_flash' }); // Generate ID for swf object let objId = player.id()+'_flash_api'; @@ -40,7 +41,7 @@ var Flash = MediaTechController.extend({ let playerOptions = player.options_; // Merge default flashvars with ones passed in to init - let flashVars = VjsLib.obj.merge({ + let flashVars = Lib.obj.merge({ // SWF Callback Functions 'readyFunction': 'videojs.Flash.onReady', @@ -56,13 +57,13 @@ var Flash = MediaTechController.extend({ }, options['flashVars']); // Merge default parames with ones passed in - let params = VjsLib.obj.merge({ + let params = Lib.obj.merge({ 'wmode': 'opaque', // Opaque is needed to overlay controls, but can affect playback performance 'bgcolor': '#000000' // Using bgcolor prevents a white flash when the object is loading }, options['params']); // Merge default attributes with ones passed in - let attributes = VjsLib.obj.merge({ + let attributes = Lib.obj.merge({ 'id': objId, 'name': objId, // Both ID and Name needed or swf to identify itself 'class': 'vjs-tech' @@ -76,7 +77,7 @@ var Flash = MediaTechController.extend({ } // Add placeholder to player div - VjsLib.insertFirst(placeHolder, parentEl); + Lib.insertFirst(placeHolder, parentEl); // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers // This allows resetting the playhead when we catch the reload @@ -90,7 +91,7 @@ var Flash = MediaTechController.extend({ // firefox doesn't bubble mousemove events to parent. videojs/video-js-swf#37 // bugzilla bug: https://bugzilla.mozilla.org/show_bug.cgi?id=836786 - if (VjsLib.IS_FIREFOX) { + if (Lib.IS_FIREFOX) { this.ready(function(){ this.on('mousemove', function(){ // since it's a custom event, don't bubble higher than the player @@ -132,7 +133,7 @@ Flash.prototype.src = function(src){ Flash.prototype.setSrc = function(src){ // Make sure source URL is absolute. - src = VjsLib.getAbsoluteURL(src); + src = Lib.getAbsoluteURL(src); this.el_.vjs_src(src); // Currently the SWF doesn't autoplay if you load a source later. @@ -178,7 +179,7 @@ Flash.prototype['setPoster'] = function(){ }; Flash.prototype.buffered = function(){ - return VjsLib.createTimeRange(0, this.el_.vjs_getProperty('buffered')); + return Lib.createTimeRange(0, this.el_.vjs_getProperty('buffered')); }; Flash.prototype.supportsFullScreen = function(){ @@ -289,7 +290,7 @@ Flash.formats = { }; Flash['onReady'] = function(currSwf){ - let el = VjsLib.el(currSwf); + let el = Lib.el(currSwf); // get player from the player div property const player = el && el.parentNode && el.parentNode['player']; @@ -326,13 +327,13 @@ Flash['checkReady'] = function(tech){ // Trigger events from the swf on the player Flash['onEvent'] = function(swfID, eventName){ - let player = VjsLib.el(swfID)['player']; + let player = Lib.el(swfID)['player']; player.trigger(eventName); }; // Log errors from the swf Flash['onError'] = function(swfID, err){ - const player = VjsLib.el(swfID)['player']; + const player = Lib.el(swfID)['player']; const msg = 'FLASH: '+err; if (err == 'srcnotfound') { @@ -368,7 +369,7 @@ Flash.embed = function(swf, placeHolder, flashVars, params, attributes){ const code = Flash.getEmbedCode(swf, flashVars, params, attributes); // Get element by embedding code and retrieving created element - const obj = VjsLib.createEl('div', { innerHTML: code }).childNodes[0]; + const obj = Lib.createEl('div', { innerHTML: code }).childNodes[0]; const par = placeHolder.parentNode; @@ -384,13 +385,13 @@ Flash.getEmbedCode = function(swf, flashVars, params, attributes){ // Convert flash vars to string if (flashVars) { - VjsLib.obj.each(flashVars, function(key, val){ + Lib.obj.each(flashVars, function(key, val){ flashVarsString += (key + '=' + val + '&'); }); } // Add swf, flashVars, and other default params - params = VjsLib.obj.merge({ + params = Lib.obj.merge({ 'movie': swf, 'flashvars': flashVarsString, 'allowScriptAccess': 'always', // Required to talk to swf @@ -398,11 +399,11 @@ Flash.getEmbedCode = function(swf, flashVars, params, attributes){ }, params); // Create param tags string - VjsLib.obj.each(params, function(key, val){ + Lib.obj.each(params, function(key, val){ paramsString += ''; }); - attributes = VjsLib.obj.merge({ + attributes = Lib.obj.merge({ // Add swf to attributes (need both for IE and Others to work) 'data': swf, @@ -413,7 +414,7 @@ Flash.getEmbedCode = function(swf, flashVars, params, attributes){ }, attributes); // Create Attributes string - VjsLib.obj.each(attributes, function(key, val){ + Lib.obj.each(attributes, function(key, val){ attrsString += (key + '="' + val + '" '); }); diff --git a/src/js/media/html5.js b/src/js/media/html5.js index a8da49688d..cac85f390a 100644 --- a/src/js/media/html5.js +++ b/src/js/media/html5.js @@ -4,7 +4,7 @@ import MediaTechController from './media'; import Component from '../component'; -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; import * as VjsUtil from '../util'; import document from 'global/document'; @@ -64,14 +64,14 @@ var Html5 = MediaTechController.extend({ } if (this['featuresNativeTextTracks']) { - this.on('loadstart', VjsLib.bind(this, this.hideCaptions)); + this.on('loadstart', Lib.bind(this, this.hideCaptions)); } // Determine if native controls should be used // Our goal should be to get the custom controls on mobile solid everywhere // so we can remove this all together. Right now this will block custom // controls on touch enabled laptops like the Chrome Pixel - if (VjsLib.TOUCH_ENABLED && player.options()['nativeControlsForTouch'] === true) { + if (Lib.TOUCH_ENABLED && player.options()['nativeControlsForTouch'] === true) { this.useNativeControls(); } @@ -113,16 +113,16 @@ Html5.prototype.createEl = function(){ el = clone; player.tag = null; } else { - el = VjsLib.createEl('video'); + el = Lib.createEl('video'); // determine if native controls should be used let attributes = VjsUtil.mergeOptions({}, player.tagAttributes); - if (!VjsLib.TOUCH_ENABLED || player.options()['nativeControlsForTouch'] !== true) { + if (!Lib.TOUCH_ENABLED || player.options()['nativeControlsForTouch'] !== true) { delete attributes.controls; } - VjsLib.setElementAttributes(el, - VjsLib.obj.merge(attributes, { + Lib.setElementAttributes(el, + Lib.obj.merge(attributes, { id: player.id() + '_html5_api', class: 'vjs-tech' }) @@ -146,7 +146,7 @@ Html5.prototype.createEl = function(){ } } - VjsLib.insertFirst(el, player.el()); + Lib.insertFirst(el, player.el()); } // Update specific tag settings, in case they were overridden @@ -157,7 +157,7 @@ Html5.prototype.createEl = function(){ if (typeof player.options_[attr] !== 'undefined') { overwriteAttrs[attr] = player.options_[attr]; } - VjsLib.setElementAttributes(el, overwriteAttrs); + Lib.setElementAttributes(el, overwriteAttrs); } return el; @@ -247,7 +247,7 @@ Html5.prototype.setCurrentTime = function(seconds){ try { this.el_.currentTime = seconds; } catch(e) { - VjsLib.log(e, 'Video is not ready. (Video.js)'); + Lib.log(e, 'Video is not ready. (Video.js)'); // this.warning(VideoJS.warnings.videoNotReady); } }; @@ -267,7 +267,7 @@ Html5.prototype.supportsFullScreen = function(){ if (typeof this.el_.webkitEnterFullScreen == 'function') { // Seems to be broken in Chromium/Chrome && Safari in Leopard - if (/Android/.test(VjsLib.USER_AGENT) || !/Chrome|Mac OS X 10.5/.test(VjsLib.USER_AGENT)) { + if (/Android/.test(Lib.USER_AGENT) || !/Chrome|Mac OS X 10.5/.test(Lib.USER_AGENT)) { return true; } } @@ -448,12 +448,12 @@ Html5.prototype.removeRemoteTextTrack = function(track) { Html5.isSupported = function(){ // IE9 with no Media Player is a LIAR! (#984) try { - VjsLib.TEST_VID['volume'] = 0.5; + Lib.TEST_VID['volume'] = 0.5; } catch (e) { return false; } - return !!VjsLib.TEST_VID.canPlayType; + return !!Lib.TEST_VID.canPlayType; }; // Add Source Handler pattern functions to this tech @@ -479,7 +479,7 @@ Html5.nativeSourceHandler.canHandleSource = function(source){ // IE9 on Windows 7 without MediaPlayer throws an error here // https://github.com/videojs/video.js/issues/519 try { - return VjsLib.TEST_VID.canPlayType(type); + return Lib.TEST_VID.canPlayType(type); } catch(e) { return ''; } @@ -525,9 +525,9 @@ Html5.registerSourceHandler(Html5.nativeSourceHandler); * @return {Boolean} */ Html5.canControlVolume = function(){ - var volume = VjsLib.TEST_VID.volume; - VjsLib.TEST_VID.volume = (volume / 2) + 0.1; - return volume !== VjsLib.TEST_VID.volume; + var volume = Lib.TEST_VID.volume; + Lib.TEST_VID.volume = (volume / 2) + 0.1; + return volume !== Lib.TEST_VID.volume; }; /** @@ -535,9 +535,9 @@ Html5.canControlVolume = function(){ * @return {[type]} [description] */ Html5.canControlPlaybackRate = function(){ - var playbackRate = VjsLib.TEST_VID.playbackRate; - VjsLib.TEST_VID.playbackRate = (playbackRate / 2) + 0.1; - return playbackRate !== VjsLib.TEST_VID.playbackRate; + var playbackRate = Lib.TEST_VID.playbackRate; + Lib.TEST_VID.playbackRate = (playbackRate / 2) + 0.1; + return playbackRate !== Lib.TEST_VID.playbackRate; }; /** @@ -552,11 +552,11 @@ Html5.supportsNativeTextTracks = function() { // Browsers with numeric modes include IE10 and older (<=2013) samsung android models. // Firefox isn't playing nice either with modifying the mode // TODO: Investigate firefox: https://github.com/videojs/video.js/issues/1862 - supportsTextTracks = !!VjsLib.TEST_VID.textTracks; - if (supportsTextTracks && VjsLib.TEST_VID.textTracks.length > 0) { - supportsTextTracks = typeof VjsLib.TEST_VID.textTracks[0]['mode'] !== 'number'; + supportsTextTracks = !!Lib.TEST_VID.textTracks; + if (supportsTextTracks && Lib.TEST_VID.textTracks.length > 0) { + supportsTextTracks = typeof Lib.TEST_VID.textTracks[0]['mode'] !== 'number'; } - if (supportsTextTracks && VjsLib.IS_FIREFOX) { + if (supportsTextTracks && Lib.IS_FIREFOX) { supportsTextTracks = false; } @@ -580,7 +580,7 @@ Html5.prototype['featuresPlaybackRate'] = Html5.canControlPlaybackRate(); * In iOS, if you move a video element in the DOM, it breaks video playback. * @type {Boolean} */ -Html5.prototype['movingMediaElementInDOM'] = !VjsLib.IS_IOS; +Html5.prototype['movingMediaElementInDOM'] = !Lib.IS_IOS; /** * Set the the tech's fullscreen resize support status. @@ -608,12 +608,12 @@ const mp4RE = /^video\/mp4/i; Html5.patchCanPlayType = function() { // Android 4.0 and above can play HLS to some extent but it reports being unable to do so - if (VjsLib.ANDROID_VERSION >= 4.0) { + if (Lib.ANDROID_VERSION >= 4.0) { if (!canPlayType) { - canPlayType = VjsLib.TEST_VID.constructor.prototype.canPlayType; + canPlayType = Lib.TEST_VID.constructor.prototype.canPlayType; } - VjsLib.TEST_VID.constructor.prototype.canPlayType = function(type) { + Lib.TEST_VID.constructor.prototype.canPlayType = function(type) { if (type && mpegurlRE.test(type)) { return 'maybe'; } @@ -622,12 +622,12 @@ Html5.patchCanPlayType = function() { } // Override Android 2.2 and less canPlayType method which is broken - if (VjsLib.IS_OLD_ANDROID) { + if (Lib.IS_OLD_ANDROID) { if (!canPlayType) { - canPlayType = VjsLib.TEST_VID.constructor.prototype.canPlayType; + canPlayType = Lib.TEST_VID.constructor.prototype.canPlayType; } - VjsLib.TEST_VID.constructor.prototype.canPlayType = function(type){ + Lib.TEST_VID.constructor.prototype.canPlayType = function(type){ if (type && mp4RE.test(type)) { return 'maybe'; } @@ -637,8 +637,8 @@ Html5.patchCanPlayType = function() { }; Html5.unpatchCanPlayType = function() { - var r = VjsLib.TEST_VID.constructor.prototype.canPlayType; - VjsLib.TEST_VID.constructor.prototype.canPlayType = canPlayType; + var r = Lib.TEST_VID.constructor.prototype.canPlayType; + Lib.TEST_VID.constructor.prototype.canPlayType = canPlayType; canPlayType = null; return r; }; diff --git a/src/js/media/loader.js b/src/js/media/loader.js index c8054e7675..15b2e25aa0 100644 --- a/src/js/media/loader.js +++ b/src/js/media/loader.js @@ -1,5 +1,5 @@ import Component from '../component'; -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; import window from 'global/window'; /** @@ -17,7 +17,7 @@ let MediaLoader = Component.extend({ // load the first supported playback technology. if (!player.options_['sources'] || player.options_['sources'].length === 0) { for (let i=0, j=player.options_['techOrder']; i'+this.defaultValue+'' }, props); diff --git a/src/js/tracks/text-track-controls.js b/src/js/tracks/text-track-controls.js index a89eba8f72..4a5260535a 100644 --- a/src/js/tracks/text-track-controls.js +++ b/src/js/tracks/text-track-controls.js @@ -1,6 +1,7 @@ import Component from '../component'; import Menu, { MenuItem, MenuButton } from '../menu'; -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; +import document from 'global/document'; import window from 'global/window'; /* Text Track Display @@ -12,24 +13,24 @@ import window from 'global/window'; * * @constructor */ -let TextTrackDisplay = Component.extend({ +var TextTrackDisplay = Component.extend({ /** @constructor */ init: function(player, options, ready){ Component.call(this, player, options, ready); - player.on('loadstart', VjsLib.bind(this, this.toggleDisplay)); + player.on('loadstart', Lib.bind(this, this.toggleDisplay)); // This used to be called during player init, but was causing an error // if a track should show by default and the display hadn't loaded yet. // Should probably be moved to an external track loader when we support // tracks that don't need a display. - player.ready(VjsLib.bind(this, function() { + player.ready(Lib.bind(this, function() { if (player.tech && player.tech['featuresNativeTextTracks']) { this.hide(); return; } - player.on('fullscreenchange', VjsLib.bind(this, this.updateDisplay)); + player.on('fullscreenchange', Lib.bind(this, this.updateDisplay)); let tracks = player.options_['tracks'] || []; for (let i = 0; i < tracks.length; i++) { @@ -186,7 +187,7 @@ TextTrackDisplay.prototype.updateForTrack = function(track) { * * @constructor */ -let TextTrackMenuItem = MenuItem.extend({ +var TextTrackMenuItem = MenuItem.extend({ /** @constructor */ init: function(player, options){ let track = this.track = options['track']; @@ -195,7 +196,7 @@ let TextTrackMenuItem = MenuItem.extend({ let changeHandler; if (tracks) { - changeHandler = VjsLib.bind(this, function() { + changeHandler = Lib.bind(this, function() { let selected = this.track['mode'] === 'showing'; if (this instanceof OffTextTrackMenuItem) { @@ -281,7 +282,7 @@ TextTrackMenuItem.prototype.onClick = function(){ * * @constructor */ -let OffTextTrackMenuItem = TextTrackMenuItem.extend({ +var OffTextTrackMenuItem = TextTrackMenuItem.extend({ /** @constructor */ init: function(player, options){ // Create pseudo track info @@ -326,7 +327,7 @@ CaptionSettingsMenuItem.prototype.onClick = function() { * * @constructor */ -let TextTrackButton = MenuButton.extend({ +var TextTrackButton = MenuButton.extend({ /** @constructor */ init: function(player, options){ MenuButton.call(this, player, options); @@ -341,7 +342,7 @@ let TextTrackButton = MenuButton.extend({ return; } - let updateHandler = VjsLib.bind(this, this.update); + let updateHandler = Lib.bind(this, this.update); tracks.addEventListener('removetrack', updateHandler); tracks.addEventListener('addtrack', updateHandler); @@ -390,7 +391,7 @@ TextTrackButton.prototype.createItems = function(){ * * @constructor */ -let CaptionsButton = TextTrackButton.extend({ +var CaptionsButton = TextTrackButton.extend({ /** @constructor */ init: function(player, options, ready){ TextTrackButton.call(this, player, options, ready); @@ -425,7 +426,7 @@ CaptionsButton.prototype.update = function() { * * @constructor */ -let SubtitlesButton = TextTrackButton.extend({ +var SubtitlesButton = TextTrackButton.extend({ /** @constructor */ init: function(player, options, ready){ TextTrackButton.call(this, player, options, ready); @@ -446,7 +447,7 @@ SubtitlesButton.prototype.className = 'vjs-subtitles-button'; * * @constructor */ -let ChaptersButton = TextTrackButton.extend({ +var ChaptersButton = TextTrackButton.extend({ /** @constructor */ init: function(player, options, ready){ TextTrackButton.call(this, player, options, ready); @@ -494,7 +495,7 @@ ChaptersButton.prototype.createMenu = function(){ track['mode'] = 'hidden'; /* jshint loopfunc:true */ // TODO see if we can figure out a better way of doing this https://github.com/videojs/video.js/issues/1864 - window.setTimeout(VjsLib.bind(this, function() { + window.setTimeout(Lib.bind(this, function() { this.createMenu(); }), 100); /* jshint loopfunc:false */ @@ -508,9 +509,9 @@ ChaptersButton.prototype.createMenu = function(){ let menu = this.menu; if (menu === undefined) { menu = new Menu(this.player_); - menu.contentEl().appendChild(VjsLib.createEl('li', { + menu.contentEl().appendChild(Lib.createEl('li', { className: 'vjs-menu-title', - innerHTML: VjsLib.capitalize(this.kind_), + innerHTML: Lib.capitalize(this.kind_), tabindex: -1 })); } @@ -544,7 +545,7 @@ ChaptersButton.prototype.createMenu = function(){ /** * @constructor */ -let ChaptersTrackMenuItem = MenuItem.extend({ +var ChaptersTrackMenuItem = MenuItem.extend({ /** @constructor */ init: function(player, options){ let track = this.track = options['track']; @@ -556,7 +557,7 @@ let ChaptersTrackMenuItem = MenuItem.extend({ options['selected'] = (cue['startTime'] <= currentTime && currentTime < cue['endTime']); MenuItem.call(this, player, options); - track.addEventListener('cuechange', VjsLib.bind(this, this.update)); + track.addEventListener('cuechange', Lib.bind(this, this.update)); } }); @@ -576,4 +577,4 @@ ChaptersTrackMenuItem.prototype.update = function(){ this.selected(cue['startTime'] <= currentTime && currentTime < cue['endTime']); }; -export { TextTrackDisplay, TextTrackButton, CaptionsButton, SubtitlesButton, ChaptersButton, ChaptersTrackMenuItem }; +export { TextTrackDisplay, TextTrackButton, CaptionsButton, SubtitlesButton, ChaptersButton, TextTrackMenuItem, ChaptersTrackMenuItem }; diff --git a/src/js/tracks/text-track-cue-list.js b/src/js/tracks/text-track-cue-list.js index e57b7fcd82..554ccb6446 100644 --- a/src/js/tracks/text-track-cue-list.js +++ b/src/js/tracks/text-track-cue-list.js @@ -1,4 +1,4 @@ -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; import document from 'global/document'; /* @@ -14,7 +14,7 @@ import document from 'global/document'; let TextTrackCueList = function(cues) { let list = this; - if (VjsLib.IS_IE8) { + if (Lib.IS_IE8) { list = document.createElement('custom'); for (let prop in TextTrackCueList.prototype) { @@ -30,12 +30,16 @@ let TextTrackCueList = function(cues) { } }); - if (VjsLib.IS_IE8) { + if (Lib.IS_IE8) { return list; } }; TextTrackCueList.prototype.setCues_ = function(cues) { + let oldLength = this.length || 0; + let i = 0; + let l = cues.length; + this.cues_ = cues; this.length_ = cues.length; @@ -49,10 +53,10 @@ TextTrackCueList.prototype.setCues_ = function(cues) { } }; - let oldLength = this.length || 0; - let l = cues.length; if (oldLength < l) { - for(let i = oldLength; i < l; i++) { + i = oldLength; + + for(; i < l; i++) { defineProp.call(this, i); } } diff --git a/src/js/tracks/text-track-enums.js b/src/js/tracks/text-track-enums.js index 7568cc4af3..ec92db272a 100644 --- a/src/js/tracks/text-track-enums.js +++ b/src/js/tracks/text-track-enums.js @@ -3,7 +3,7 @@ * * enum TextTrackMode { "disabled", "hidden", "showing" }; */ -let TextTrackMode = { +var TextTrackMode = { 'disabled': 'disabled', 'hidden': 'hidden', 'showing': 'showing' @@ -14,7 +14,7 @@ let TextTrackMode = { * * enum TextTrackKind { "subtitles", "captions", "descriptions", "chapters", "metadata" }; */ -let TextTrackKind = { +var TextTrackKind = { 'subtitles': 'subtitles', 'captions': 'captions', 'descriptions': 'descriptions', diff --git a/src/js/tracks/text-track-list.js b/src/js/tracks/text-track-list.js index 26621e3eb5..ba840ddc7b 100644 --- a/src/js/tracks/text-track-list.js +++ b/src/js/tracks/text-track-list.js @@ -1,5 +1,5 @@ import EventEmitter from '../event-emitter'; -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; import document from 'global/document'; /* @@ -18,7 +18,7 @@ import document from 'global/document'; let TextTrackList = function(tracks) { let list = this; - if (VjsLib.IS_IE8) { + if (Lib.IS_IE8) { list = document.createElement('custom'); for (let prop in TextTrackList.prototype) { @@ -39,12 +39,12 @@ let TextTrackList = function(tracks) { list.addTrack_(tracks[i]); } - if (VjsLib.IS_IE8) { + if (Lib.IS_IE8) { return list; } }; -TextTrackList.prototype = VjsLib.obj.create(EventEmitter.prototype); +TextTrackList.prototype = Lib.obj.create(EventEmitter.prototype); TextTrackList.prototype.constructor = TextTrackList; /* @@ -73,7 +73,7 @@ TextTrackList.prototype.addTrack_ = function(track) { }); } - track.addEventListener('modechange', VjsLib.bind(this, function() { + track.addEventListener('modechange', Lib.bind(this, function() { this.trigger('change'); })); this.tracks_.push(track); @@ -105,7 +105,7 @@ TextTrackList.prototype.removeTrack_ = function(rtrack) { TextTrackList.prototype.getTrackById = function(id) { let result = null; - for (let i = 0, i = this.length; i < l; i++) { + for (let i = 0, l = this.length; i < l; i++) { let 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 6c2062a42a..c3de1910ba 100644 --- a/src/js/tracks/text-track-settings.js +++ b/src/js/tracks/text-track-settings.js @@ -1,6 +1,6 @@ import Component from '../component'; -import * as VjsLib from '../lib'; -import * as VjsEvents from '../events'; +import * as Lib from '../lib'; +import * as Events from '../events'; import window from 'global/window'; let TextTrackSettings = Component.extend({ @@ -8,12 +8,12 @@ let TextTrackSettings = Component.extend({ Component.call(this, player, options); this.hide(); - VjsEvents.on(this.el().querySelector('.vjs-done-button'), 'click', VjsLib.bind(this, function() { + Events.on(this.el().querySelector('.vjs-done-button'), 'click', Lib.bind(this, function() { this.saveSettings(); this.hide(); })); - VjsEvents.on(this.el().querySelector('.vjs-default-button'), 'click', VjsLib.bind(this, function() { + Events.on(this.el().querySelector('.vjs-default-button'), 'click', Lib.bind(this, function() { this.el().querySelector('.vjs-fg-color > select').selectedIndex = 0; this.el().querySelector('.vjs-bg-color > select').selectedIndex = 0; this.el().querySelector('.window-color > select').selectedIndex = 0; @@ -26,15 +26,15 @@ let TextTrackSettings = Component.extend({ this.updateDisplay(); })); - VjsEvents.on(this.el().querySelector('.vjs-fg-color > select'), 'change', VjsLib.bind(this, this.updateDisplay)); - VjsEvents.on(this.el().querySelector('.vjs-bg-color > select'), 'change', VjsLib.bind(this, this.updateDisplay)); - VjsEvents.on(this.el().querySelector('.window-color > select'), 'change', VjsLib.bind(this, this.updateDisplay)); - VjsEvents.on(this.el().querySelector('.vjs-text-opacity > select'), 'change', VjsLib.bind(this, this.updateDisplay)); - VjsEvents.on(this.el().querySelector('.vjs-bg-opacity > select'), 'change', VjsLib.bind(this, this.updateDisplay)); - VjsEvents.on(this.el().querySelector('.vjs-window-opacity > select'), 'change', VjsLib.bind(this, this.updateDisplay)); - VjsEvents.on(this.el().querySelector('.vjs-font-percent select'), 'change', VjsLib.bind(this, this.updateDisplay)); - VjsEvents.on(this.el().querySelector('.vjs-edge-style select'), 'change', VjsLib.bind(this, this.updateDisplay)); - VjsEvents.on(this.el().querySelector('.vjs-font-family select'), 'change', VjsLib.bind(this, this.updateDisplay)); + Events.on(this.el().querySelector('.vjs-fg-color > select'), 'change', Lib.bind(this, this.updateDisplay)); + Events.on(this.el().querySelector('.vjs-bg-color > select'), 'change', Lib.bind(this, this.updateDisplay)); + Events.on(this.el().querySelector('.window-color > select'), 'change', Lib.bind(this, this.updateDisplay)); + Events.on(this.el().querySelector('.vjs-text-opacity > select'), 'change', Lib.bind(this, this.updateDisplay)); + Events.on(this.el().querySelector('.vjs-bg-opacity > select'), 'change', Lib.bind(this, this.updateDisplay)); + Events.on(this.el().querySelector('.vjs-window-opacity > select'), 'change', Lib.bind(this, this.updateDisplay)); + Events.on(this.el().querySelector('.vjs-font-percent select'), 'change', Lib.bind(this, this.updateDisplay)); + Events.on(this.el().querySelector('.vjs-edge-style select'), 'change', Lib.bind(this, this.updateDisplay)); + Events.on(this.el().querySelector('.vjs-font-family select'), 'change', Lib.bind(this, this.updateDisplay)); if (player.options()['persistTextTrackSettings']) { this.restoreSettings(); @@ -122,7 +122,7 @@ TextTrackSettings.prototype.saveSettings = function() { let values = this.getValues(); try { - if (!VjsLib.isEmpty(values)) { + if (!Lib.isEmpty(values)) { window.localStorage.setItem('vjs-text-track-settings', JSON.stringify(values)); } else { window.localStorage.removeItem('vjs-text-track-settings'); diff --git a/src/js/tracks/text-track.js b/src/js/tracks/text-track.js index 3cfc918f98..ea453e5631 100644 --- a/src/js/tracks/text-track.js +++ b/src/js/tracks/text-track.js @@ -1,8 +1,10 @@ import TextTrackCueList from './text-track-cue-list'; -import * as VjsLib from '../lib'; +import * as Lib from '../lib'; import * as TextTrackEnum from './text-track-enums'; import EventEmitter from '../event-emitter'; import document from 'global/document'; +import window from 'global/window'; +import XHR from '../xhr.js'; /* * https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack @@ -35,7 +37,7 @@ let TextTrack = function(options) { } let tt = this; - if (VjsLib.IS_IE8) { + if (Lib.IS_IE8) { tt = document.createElement('custom'); for (let prop in TextTrack.prototype) { @@ -49,7 +51,7 @@ let TextTrack = function(options) { let kind = TextTrackEnum.TextTrackKind[options['kind']] || 'subtitles'; let label = options['label'] || ''; let language = options['language'] || options['srclang'] || ''; - let id = options['id'] || 'vjs_text_track_' + VjsLib.guid++; + let id = options['id'] || 'vjs_text_track_' + Lib.guid++; if (kind === 'metadata' || kind === 'chapters') { mode = 'hidden'; @@ -62,7 +64,7 @@ let TextTrack = function(options) { let activeCues = new TextTrackCueList(tt.activeCues_); let changed = false; - let timeupdateHandler = VjsLib.bind(tt, function() { + let timeupdateHandler = Lib.bind(tt, function() { this['activeCues']; if (changed) { this['trigger']('cuechange'); @@ -176,12 +178,12 @@ let TextTrack = function(options) { tt.loaded_ = true; } - if (VjsLib.IS_IE8) { + if (Lib.IS_IE8) { return tt; } }; -TextTrack.prototype = VjsLib.obj.create(EventEmitter.prototype); +TextTrack.prototype = Lib.obj.create(EventEmitter.prototype); TextTrack.prototype.constructor = TextTrack; /* @@ -239,17 +241,17 @@ let parseCues = function(srcContent, track) { track.addCue(cue); }; parser['onparsingerror'] = function(error) { - VjsLib.log.error(error); + Lib.log.error(error); }; parser['parse'](srcContent); parser['flush'](); }; -let loadTrack = function(src, track) { - VjsLib.xhr(src, VjsLib.bind(this, function(err, response, responseBody){ +var loadTrack = function(src, track) { + XHR(src, Lib.bind(this, function(err, response, responseBody){ if (err) { - return VjsLib.log.error(err); + return Lib.log.error(err); } @@ -258,7 +260,7 @@ let loadTrack = function(src, track) { })); }; -let indexOf = function(searchElement, fromIndex) { +var indexOf = function(searchElement, fromIndex) { if (this == null) { throw new TypeError('"this" is null or not defined'); } diff --git a/src/js/util.js b/src/js/util.js index 934405ff64..fc5d92f5b5 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -15,7 +15,7 @@ var util = {}; * @param {Object} obj2 Overriding object * @return {Object} New object -- obj1 and obj2 will be untouched */ -let mergeOptions = function(obj1, obj2){ +var mergeOptions = function(obj1, obj2){ var key, val1, val2; // make a copy of obj1 so we're not overwriting original values. diff --git a/src/js/video.js b/src/js/video.js index eb10ee12af..dc87a89b6a 100644 --- a/src/js/video.js +++ b/src/js/video.js @@ -13,7 +13,9 @@ import ErrorDisplay from './error-display'; import videojs from './core'; import * as setup from './setup'; import Component from './component'; -import * as VjsLib from './lib'; +import * as Lib from './lib'; +import * as Util from './util.js'; + if (typeof HTMLVideoElement === 'undefined') { document.createElement('video'); @@ -28,18 +30,31 @@ setup.autoSetupTimeout(1, videojs); videojs.getComponent = Component.getComponent; videojs.registerComponent = Component.registerComponent; -// Expose but deprecate the window[componentName] method for accessing components -VjsLib.obj.each(Component.components, function(name, component){ - // A deprecation warning as the constuctor - module.exports[name] = function(player, options, ready){ - VjsLib.log.warn('Using videojs.'+name+' to access the '+name+' component has been deprecated. Please use videojs.getComponent("componentName")'); +// APIs that will be removed with 5.0, but need them to get tests passing +// in ES6 transition +videojs.TOUCH_ENABLED = Lib.TOUCH_ENABLED; +videojs.util = Util; + +// Probably want to keep this one for 5.0? +import Player from './player'; +videojs.players = Player.players; + +// REMOVING: We probably should not include this in 5.0 thought it would make it +// more backwards compatible +// // Expose but deprecate the window[componentName] method for accessing components +// Lib.obj.each(Component.components, function(name, component){ +// // A deprecation warning as the constuctor +// module.exports[name] = function(player, options, ready){ +// Lib.log.warn('Using videojs.'+name+' to access the '+name+' component has been deprecated. Please use videojs.getComponent("componentName")'); +// +// return new Component(player, options, ready); +// }; +// +// // Allow the prototype and class methods to be accessible still this way +// // Though anything that attempts to override class methods will no longer work +// Lib.obj.merge(module.exports[name], component); +// }); - return new Component(player, options, ready); - }; - // Allow the prototype and class methods to be accessible still this way - // Though anything that attempts to override class methods will no longer work - VjsLib.obj.merge(module.exports[name], component); -}); export default videojs; diff --git a/src/js/xhr.js b/src/js/xhr.js index 50395d09b4..2d2250e1c3 100644 --- a/src/js/xhr.js +++ b/src/js/xhr.js @@ -1,5 +1,5 @@ -import VjsUtils from './utils'; -import * as VjsLib from './lib'; +import * as VjsUtils from './util'; +import * as Lib from './lib'; import window from 'global/window'; /** @@ -66,7 +66,7 @@ var xhr = function(options, callback){ // Store a reference to the url on the request instance request.uri = options.uri; - let urlInfo = VjsLib.parseUrl(options.uri); + let urlInfo = Lib.parseUrl(options.uri); let winLoc = window.location; let successHandler = function(){ diff --git a/test/karma-qunit-shim.js b/test/karma-qunit-shim.js index 2e827d6a8f..6d0742b68a 100644 --- a/test/karma-qunit-shim.js +++ b/test/karma-qunit-shim.js @@ -1,3 +1,6 @@ +var q = QUnit; + +// This may not be needed anymore, but double check before removing var fixture = document.createElement('div'); fixture.id = 'qunit-fixture'; document.body.appendChild(fixture); diff --git a/test/karma.conf.js b/test/karma.conf.js index 41590324bd..f70e6cc04b 100644 --- a/test/karma.conf.js +++ b/test/karma.conf.js @@ -1,19 +1,19 @@ var fs = require('fs'); var vm = require('vm'); var babelify = require('babelify'); -var sourceLoader = fs.readFileSync('./build/source-loader.js', 'utf8'); -var sandbox = { - blockSourceLoading: true, - document: {}, - window: {} -}; -var sourceFiles = []; - - -vm.runInNewContext(sourceLoader, sandbox, 'build/source-loader.js'); -sourceFiles = sandbox.sourceFiles.map(function(src) { - return '../' + src; -}); +// var sourceLoader = fs.readFileSync('./build/source-loader.js', 'utf8'); +// var sandbox = { +// blockSourceLoading: true, +// document: {}, +// window: {} +// }; +// var sourceFiles = []; +// +// +// vm.runInNewContext(sourceLoader, sandbox, 'build/source-loader.js'); +// sourceFiles = sandbox.sourceFiles.map(function(src) { +// return '../' + src; +// }); module.exports = function(config) { var customLaunchers = { @@ -82,7 +82,7 @@ module.exports = function(config) { ], preprocessors: { - 'test/**/*.js': [ 'browserify' ] + '../test/unit/**/*.js': [ 'browserify' ] }, browserify: { diff --git a/test/unit/api.js b/test/unit/api.js index 5ee53cd9c5..9a1b086d63 100644 --- a/test/unit/api.js +++ b/test/unit/api.js @@ -1,7 +1,11 @@ -module('Player Minified'); +import videojs from '../../src/js/video.js'; +import TestHelpers from './test-helpers.js'; +import document from 'global/document'; + +q.module('Player Minified'); test('should be able to access expected player API methods', function() { - var player = PlayerTest.makePlayer(); + var player = TestHelpers.makePlayer(); // Native HTML5 Methods ok(player.error, 'error exists'); @@ -64,7 +68,7 @@ test('should be able to access expected player API methods', function() { }); test('should be able to access expected component API methods', function() { - var comp = videojs.Component.create({ id: function(){ return 1; }, reportUserActivity: function(){} }); + var comp = videojs.getComponent('Component').create({ id: function(){ return 1; }, reportUserActivity: function(){} }); // Component methods ok(comp.player, 'player exists'); @@ -101,38 +105,38 @@ test('should be able to access expected component API methods', function() { }); test('should be able to access expected MediaTech API methods', function() { - var media = videojs.MediaTechController; - var mediaProto = videojs.MediaTechController.prototype; - var html5 = videojs.Html5; - var html5Proto = videojs.Html5.prototype; - var flash = videojs.Flash; - var flashProto = videojs.Flash.prototype; + var media = videojs.getComponent('MediaTechController'); + var mediaProto = media.prototype; + var html5 = videojs.getComponent('Html5'); + var html5Proto = html5.prototype; + var flash = videojs.getComponent('Flash'); + var 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'); - ok(videojs.Html5.patchCanPlayType, 'patchCanPlayType should exist for HTML5'); - ok(videojs.Html5.unpatchCanPlayType, 'unpatchCanPlayType should exist for HTML5'); + ok(html5.patchCanPlayType, 'patchCanPlayType should exist for HTML5'); + ok(html5.unpatchCanPlayType, 'unpatchCanPlayType should exist for HTML5'); // Source Handler Functions ok(media.withSourceHandlers, 'withSourceHandlers should exist for Media Tech'); - ok(videojs.Html5.canPlaySource, 'canPlaySource should exist for HTML5'); - ok(videojs.Html5.registerSourceHandler, 'registerSourceHandler should exist for Html5'); - ok(videojs.Html5.selectSourceHandler, 'selectSourceHandler should exist for Html5'); - ok(videojs.Html5.prototype.setSource, 'setSource should exist for Html5'); - ok(videojs.Html5.prototype.disposeSourceHandler, 'disposeSourceHandler should exist for Html5'); - - ok(videojs.Flash.canPlaySource, 'canPlaySource should exist for Flash'); - ok(videojs.Flash.registerSourceHandler, 'registerSourceHandler should exist for Flash'); - ok(videojs.Flash.selectSourceHandler, 'selectSourceHandler should exist for Flash'); - ok(videojs.Flash.prototype.setSource, 'setSource should exist for Flash'); - ok(videojs.Flash.prototype.disposeSourceHandler, 'disposeSourceHandler should exist for Flash'); + 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'); }); test('should export ready api call to public', function() { - var videoTag = PlayerTest.makeTag(); + var videoTag = TestHelpers.makeTag(); var fixture = document.getElementById('qunit-fixture'); fixture.appendChild(videoTag); @@ -144,50 +148,50 @@ test('should export ready api call to public', function() { test('should export useful components to the public', function () { ok(videojs.TOUCH_ENABLED !== undefined, 'Touch detection should be public'); - ok(videojs.ControlBar, 'ControlBar should be public'); - ok(videojs.Button, 'Button should be public'); - ok(videojs.PlayToggle, 'PlayToggle should be public'); - ok(videojs.FullscreenToggle, 'FullscreenToggle should be public'); - ok(videojs.BigPlayButton, 'BigPlayButton should be public'); - ok(videojs.LoadingSpinner, 'LoadingSpinner should be public'); - ok(videojs.CurrentTimeDisplay, 'CurrentTimeDisplay should be public'); - ok(videojs.DurationDisplay, 'DurationDisplay should be public'); - ok(videojs.TimeDivider, 'TimeDivider should be public'); - ok(videojs.RemainingTimeDisplay, 'RemainingTimeDisplay should be public'); - ok(videojs.Slider, 'Slider should be public'); - ok(videojs.ProgressControl, 'ProgressControl should be public'); - ok(videojs.SeekBar, 'SeekBar should be public'); - ok(videojs.LoadProgressBar, 'LoadProgressBar should be public'); - ok(videojs.PlayProgressBar, 'PlayProgressBar should be public'); - ok(videojs.SeekHandle, 'SeekHandle should be public'); - ok(videojs.VolumeControl, 'VolumeControl should be public'); - ok(videojs.VolumeBar, 'VolumeBar should be public'); - ok(videojs.VolumeLevel, 'VolumeLevel should be public'); - ok(videojs.VolumeMenuButton, 'VolumeMenuButton should be public'); - ok(videojs.VolumeHandle, 'VolumeHandle should be public'); - ok(videojs.MuteToggle, 'MuteToggle should be public'); - ok(videojs.PosterImage, 'PosterImage should be public'); - ok(videojs.Menu, 'Menu should be public'); - ok(videojs.MenuItem, 'MenuItem should be public'); - ok(videojs.MenuButton, 'MenuButton should be public'); - ok(videojs.PlaybackRateMenuButton, 'PlaybackRateMenuButton should be public'); - - ok(videojs.CaptionSettingsMenuItem, 'CaptionSettingsMenuItem should be public'); - ok(videojs.OffTextTrackMenuItem, 'OffTextTrackMenuItem should be public'); - ok(videojs.TextTrackMenuItem, 'TextTrackMenuItem should be public'); - ok(videojs.TextTrackDisplay, 'TextTrackDisplay should be public'); - ok(videojs.TextTrackButton, 'TextTrackButton should be public'); - ok(videojs.CaptionsButton, 'CaptionsButton should be public'); - ok(videojs.SubtitlesButton, 'SubtitlesButton should be public'); - ok(videojs.ChaptersButton, 'ChaptersButton should be public'); - ok(videojs.ChaptersTrackMenuItem, 'ChaptersTrackMenuItem 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('SeekHandle'), 'SeekHandle 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('VolumeHandle'), 'VolumeHandle 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('ChaptersButton'), 'ChaptersButton should be public'); + ok(videojs.getComponent('ChaptersTrackMenuItem'), 'ChaptersTrackMenuItem should be public'); ok(videojs.util, 'util namespace should be public'); ok(videojs.util.mergeOptions, 'mergeOptions should be public'); }); test('should be able to initialize player twice on the same tag using string reference', function() { - var videoTag = PlayerTest.makeTag(); + var videoTag = TestHelpers.makeTag(); var id = videoTag.id; var fixture = document.getElementById('qunit-fixture'); @@ -197,7 +201,7 @@ test('should be able to initialize player twice on the same tag using string ref player.dispose(); ok(!document.getElementById(id), 'element is removed'); - videoTag = PlayerTest.makeTag(); + videoTag = TestHelpers.makeTag(); fixture.appendChild(videoTag); player = videojs('example_1'); @@ -205,7 +209,7 @@ test('should be able to initialize player twice on the same tag using string ref }); test('videojs.players should be available after minification', function() { - var videoTag = PlayerTest.makeTag(); + var videoTag = TestHelpers.makeTag(); var id = videoTag.id; var fixture = document.getElementById('qunit-fixture'); @@ -217,41 +221,11 @@ test('videojs.players should be available after minification', function() { player.dispose(); }); -// NOTE: This test could be removed after we've landed on a permanent -// externs/exports strategy. See comment on videojs/video.js#853 -test('fullscreenToggle does not depend on minified player methods', function(){ - var noop, player, fullscreen, requestFullscreen, exitFullscreen, isFullscreen_; - noop = function(){}; - requestFullscreen = false; - exitFullscreen = false; - - player = PlayerTest.makePlayer(); - - player['requestFullscreen'] = function(){ - requestFullscreen = true; - }; - player['exitFullscreen'] = function(){ - exitFullscreen = true; - }; - - isFullscreen_ = false; - player['isFullscreen'] = function(){ - return isFullscreen_; - }; - - fullscreen = new videojs.FullscreenToggle(player); - fullscreen.trigger('click'); - - ok(requestFullscreen, 'requestFullscreen called'); - - isFullscreen_ = true; - fullscreen.trigger('click'); - - ok(exitFullscreen, 'exitFullscreen called'); -}); - test('component can be subclassed externally', function(){ - var player = new (videojs.Component.extend({ + var Component = videojs.getComponent('Component'); + var ControlBar = videojs.getComponent('ControlBar'); + + var player = new (Component.extend({ languages: function(){}, reportUserActivity: function(){}, language: function(){}, @@ -264,5 +238,6 @@ test('component can be subclassed externally', function(){ id: function(){}, reportUserActivity: function(){} }); - ok(new videojs.ControlBar(player), 'created a control bar without throwing'); + + ok(new ControlBar(player), 'created a control bar without throwing'); }); diff --git a/test/unit/button.js b/test/unit/button.js index 29ac335e46..cf3c380a9f 100644 --- a/test/unit/button.js +++ b/test/unit/button.js @@ -1,13 +1,14 @@ -module('Button'); +import Button from '../../src/js/button.js'; +import TestHelpers from './test-helpers.js'; -var Button = vjs.Button; +q.module('Button'); test('should localize its text', function(){ expect(1); var player, testButton, el; - player = PlayerTest.makePlayer({ + player = TestHelpers.makePlayer({ 'language': 'es', 'languages': { 'es': { diff --git a/test/unit/component.js b/test/unit/component.js index 32b56be8ef..4fde5c5088 100644 --- a/test/unit/component.js +++ b/test/unit/component.js @@ -1,4 +1,9 @@ -module('Component', { +import Component from '../../src/js/component.js'; +import * as Lib from '../../src/js/lib.js'; +import * as Events from '../../src/js/events.js'; +import document from 'global/document'; + +q.module('Component', { 'setup': function() { this.clock = sinon.useFakeTimers(); }, @@ -7,8 +12,6 @@ module('Component', { } }); -var Component = vjs.Component; - var getFakePlayer = function(){ return { // Fake player requries an ID @@ -161,8 +164,8 @@ test('should dispose of component and children', function(){ // Add a listener comp.on('click', function(){ return true; }); - var data = vjs.getData(comp.el()); - var id = comp.el()[vjs.expando]; + var data = Lib.getData(comp.el()); + var id = comp.el()[Lib.expando]; var hasDisposed = false; var bubbles = null; @@ -179,8 +182,8 @@ test('should dispose of component and children', function(){ ok(!comp.el(), 'component element was deleted'); ok(!child.children(), 'child children were deleted'); ok(!child.el(), 'child element was deleted'); - ok(!vjs.cache[id], 'listener cache nulled'); - ok(vjs.isEmpty(data), 'original listener cache object was emptied'); + ok(!Lib.cache[id], 'listener cache nulled'); + ok(Lib.isEmpty(data), 'original listener cache object was emptied'); }); test('should add and remove event listeners to element', function(){ @@ -299,27 +302,27 @@ test('should add listeners to other element and remove them', function(){ }; comp1.on(el, 'test-event', testListener); - vjs.trigger(el, 'test-event'); + Events.trigger(el, 'test-event'); equal(listenerFired, 1, 'listener was fired once'); listenerFired = 0; comp1.off(el, 'test-event', testListener); - vjs.trigger(el, 'test-event'); + Events.trigger(el, 'test-event'); 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(); - vjs.trigger(el, 'test-event'); + Events.trigger(el, 'test-event'); equal(listenerFired, 0, 'listener was removed when this component was disposed first'); comp1.off = function(){ throw 'Comp1 off called'; }; try { - vjs.trigger(el, 'dispose'); + Events.trigger(el, 'dispose'); } catch(e) { ok(false, 'listener was not removed from other element'); } - vjs.trigger(el, 'dispose'); + Events.trigger(el, 'dispose'); ok(true, 'this component removed dispose listeners from other element'); }); @@ -336,9 +339,9 @@ test('should add listeners to other components that are fired once', function(){ }; comp1.one(el, 'test-event', testListener); - vjs.trigger(el, 'test-event'); + Events.trigger(el, 'test-event'); equal(listenerFired, 1, 'listener was executed once'); - vjs.trigger(el, 'test-event'); + Events.trigger(el, 'test-event'); equal(listenerFired, 1, 'listener was executed only once'); }); @@ -424,7 +427,7 @@ test('should change the width and height of a component', function(){ comp.height('123px'); ok(comp.width() === 500, 'percent values working'); - var compStyle = vjs.getComputedDimension(el, 'width'); + var compStyle = Lib.getComputedDimension(el, 'width'); ok(compStyle === comp.width() + 'px', 'matches computed style'); ok(comp.height() === 123, 'px values working'); @@ -442,9 +445,9 @@ test('should use a defined content el for appending children', function(){ var CompWithContent = Component.extend(); CompWithContent.prototype.createEl = function(){ // Create the main componenent element - var el = vjs.createEl('div'); + var el = Lib.createEl('div'); // Create the element where children will be appended - this.contentEl_ = vjs.createEl('div', { 'id': 'contentEl' }); + this.contentEl_ = Lib.createEl('div', { 'id': 'contentEl' }); el.appendChild(this.contentEl_); return el; }; @@ -467,8 +470,8 @@ test('should emit a tap event', function(){ expect(3); // Fake touch support. Real touch support isn't needed for this test. - var origTouch = vjs.TOUCH_ENABLED; - vjs.TOUCH_ENABLED = true; + var origTouch = Lib.TOUCH_ENABLED; + Lib.TOUCH_ENABLED = true; var comp = new Component(getFakePlayer()); var singleTouch = {}; @@ -479,23 +482,23 @@ test('should emit a tap event', function(){ }); // A touchstart followed by touchend should trigger a tap - vjs.trigger(comp.el(), {type: 'touchstart', touches: [{}]}); + Events.trigger(comp.el(), {type: 'touchstart', touches: [{}]}); comp.trigger('touchend'); // A touchmove with a lot of movement should not trigger a tap - vjs.trigger(comp.el(), {type: 'touchstart', touches: [ + Events.trigger(comp.el(), {type: 'touchstart', touches: [ { pageX: 0, pageY: 0 } ]}); - vjs.trigger(comp.el(), {type: 'touchmove', touches: [ + Events.trigger(comp.el(), {type: 'touchmove', touches: [ { pageX: 100, pageY: 100 } ]}); comp.trigger('touchend'); // A touchmove with not much movement should still allow a tap - vjs.trigger(comp.el(), {type: 'touchstart', touches: [ + Events.trigger(comp.el(), {type: 'touchstart', touches: [ { pageX: 0, pageY: 0 } ]}); - vjs.trigger(comp.el(), {type: 'touchmove', touches: [ + Events.trigger(comp.el(), {type: 'touchmove', touches: [ { pageX: 7, pageY: 7 } ]}); comp.trigger('touchend'); @@ -503,23 +506,23 @@ test('should emit a tap event', function(){ // A touchmove with a lot of movement by modifying the exisiting touch object // should not trigger a tap singleTouch = { pageX: 0, pageY: 0 }; - vjs.trigger(comp.el(), {type: 'touchstart', touches: [singleTouch]}); + Events.trigger(comp.el(), {type: 'touchstart', touches: [singleTouch]}); singleTouch.pageX = 100; singleTouch.pageY = 100; - vjs.trigger(comp.el(), {type: 'touchmove', touches: [singleTouch]}); + Events.trigger(comp.el(), {type: 'touchmove', touches: [singleTouch]}); comp.trigger('touchend'); // A touchmove with not much movement by modifying the exisiting touch object // should still allow a tap singleTouch = { pageX: 0, pageY: 0 }; - vjs.trigger(comp.el(), {type: 'touchstart', touches: [singleTouch]}); + Events.trigger(comp.el(), {type: 'touchstart', touches: [singleTouch]}); singleTouch.pageX = 7; singleTouch.pageY = 7; - vjs.trigger(comp.el(), {type: 'touchmove', touches: [singleTouch]}); + Events.trigger(comp.el(), {type: 'touchmove', touches: [singleTouch]}); comp.trigger('touchend'); // Reset to orignial value - vjs.TOUCH_ENABLED = origTouch; + Lib.TOUCH_ENABLED = origTouch; }); test('should provide timeout methods that automatically get cleared on component disposal', function() { diff --git a/test/unit/control-bar.js b/test/unit/control-bar.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test/unit/controls.js b/test/unit/controls.js index 1259765bd0..1ada41fda3 100644 --- a/test/unit/controls.js +++ b/test/unit/controls.js @@ -1,4 +1,11 @@ -module('Controls'); +import VolumeControl from '../../src/js/control-bar/volume-control.js'; +import MuteToggle from '../../src/js/control-bar/mute-toggle.js'; +import PlaybackRateMenuButton from '../../src/js/control-bar/playback-rate-menu-button.js'; +import Slider from '../../src/js/slider.js'; +import TestHelpers from './test-helpers.js'; +import document from 'global/document'; + +q.module('Controls'); test('should hide volume control if it\'s not supported', function(){ expect(2); @@ -19,8 +26,8 @@ test('should hide volume control if it\'s not supported', function(){ reportUserActivity: function(){} }; - volumeControl = new vjs.VolumeControl(player); - muteToggle = new vjs.MuteToggle(player); + volumeControl = new VolumeControl(player); + 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'); @@ -53,8 +60,8 @@ test('should test and toggle volume control on `loadstart`', function(){ reportUserActivity: function(){} }; - volumeControl = new vjs.VolumeControl(player); - muteToggle = new vjs.MuteToggle(player); + volumeControl = new VolumeControl(player); + muteToggle = new MuteToggle(player); equal(volumeControl.hasClass('vjs-hidden'), false, 'volumeControl is hidden initially'); equal(muteToggle.hasClass('vjs-hidden'), false, 'muteToggle is hidden initially'); @@ -85,7 +92,7 @@ test('calculateDistance should use changedTouches, if available', function() { ready: noop, reportUserActivity: noop }; - slider = new vjs.Slider(player); + slider = new Slider(player); document.body.appendChild(slider.el_); slider.el_.style.position = 'absolute'; slider.el_.style.width = '200px'; @@ -104,8 +111,8 @@ test('calculateDistance should use changedTouches, if available', function() { test('should hide playback rate control if it\'s not supported', function(){ expect(1); - var player = PlayerTest.makePlayer(); - var playbackRate = new vjs.PlaybackRateMenuButton(player); + var player = TestHelpers.makePlayer(); + var playbackRate = new PlaybackRateMenuButton(player); ok(playbackRate.el().className.indexOf('vjs-hidden') >= 0, 'playbackRate is not hidden'); }); diff --git a/test/unit/core-object.js b/test/unit/core-object.js index 6f44e664db..503abf212e 100644 --- a/test/unit/core-object.js +++ b/test/unit/core-object.js @@ -1,9 +1,9 @@ -module('Core Object'); +import CoreObject from '../../src/js/core-object.js'; -var vjs = videojs.TEST; +q.module('Core Object'); test('should verify CoreObject extension', function(){ - var TestObject = vjs.CoreObject.extend({ + var TestObject = CoreObject.extend({ init: function(initOptions){ this['a'] = initOptions['a']; }, @@ -14,7 +14,7 @@ test('should verify CoreObject extension', function(){ var instance = new TestObject({ 'a': true }); ok(instance instanceof TestObject, 'New instance is instance of TestObject'); - ok(instance instanceof vjs.CoreObject, 'New instance is instance of CoreObject'); + ok(instance instanceof CoreObject, 'New instance is instance of CoreObject'); ok(instance['a'], 'Init options are passed to init'); ok(instance.testFn(), 'Additional methods are applied to TestObject prototype'); @@ -34,7 +34,7 @@ test('should verify CoreObject extension', function(){ ok(childInstance instanceof TestChild, 'New instance is instance of TestChild'); ok(childInstance instanceof TestObject, 'New instance is instance of TestObject'); - ok(childInstance instanceof vjs.CoreObject, 'New instance is instance of CoreObject'); + ok(childInstance instanceof CoreObject, 'New instance is instance of CoreObject'); ok(childInstance['b'], 'Init options are passed to init'); ok(childInstance['a'], 'Init options are passed to super init'); ok(childInstance.testFn() === false, 'Methods can be overridden by extend'); @@ -42,7 +42,7 @@ test('should verify CoreObject extension', function(){ }); test('should verify CoreObject create function', function(){ - var TestObject = vjs.CoreObject.extend({ + var TestObject = CoreObject.extend({ init: function(initOptions){ this['a'] = initOptions['a']; }, @@ -54,7 +54,7 @@ test('should verify CoreObject create function', function(){ var instance = TestObject.create({ 'a': true }); ok(instance instanceof TestObject, 'New instance is instance of TestObject'); - ok(instance instanceof vjs.CoreObject, 'New instance is instance of CoreObject'); + ok(instance instanceof CoreObject, 'New instance is instance of CoreObject'); ok(instance['a'], 'Init options are passed to init'); ok(instance.testFn(), 'Additional methods are applied to TestObject prototype'); }); diff --git a/test/unit/core.js b/test/unit/core.js index 5ccdf945b0..c66583dc3d 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -1,4 +1,10 @@ -module('Core'); +import videojs from '../../src/js/core.js'; +import Player from '../../src/js/player.js'; +import * as Lib from '../../src/js/lib.js'; +import Options from '../../src/js/options.js'; +import document from 'global/document'; + +q.module('Core'); test('should create a video tag and have access children in old IE', function(){ var fixture = document.getElementById('qunit-fixture'); @@ -18,7 +24,7 @@ test('should return a video player instance', function(){ var player = videojs('test_vid_id'); ok(player, 'created player from tag'); ok(player.id() === 'test_vid_id'); - ok(videojs.players['test_vid_id'] === player, 'added player to global reference'); + ok(Player.players['test_vid_id'] === player, 'added player to global reference'); var playerAgain = videojs('test_vid_id'); ok(player === playerAgain, 'did not create a second player from same tag'); @@ -33,9 +39,9 @@ test('should add the value to the languages object', function() { code = 'es'; data = {'Hello': 'Hola'}; - result = vjs.addLanguage(code, data); + result = videojs.addLanguage(code, data); - ok(vjs.options['languages'][code], 'should exist'); - equal(vjs.options['languages'][code], data, 'should match'); - deepEqual(result[code], vjs.options['languages'][code], 'should also match'); + ok(Options['languages'][code], 'should exist'); + equal(Options['languages'][code], data, 'should match'); + deepEqual(result[code], Options['languages'][code], 'should also match'); }); \ No newline at end of file diff --git a/test/unit/events.js b/test/unit/events.js index 95e3b4924b..25b05bc0d6 100644 --- a/test/unit/events.js +++ b/test/unit/events.js @@ -1,6 +1,7 @@ -module('Events'); +import * as Events from '../../src/js/events.js'; +import document from 'global/document'; -var Events = vjs.Events; +q.module('Events'); test('should add and remove an event listener to an element', function(){ expect(1); diff --git a/test/unit/flash.js b/test/unit/flash.js index c97ceb319b..5cbecd6cf0 100644 --- a/test/unit/flash.js +++ b/test/unit/flash.js @@ -1,6 +1,7 @@ -module('Flash'); +import Flash from '../../src/js/media/flash.js'; +import document from 'global/document'; -var Flash = vjs.Flash; +q.module('Flash'); var streamToPartsAndBack = function(url) { var parts = Flash.streamToParts(url); @@ -76,7 +77,15 @@ test('currentTime is the seek target during seeking', function() { trigger: noop, ready: noop, addChild: noop, - options_: {} + options_: {}, + // This complexity is needed because of the VTT.js loading + // It'd be great if we can find a better solution for that + options: function(){ return {}; }, + el: function(){ + return { + appendChild: noop + }; + } }, { 'parentEl': parentEl }), @@ -113,6 +122,7 @@ test('dispose removes the object element even before ready fires', function() { trigger: noop, ready: noop, addChild: noop, + options: function(){ return {}; }, options_: {} }, { 'parentEl': parentEl @@ -126,7 +136,7 @@ test('dispose removes the object element even before ready fires', function() { test('ready triggering before and after disposing the tech', function() { var checkReady, fixtureDiv, playerDiv, techEl; - checkReady = sinon.stub(vjs.Flash, 'checkReady'); + checkReady = sinon.stub(Flash, 'checkReady'); fixtureDiv = document.getElementById('qunit-fixture'); playerDiv = document.createElement('div'); diff --git a/test/unit/lib.js b/test/unit/lib.js index f853ff1ee2..7c874a08e1 100644 --- a/test/unit/lib.js +++ b/test/unit/lib.js @@ -1,13 +1,14 @@ -var createElement; +import * as Lib from '../../src/js/lib.js'; +import window from 'global/window'; +import document from 'global/document'; -var Lib = vjs.Lib; - -module('Lib', { +q.module('Lib', { 'setup': function() { - createElement = document.createElement; + // Allow for stubbing createElement, should replace with sinon now + this.createElement = document.createElement; }, 'teardown': function() { - document.createElement = createElement; + document.createElement = this.createElement; } }); @@ -396,15 +397,13 @@ test('should loop through each element of an array', function() { deepEqual(array, a, 'The array arg should match the original array'); equal(i++, iterator, 'The indexes should match'); equal(this, thisArg, 'The context should equal the thisArg'); - }, thisArg); - ok(sum, 6); - Lib.arr.forEach(a, function(){ - console.log(this); - if (this !== videojs) { - ok(false, 'default context should be vjs'); + if (this !== thisArg) { + ok(false, 'should allow setting the context'); } - }); + }, thisArg); + + ok(sum, 6); }); //getFileExtension tests diff --git a/test/unit/media.html5.js b/test/unit/media.html5.js index 1303b278dd..d3c2541698 100644 --- a/test/unit/media.html5.js +++ b/test/unit/media.html5.js @@ -1,8 +1,10 @@ var player, tech, el; -var Html5 = vjs.Html5; +import Html5 from '../../src/js/media/html5.js'; +import * as Lib from '../../src/js/lib.js'; +import document from 'global/document'; -module('HTML5', { +q.module('HTML5', { 'setup': function() { el = document.createElement('div'); @@ -22,7 +24,7 @@ module('HTML5', { addChild: function(){}, trigger: function(){} }; - tech = new vjs.Html5(player, {}); + tech = new Html5(player, {}); }, 'teardown': function() { tech.dispose(); @@ -113,7 +115,7 @@ test('patchCanPlayType patches canplaytype with our function, conditionally', fu strictEqual(patchedCanPlayType, unpatchedCanPlayType, 'patched canPlayType and function returned from unpatch are equal'); Lib.ANDROID_VERSION = oldAV; - Lib.Html5.unpatchCanPlayType(); + Html5.unpatchCanPlayType(); }); test('should return maybe for HLS urls on Android 4.0 or above', function() { @@ -121,7 +123,7 @@ test('should return maybe for HLS urls on Android 4.0 or above', function() { video = document.createElement('video'); Lib.ANDROID_VERSION = 4.0; - Lib.Html5.patchCanPlayType(); + Html5.patchCanPlayType(); strictEqual(video.canPlayType('application/x-mpegurl'), 'maybe', 'android version 4.0 or above should be a maybe for x-mpegurl'); strictEqual(video.canPlayType('application/x-mpegURL'), 'maybe', 'android version 4.0 or above should be a maybe for x-mpegURL'); @@ -129,7 +131,7 @@ test('should return maybe for HLS urls on Android 4.0 or above', function() { strictEqual(video.canPlayType('application/vnd.apple.mpegURL'), 'maybe', 'android version 4.0 or above should be a maybe for vnd.apple.mpegurl'); Lib.ANDROID_VERSION = oldAV; - Lib.Html5.unpatchCanPlayType(); + Html5.unpatchCanPlayType(); }); test('should return a maybe for mp4 on OLD ANDROID', function() { @@ -137,12 +139,12 @@ test('should return a maybe for mp4 on OLD ANDROID', function() { video = document.createElement('video'); Lib.IS_OLD_ANDROID = true; - Lib.Html5.patchCanPlayType(); + Html5.patchCanPlayType(); strictEqual(video.canPlayType('video/mp4'), 'maybe', 'old android should return a maybe for video/mp4'); Lib.IS_OLD_ANDROID = isOldAndroid; - Lib.Html5.unpatchCanPlayType(); + Html5.unpatchCanPlayType(); }); test('error events may not set the errors property', function() { @@ -152,7 +154,7 @@ test('error events may not set the errors property', function() { }); test('should have the source handler interface', function() { - ok(Lib.Html5.registerSourceHandler, 'has the registerSourceHandler function'); + ok(Html5.registerSourceHandler, 'has the registerSourceHandler function'); }); test('native source handler canHandleSource', function(){ @@ -167,7 +169,7 @@ test('native source handler canHandleSource', function(){ return ''; }; - var canHandleSource = vjs.Html5.nativeSourceHandler.canHandleSource; + var canHandleSource = Html5.nativeSourceHandler.canHandleSource; equal(canHandleSource({ type: 'video/mp4', src: 'video.flv' }), 'maybe', 'Native source handler reported type support'); equal(canHandleSource({ src: 'http://www.example.com/video.mp4' }), 'maybe', 'Native source handler reported extension support'); diff --git a/test/unit/media.js b/test/unit/media.js index 891ab711d2..647386ec44 100644 --- a/test/unit/media.js +++ b/test/unit/media.js @@ -1,8 +1,8 @@ var noop = function() {}, clock, oldTextTracks; -var MediaTechController = vjs.MediaTechController; +import MediaTechController from '../../src/js/media/media.js'; -module('Media Tech', { +q.module('Media Tech', { 'setup': function() { this.noop = function() {}; this.clock = sinon.useFakeTimers(); diff --git a/test/unit/mediafaker.js b/test/unit/mediafaker.js index cc5b19c19e..408a7948aa 100644 --- a/test/unit/mediafaker.js +++ b/test/unit/mediafaker.js @@ -1,12 +1,14 @@ // Fake a media playback tech controller so that player tests // can run without HTML5 or Flash, of which PhantomJS supports neither. -var MediaTechController = vjs.MediaTechController; +import MediaTechController from '../../src/js/media/media.js'; +import * as Lib from '../../src/js/lib.js'; +import Component from '../../src/js/component.js'; /** * @constructor */ -vjs.MediaFaker = MediaTechController.extend({ +var MediaFaker = MediaTechController.extend({ init: function(player, options, onReady){ MediaTechController.call(this, player, options, onReady); @@ -15,10 +17,10 @@ vjs.MediaFaker = MediaTechController.extend({ }); // Support everything except for "video/unsupported-format" -vjs.MediaFaker.isSupported = function(){ return true; }; -vjs.MediaFaker.canPlaySource = function(srcObj){ return srcObj.type !== 'video/unsupported-format'; }; +MediaFaker.isSupported = function(){ return true; }; +MediaFaker.canPlaySource = function(srcObj){ return srcObj.type !== 'video/unsupported-format'; }; -vjs.MediaFaker.prototype.createEl = function(){ +MediaFaker.prototype.createEl = function(){ var el = MediaTechController.prototype.createEl.call(this, 'div', { className: 'vjs-tech' }); @@ -27,32 +29,30 @@ vjs.MediaFaker.prototype.createEl = function(){ el.poster = this.player().poster(); } - vjs.Lib.insertFirst(el, this.player_.el()); + Lib.insertFirst(el, this.player_.el()); return el; }; // fake a poster attribute to mimic the video element -vjs.MediaFaker.prototype.poster = function(){ return this.el().poster; }; -vjs.MediaFaker.prototype['setPoster'] = function(val){ this.el().poster = val; }; - -vjs.MediaFaker.prototype.currentTime = function(){ return 0; }; -vjs.MediaFaker.prototype.seeking = function(){ return false; }; -vjs.MediaFaker.prototype.src = function(){ return 'movie.mp4'; }; -vjs.MediaFaker.prototype.volume = function(){ return 0; }; -vjs.MediaFaker.prototype.muted = function(){ return false; }; -vjs.MediaFaker.prototype.pause = function(){ return false; }; -vjs.MediaFaker.prototype.paused = function(){ return true; }; -vjs.MediaFaker.prototype.play = function() { +MediaFaker.prototype.poster = function(){ return this.el().poster; }; +MediaFaker.prototype['setPoster'] = function(val){ this.el().poster = val; }; + +MediaFaker.prototype.currentTime = function(){ return 0; }; +MediaFaker.prototype.seeking = function(){ return false; }; +MediaFaker.prototype.src = function(){ return 'movie.mp4'; }; +MediaFaker.prototype.volume = function(){ return 0; }; +MediaFaker.prototype.muted = function(){ return false; }; +MediaFaker.prototype.pause = function(){ return false; }; +MediaFaker.prototype.paused = function(){ return true; }; +MediaFaker.prototype.play = function() { this.player().trigger('play'); }; -vjs.MediaFaker.prototype.supportsFullScreen = function(){ return false; }; -vjs.MediaFaker.prototype.buffered = function(){ return {}; }; -vjs.MediaFaker.prototype.duration = function(){ return {}; }; -vjs.MediaFaker.prototype.networkState = function(){ return 0; }; -vjs.MediaFaker.prototype.readyState = function(){ return 0; }; - -// Export vars for Closure Compiler -vjs['MediaFaker'] = vjs.MediaFaker; -vjs['MediaFaker']['isSupported'] = vjs.MediaFaker.isSupported; -vjs['MediaFaker']['canPlaySource'] = vjs.MediaFaker.canPlaySource; +MediaFaker.prototype.supportsFullScreen = function(){ return false; }; +MediaFaker.prototype.buffered = function(){ return {}; }; +MediaFaker.prototype.duration = function(){ return {}; }; +MediaFaker.prototype.networkState = function(){ return 0; }; +MediaFaker.prototype.readyState = function(){ return 0; }; + +Component.registerComponent('MediaFaker', MediaFaker); +module.exports = MediaFaker; \ No newline at end of file diff --git a/test/unit/menu.js b/test/unit/menu.js index fc79340ccb..19ceca5207 100644 --- a/test/unit/menu.js +++ b/test/unit/menu.js @@ -1,11 +1,14 @@ -module('MenuButton'); +import { MenuButton } from '../../src/js/menu.js'; +import TestHelpers from './test-helpers.js'; + +q.module('MenuButton'); test('should place title list item into ul', function() { var player, menuButton; - player = PlayerTest.makePlayer(); + player = TestHelpers.makePlayer(); - menuButton = new vjs.MenuButton(player, { + menuButton = new MenuButton(player, { 'title': 'testTitle' }); diff --git a/test/unit/player.js b/test/unit/player.js index 4715be07c2..3a84b79c8a 100644 --- a/test/unit/player.js +++ b/test/unit/player.js @@ -1,4 +1,13 @@ -module('Player', { +import Player from '../../src/js/player.js'; +import videojs from '../../src/js/core.js'; +import Options from '../../src/js/options.js'; +import * as Lib from '../../src/js/lib.js'; +import MediaError from '../../src/js/media-error.js'; +import Html5 from '../../src/js/media/html5.js'; +import TestHelpers from './test-helpers.js'; +import document from 'global/document'; + +q.module('Player', { 'setup': function() { this.clock = sinon.useFakeTimers(); }, @@ -7,8 +16,6 @@ module('Player', { } }); -var Player = vjs.Player; - // Compiler doesn't like using 'this' in setup/teardown. // module("Player", { // /** @@ -40,7 +47,7 @@ var Player = vjs.Player; test('should create player instance that inherits from component and dispose it', function(){ - var player = PlayerTest.makePlayer(); + var player = TestHelpers.makePlayer(); ok(player.el().nodeName === 'DIV'); ok(player.on, 'component function exists'); @@ -56,16 +63,16 @@ test('should accept options from multiple sources and override in correct order' // version of the key for all version. // Set a global option - vjs.options['attr'] = 1; + Options['attr'] = 1; - var tag0 = PlayerTest.makeTag(); + var tag0 = TestHelpers.makeTag(); var player0 = new Player(tag0); ok(player0.options_['attr'] === 1, 'global option was set'); player0.dispose(); // Set a tag level option - var tag1 = PlayerTest.makeTag(); + var tag1 = TestHelpers.makeTag(); tag1.setAttribute('attr', 'asdf'); // Attributes must be set as strings var player1 = new Player(tag1); @@ -73,7 +80,7 @@ test('should accept options from multiple sources and override in correct order' player1.dispose(); // Set a tag level option - var tag2 = PlayerTest.makeTag(); + var tag2 = TestHelpers.makeTag(); tag2.setAttribute('attr', 'asdf'); var player2 = new Player(tag2, { 'attr': 'fdsa' }); @@ -95,7 +102,7 @@ test('should get tag, source, and track settings', function(){ fixture.innerHTML += html; var tag = document.getElementById('example_1'); - var player = PlayerTest.makePlayer({}, tag); + var player = TestHelpers.makePlayer({}, tag); ok(player.options_['autoplay'] === true); ok(player.options_['preload'] === 'none'); // No extern. Use string. @@ -127,7 +134,7 @@ test('should asynchronously fire error events during source selection', function sinon.stub(Lib.log, 'error'); - var player = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ 'techOrder': ['foo'], 'sources': [ { 'src': 'http://vjs.zencdn.net/v/oceans.mp4', 'type': 'video/mp4' } @@ -146,7 +153,7 @@ test('should asynchronously fire error events during source selection', function }); test('should set the width and height of the player', function(){ - var player = PlayerTest.makePlayer({ width: 123, height: '100%' }); + var player = TestHelpers.makePlayer({ width: 123, height: '100%' }); ok(player.width() === 123); ok(player.el().style.width === '123px'); @@ -165,7 +172,7 @@ test('should set the width and height of the player', function(){ }); test('should not force width and height', function() { - var player = PlayerTest.makePlayer({ width: 'auto', height: 'auto' }); + var player = TestHelpers.makePlayer({ width: 'auto', height: 'auto' }); ok(player.el().style.width === '', 'Width is not forced'); ok(player.el().style.height === '', 'Height is not forced'); @@ -173,7 +180,7 @@ test('should not force width and height', function() { }); test('should wrap the original tag in the player div', function(){ - var tag = PlayerTest.makeTag(); + var tag = TestHelpers.makeTag(); var container = document.createElement('div'); var fixture = document.getElementById('qunit-fixture'); @@ -196,10 +203,10 @@ test('should set and update the poster value', function(){ poster = 'http://example.com/poster.jpg'; updatedPoster = 'http://example.com/updated-poster.jpg'; - tag = PlayerTest.makeTag(); + tag = TestHelpers.makeTag(); tag.setAttribute('poster', poster); - player = PlayerTest.makePlayer({}, tag); + player = TestHelpers.makePlayer({}, tag); equal(player.poster(), poster, 'the poster property should equal the tag attribute'); var pcEmitted = false; @@ -218,7 +225,7 @@ test('should set and update the poster value', function(){ // 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 = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ poster: 'https://example.com/poster.jpg' }); @@ -236,7 +243,7 @@ test('should hide the poster when play is called', function() { }); test('should load a media controller', function(){ - var player = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ preload: 'none', sources: [ { src: 'http://google.com', type: 'video/mp4' }, @@ -250,22 +257,22 @@ test('should load a media controller', function(){ }); test('should be able to initialize player twice on the same tag using string reference', function() { - var videoTag = PlayerTest.makeTag(); + var videoTag = TestHelpers.makeTag(); var id = videoTag.id; var fixture = document.getElementById('qunit-fixture'); fixture.appendChild(videoTag); - var player = vjs(videoTag.id); + var player = videojs(videoTag.id); ok(player, 'player is created'); player.dispose(); ok(!document.getElementById(id), 'element is removed'); - videoTag = PlayerTest.makeTag(); + videoTag = TestHelpers.makeTag(); fixture.appendChild(videoTag); //here we receive cached version instead of real - player = vjs(videoTag.id); + player = videojs(videoTag.id); //here it triggers error, because player was destroyed already after first dispose player.dispose(); }); @@ -273,7 +280,7 @@ test('should be able to initialize player twice on the same tag using string ref test('should set controls and trigger events', function() { expect(6); - var player = PlayerTest.makePlayer({ 'controls': false }); + 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'); @@ -302,7 +309,7 @@ test('should set controls and trigger events', function() { // asyncTest('should trigger the fullscreenchange event', function() { // expect(3); -// var player = PlayerTest.makePlayer(); +// var player = TestHelpers.makePlayer(); // player.on('fullscreenchange', function(){ // ok(true, 'fullscreenchange event fired'); // ok(this.isFullscreen() === true, 'isFullscreen is true'); @@ -316,7 +323,7 @@ test('should set controls and trigger events', function() { // }); test('should toggle user the user state between active and inactive', function(){ - var player = PlayerTest.makePlayer({}); + var player = TestHelpers.makePlayer({}); expect(9); @@ -349,20 +356,20 @@ test('should add a touch-enabled classname when touch is supported', function(){ expect(1); // Fake touch support. Real touch support isn't needed for this test. - var origTouch = vjs.TOUCH_ENABLED; - vjs.TOUCH_ENABLED = true; + var origTouch = Lib.TOUCH_ENABLED; + Lib.TOUCH_ENABLED = true; - player = PlayerTest.makePlayer({}); + player = TestHelpers.makePlayer({}); ok(player.el().className.indexOf('vjs-touch-enabled'), 'touch-enabled classname added'); - vjs.TOUCH_ENABLED = origTouch; + Lib.TOUCH_ENABLED = origTouch; player.dispose(); }); test('should allow for tracking when native controls are used', function(){ - var player = PlayerTest.makePlayer({}); + var player = TestHelpers.makePlayer({}); expect(6); @@ -428,7 +435,7 @@ test('should register players with generated ids', function(){ test('should not add multiple first play events despite subsequent loads', function() { expect(1); - var player = PlayerTest.makePlayer({}); + var player = TestHelpers.makePlayer({}); player.on('firstplay', function(){ ok(true, 'First play should fire once.'); @@ -441,7 +448,7 @@ test('should not add multiple first play events despite subsequent loads', funct }); test('should fire firstplay after resetting the player', function() { - var player = PlayerTest.makePlayer({}); + var player = TestHelpers.makePlayer({}); var fpFired = false; player.on('firstplay', function(){ @@ -472,7 +479,7 @@ test('should fire firstplay after resetting the player', function() { test('should remove vjs-has-started class', function(){ expect(3); - var player = PlayerTest.makePlayer({}); + var player = TestHelpers.makePlayer({}); player.trigger('loadstart'); player.trigger('play'); @@ -488,7 +495,7 @@ test('should remove vjs-has-started class', function(){ test('should add and remove vjs-ended class', function() { expect(4); - var player = PlayerTest.makePlayer({}); + var player = TestHelpers.makePlayer({}); player.trigger('loadstart'); player.trigger('play'); @@ -507,11 +514,11 @@ test('should add and remove vjs-ended class', function() { test('player should handle different error types', function(){ expect(8); - var player = PlayerTest.makePlayer({}); + var player = TestHelpers.makePlayer({}); var testMsg = 'test message'; // prevent error log messages in the console - sinon.stub(vjs.log, 'error'); + sinon.stub(Lib.log, 'error'); // error code supplied function errCode(){ @@ -527,7 +534,7 @@ test('player should handle different error types', function(){ equal(player.error().message, testMsg, 'MediaError message is correct'); } player.on('error', errInst); - player.error(new vjs.MediaError({ code: 2, message: testMsg })); + player.error(new MediaError({ code: 2, message: testMsg })); player.off('error', errInst); // error message supplied @@ -552,7 +559,7 @@ test('player should handle different error types', function(){ ok(player.el().className.indexOf('vjs-error') >= 0, 'player does not have vjs-error classname'); // restore error logging - vjs.log.error.restore(); + Lib.log.error.restore(); }); test('Data attributes on the video element should persist in the new wrapper element', function() { @@ -560,10 +567,10 @@ test('Data attributes on the video element should persist in the new wrapper ele dataId = 123; - tag = PlayerTest.makeTag(); + tag = TestHelpers.makeTag(); tag.setAttribute('data-id', dataId); - player = PlayerTest.makePlayer({}, tag); + player = TestHelpers.makePlayer({}, tag); equal(player.el().getAttribute('data-id'), dataId, 'data-id should be available on the new player element after creation'); }); @@ -571,7 +578,7 @@ test('Data attributes on the video element should persist in the new wrapper ele test('should restore attributes from the original video tag when creating a new element', function(){ var player, html5Mock, el; - player = PlayerTest.makePlayer(); + player = TestHelpers.makePlayer(); html5Mock = { player_: player }; // simulate attributes stored from the original tag @@ -585,7 +592,7 @@ test('should restore attributes from the original video tag when creating a new player.options_['preload'] = 'none'; // create the element - el = vjs.Html5.prototype.createEl.call(html5Mock); + 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'); @@ -597,7 +604,7 @@ test('should honor default inactivity timeout', function() { var clock = sinon.useFakeTimers(); // default timeout is 2000ms - player = PlayerTest.makePlayer({}); + player = TestHelpers.makePlayer({}); equal(player.userActive(), true, 'User is active on creation'); clock.tick(1800); @@ -613,7 +620,7 @@ test('should honor configured inactivity timeout', function() { var clock = sinon.useFakeTimers(); // default timeout is 2000ms, set to shorter 200ms - player = PlayerTest.makePlayer({ + player = TestHelpers.makePlayer({ 'inactivityTimeout': 200 }); @@ -632,7 +639,7 @@ test('should honor disabled inactivity timeout', function() { var clock = sinon.useFakeTimers(); // default timeout is 2000ms, disable by setting to zero - player = PlayerTest.makePlayer({ + player = TestHelpers.makePlayer({ 'inactivityTimeout': 0 }); @@ -646,7 +653,7 @@ test('should honor disabled inactivity timeout', function() { test('should clear pending errors on disposal', function() { var clock = sinon.useFakeTimers(), player; - player = PlayerTest.makePlayer(); + player = TestHelpers.makePlayer(); player.src({ src: 'http://example.com/movie.unsupported-format', type: 'video/unsupported-format' @@ -662,7 +669,7 @@ test('should clear pending errors on disposal', function() { test('pause is called when player ended event is fired and player is not paused', function() { var video = document.createElement('video'), - player = PlayerTest.makePlayer({}, video), + player = TestHelpers.makePlayer({}, video), pauses = 0; player.paused = function() { return false; @@ -676,7 +683,7 @@ test('pause is called when player ended event is fired and player is not paused' test('pause is not called if the player is paused and ended is fired', function() { var video = document.createElement('video'), - player = PlayerTest.makePlayer({}, video), + player = TestHelpers.makePlayer({}, video), pauses = 0; player.paused = function() { return true; @@ -690,7 +697,7 @@ test('pause is not called if the player is paused and ended is fired', function( test('should add an audio class if an audio el is used', function() { var audio = document.createElement('audio'), - player = PlayerTest.makePlayer({}, audio), + player = TestHelpers.makePlayer({}, audio), audioClass = 'vjs-audio'; ok(player.el().className.indexOf(audioClass) !== -1, 'added '+ audioClass +' css class'); diff --git a/test/unit/plugins.js b/test/unit/plugins.js index 27c777dc16..c55e0b87c2 100644 --- a/test/unit/plugins.js +++ b/test/unit/plugins.js @@ -1,18 +1,22 @@ -module('Plugins'); +import Plugin from '../../src/js/plugins.js'; +import Player from '../../src/js/player.js'; +import TestHelpers from './test-helpers.js'; + +q.module('Plugins'); test('Plugin should get initialized and receive options', function(){ expect(2); - vjs.plugin('myPlugin1', function(options){ + Plugin('myPlugin1', function(options){ ok(true, 'Plugin initialized'); ok(options['test'], 'Option passed through'); }); - vjs.plugin('myPlugin2', function(options){ + Plugin('myPlugin2', function(options){ ok(false, 'Plugin initialized and should not have been'); }); - var player = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ 'plugins': { 'myPlugin1': { 'test': true @@ -26,12 +30,12 @@ test('Plugin should get initialized and receive options', function(){ test('Plugin should have the option of being initilized outside of player init', function(){ expect(3); - vjs.plugin('myPlugin3', function(options){ + Plugin('myPlugin3', function(options){ ok(true, 'Plugin initialized after player init'); ok(options['test'], 'Option passed through'); }); - var player = PlayerTest.makePlayer({}); + var player = TestHelpers.makePlayer({}); ok(player['myPlugin3'], 'Plugin has direct access on player instance'); @@ -45,12 +49,12 @@ test('Plugin should have the option of being initilized outside of player init', test('Plugin should be able to add a UI component', function(){ expect(2); - vjs.plugin('myPlugin4', function(options){ - ok((this instanceof vjs.Player), 'Plugin executed in player scope by default'); + Plugin('myPlugin4', function(options){ + ok((this instanceof Player), 'Plugin executed in player scope by default'); this.addChild('component'); }); - var player = PlayerTest.makePlayer({}); + var player = TestHelpers.makePlayer({}); player['myPlugin4']({ 'test': true }); @@ -67,21 +71,21 @@ test('Plugin should overwrite plugin of same name', function(){ v3Called = 0; // Create initial plugin - vjs.plugin('myPlugin5', function(options){ + Plugin('myPlugin5', function(options){ v1Called++; }); - var player = PlayerTest.makePlayer({}); + var player = TestHelpers.makePlayer({}); player['myPlugin5']({}); // Overwrite and create new player - vjs.plugin('myPlugin5', function(options){ + Plugin('myPlugin5', function(options){ v2Called++; }); - var player2 = PlayerTest.makePlayer({}); + var player2 = TestHelpers.makePlayer({}); player2['myPlugin5']({}); // Overwrite and init new version on existing player - vjs.plugin('myPlugin5', function(options){ + Plugin('myPlugin5', function(options){ v3Called++; }); player2['myPlugin5']({}); @@ -102,9 +106,9 @@ test('Plugins should get events in registration order', function() { var pluginName = 'orderPlugin'; var i = 0; var name; - var player = PlayerTest.makePlayer({}); + var player = TestHelpers.makePlayer({}); var plugin = function (name) { - vjs.plugin(name, function (opts) { + Plugin(name, function (opts) { this.on('test', function (event) { order.push(name); }); @@ -118,7 +122,7 @@ test('Plugins should get events in registration order', function() { plugin(name); } - vjs.plugin('testerPlugin', function (opts) { + Plugin('testerPlugin', function (opts) { this.trigger('test'); }); @@ -134,9 +138,9 @@ test('Plugins should not get events after stopImmediatePropagation is called', f var pluginName = 'orderPlugin'; var i = 0; var name; - var player = PlayerTest.makePlayer({}); + var player = TestHelpers.makePlayer({}); var plugin = function (name) { - vjs.plugin(name, function (opts) { + Plugin(name, function (opts) { this.on('test', function (event) { order.push(name); event.stopImmediatePropagation(); @@ -151,7 +155,7 @@ test('Plugins should not get events after stopImmediatePropagation is called', f plugin(name); } - vjs.plugin('testerPlugin', function (opts) { + Plugin('testerPlugin', function (opts) { this.trigger('test'); }); diff --git a/test/unit/poster.js b/test/unit/poster.js index 2206d30b6e..b35815b77b 100644 --- a/test/unit/poster.js +++ b/test/unit/poster.js @@ -1,4 +1,9 @@ -module('PosterImage', { +import PosterImage from '../../src/js/poster.js'; +import * as Lib from '../../src/js/lib.js'; +import TestHelpers from './test-helpers.js'; +import document from 'global/document'; + +q.module('PosterImage', { 'setup': function(){ // Store the original background support so we can test different vals this.origVal = Lib.BACKGROUND_SIZE_SUPPORTED; @@ -25,8 +30,6 @@ module('PosterImage', { } }); -var PosterImage = vjs.PosterImage; - test('should create and update a poster image', function(){ var posterImage; @@ -35,7 +38,7 @@ test('should create and update a poster image', function(){ return url.replace(new RegExp('\\"', 'g'),''); } - vjs.BACKGROUND_SIZE_SUPPORTED = true; + Lib.BACKGROUND_SIZE_SUPPORTED = true; posterImage = new PosterImage(this.mockPlayer); equal(normalizeUrl(posterImage.el().style.backgroundImage), 'url('+this.poster1+')', 'Background image used'); @@ -48,7 +51,7 @@ test('should create and update a poster image', function(){ test('should create and update a fallback image in older browsers', function(){ var posterImage; - vjs.BACKGROUND_SIZE_SUPPORTED = false; + Lib.BACKGROUND_SIZE_SUPPORTED = false; posterImage = new PosterImage(this.mockPlayer); equal(posterImage.fallbackImg_.src, this.poster1, 'Fallback image created'); diff --git a/test/unit/setup.js b/test/unit/setup.js index 18f7a10af4..db17db3085 100644 --- a/test/unit/setup.js +++ b/test/unit/setup.js @@ -1,10 +1,12 @@ -module('Setup'); +import TestHelpers from './test-helpers.js'; + +q.module('Setup'); test('should set options from data-setup even if autoSetup is not called before initialisation', function(){ - var el = PlayerTest.makeTag(); + var el = TestHelpers.makeTag(); el.setAttribute('data-setup', '{"controls": true, "autoplay": false, "preload": "auto"}'); - var player = PlayerTest.makePlayer({}, el); + var player = TestHelpers.makePlayer({}, el); ok(player.options_['controls'] === true); ok(player.options_['autoplay'] === false); diff --git a/test/unit/test-helpers.js b/test/unit/test-helpers.js index 0c11b7de5b..784d8e0d8c 100644 --- a/test/unit/test-helpers.js +++ b/test/unit/test-helpers.js @@ -1,14 +1,20 @@ -var PlayerTest = { +import Player from '../../src/js/player.js'; +import MediaFaker from './mediafaker.js'; +import window from 'global/window'; +import document from 'global/document'; + +var TestHelpers = { makeTag: function(){ var videoTag = document.createElement('video'); videoTag.id = 'example_1'; videoTag.className = 'video-js vjs-default-skin'; return videoTag; }, + makePlayer: function(playerOptions, videoTag){ var player; - videoTag = videoTag || PlayerTest.makeTag(); + videoTag = videoTag || TestHelpers.makeTag(); var fixture = document.getElementById('qunit-fixture'); fixture.appendChild(videoTag); @@ -16,11 +22,9 @@ var PlayerTest = { playerOptions = playerOptions || {}; playerOptions['techOrder'] = playerOptions['techOrder'] || ['mediaFaker']; - return player = new vjs.Player(videoTag, playerOptions); - } -}; + return player = new Player(videoTag, playerOptions); + }, -var TestHelpers = { getComputedStyle: function(el, rule){ var val; @@ -34,3 +38,5 @@ var TestHelpers = { return val; } }; + +module.exports = TestHelpers; \ No newline at end of file diff --git a/test/unit/tracks/text-track-controls.js b/test/unit/tracks/text-track-controls.js index 1cbb523301..a39baf4155 100644 --- a/test/unit/tracks/text-track-controls.js +++ b/test/unit/tracks/text-track-controls.js @@ -1,4 +1,8 @@ -module('Text Track Controls'); +import { TextTrackMenuItem } from '../../../src/js/tracks/text-track-controls'; +import TestHelpers from '../test-helpers.js'; +import * as Lib from '../../../src/js/lib.js'; + +q.module('Text Track Controls'); var track = { kind: 'captions', @@ -6,7 +10,7 @@ var track = { }; test('should be displayed when text tracks list is not empty', function() { - var player = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ tracks: [track] }); @@ -15,7 +19,7 @@ test('should be displayed when text tracks list is not empty', function() { }); test('should be displayed when a text track is added to an empty track list', function() { - var player = PlayerTest.makePlayer(); + var player = TestHelpers.makePlayer(); player.addRemoteTextTrack(track); @@ -24,14 +28,14 @@ test('should be displayed when a text track is added to an empty track list', fu }); test('should not be displayed when text tracks list is empty', function() { - var player = PlayerTest.makePlayer(); + var player = TestHelpers.makePlayer(); ok(player.controlBar.captionsButton.hasClass('vjs-hidden'), 'control is not displayed'); equal(player.textTracks().length, 0, 'textTracks is empty'); }); test('should not be displayed when last text track is removed', function() { - var player = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ tracks: [track] }); @@ -42,7 +46,7 @@ test('should not be displayed when last text track is removed', function() { }); test('menu should contain "Settings", "Off" and one track', function() { - var player = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ tracks: [track] }), menuItems = player.controlBar.captionsButton.items; @@ -54,7 +58,7 @@ test('menu should contain "Settings", "Off" and one track', function() { }); test('menu should update with addRemoteTextTrack', function() { - var player = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ tracks: [track] }); @@ -65,7 +69,7 @@ test('menu should update with addRemoteTextTrack', function() { }); test('menu should update with removeRemoteTextTrack', function() { - var player = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ tracks: [track, track] }); @@ -75,19 +79,19 @@ test('menu should update with removeRemoteTextTrack', function() { equal(player.textTracks().length, 1, 'textTracks contains one item'); }); -if (!vjs.IS_IE8) { +if (!Lib.IS_IE8) { // This test doesn't work on IE8. // However, this test tests a specific with iOS7 where the TextTrackList doesn't report track mode changes. // TODO: figure out why this test doens't work on IE8. https://github.com/videojs/video.js/issues/1861 test('menu items should polyfill mode change events', function() { - var player = PlayerTest.makePlayer({}), + var player = TestHelpers.makePlayer({}), changes, trackMenuItem; // emulate a TextTrackList that doesn't report track mode changes, // like iOS7 player.textTracks().onchange = undefined; - trackMenuItem = new vjs.TextTrackMenuItem(player, { + trackMenuItem = new TextTrackMenuItem(player, { track: track }); diff --git a/test/unit/tracks/text-track-cue-list.js b/test/unit/tracks/text-track-cue-list.js index b035faef2a..c9f15e8309 100644 --- a/test/unit/tracks/text-track-cue-list.js +++ b/test/unit/tracks/text-track-cue-list.js @@ -1,23 +1,25 @@ -(function() { -module('Text Track Cue List'); - -var TTCL = vjs.TextTrackCueList, - genericTracks = [{ - id: '1' - }, { - id: '2' - }, { - id: '3' - }]; +import TextTrackCueList from '../../../src/js/tracks/text-track-cue-list.js'; + +let genericTracks = [ + { + id: '1' + }, { + id: '2' + }, { + id: '3' + } +]; + +q.module('Text Track Cue List'); test('TextTrackCueList\'s length is set correctly', function() { - var ttcl = new TTCL(genericTracks); + var ttcl = new TextTrackCueList(genericTracks); equal(ttcl.length, genericTracks.length, 'the length is ' + genericTracks.length); }); test('can get cues by id', function() { - var ttcl = new TTCL(genericTracks); + var ttcl = new TextTrackCueList(genericTracks); equal(ttcl.getCueById('1').id, 1, 'id "1" has id of "1"'); equal(ttcl.getCueById('2').id, 2, 'id "2" has id of "2"'); @@ -26,7 +28,7 @@ test('can get cues by id', function() { }); test('length is updated when new tracks are added or removed', function() { - var ttcl = new TTCL(genericTracks); + var ttcl = new TextTrackCueList(genericTracks); ttcl.setCues_(genericTracks.concat([{id: '100'}])); equal(ttcl.length, genericTracks.length + 1, 'the length is ' + (genericTracks.length + 1)); @@ -40,7 +42,7 @@ test('length is updated when new tracks are added or removed', function() { }); test('can access items by index', function() { - var ttcl = new TTCL(genericTracks), + var ttcl = new TextTrackCueList(genericTracks), i = 0, length = ttcl.length; @@ -52,16 +54,17 @@ test('can access items by index', function() { }); test('can access new items by index', function() { - var ttcl = new TTCL(genericTracks); + var ttcl = new TextTrackCueList(genericTracks); ttcl.setCues_(genericTracks.concat([{id: '100'}])); + equal(ttcl[3].id, '100', 'id of item at index 3 is 100'); ttcl.setCues_(genericTracks.concat([{id: '100'}, {id: '101'}])); equal(ttcl[4].id, '101', 'id of item at index 4 is 101'); }); test('cannot access removed items by index', function() { - var ttcl = new TTCL(genericTracks); + var ttcl = new TextTrackCueList(genericTracks); ttcl.setCues_(genericTracks.concat([{id: '100'}, {id: '101'}])); equal(ttcl[3].id, '100', 'id of item at index 3 is 100'); @@ -74,7 +77,7 @@ test('cannot access removed items by index', function() { }); test('new item available at old index', function() { - var ttcl = new TTCL(genericTracks); + var ttcl = new TextTrackCueList(genericTracks); ttcl.setCues_(genericTracks.concat([{id: '100'}])); equal(ttcl[3].id, '100', 'id of item at index 3 is 100'); @@ -85,5 +88,3 @@ test('new item available at old index', function() { ttcl.setCues_(genericTracks.concat([{id: '101'}])); equal(ttcl[3].id, '101', 'id of new item at index 3 is now 101'); }); - -})(); diff --git a/test/unit/tracks/text-track-list.js b/test/unit/tracks/text-track-list.js index dbe033a384..9eb7052986 100644 --- a/test/unit/tracks/text-track-list.js +++ b/test/unit/tracks/text-track-list.js @@ -1,26 +1,31 @@ -module('Text Track List'); - -var TTL = vjs.TextTrackList, - noop = Function.prototype, - genericTracks = [{ - id: '1', - addEventListener: noop - }, { - id: '2', - addEventListener: noop - }, { - id: '3', - addEventListener: noop - }]; +import TextTrackList from '../../../src/js/tracks/text-track-list.js'; +import TextTrack from '../../../src/js/tracks/text-track.js'; +import EventEmitter from '../../../src/js/event-emitter.js'; + +var noop = Function.prototype; +var genericTracks = [ + { + id: '1', + addEventListener: noop + }, { + id: '2', + addEventListener: noop + }, { + id: '3', + addEventListener: noop + } +]; + +q.module('Text Track List'); test('TextTrackList\'s length is set correctly', function() { - var ttl = new TTL(genericTracks); + var ttl = new TextTrackList(genericTracks); equal(ttl.length, genericTracks.length, 'the length is ' + genericTracks.length); }); test('can get text tracks by id', function() { - var ttl = new TTL(genericTracks); + var ttl = new TextTrackList(genericTracks); equal(ttl.getTrackById('1').id, 1, 'id "1" has id of "1"'); equal(ttl.getTrackById('2').id, 2, 'id "2" has id of "2"'); @@ -29,7 +34,7 @@ test('can get text tracks by id', function() { }); test('length is updated when new tracks are added or removed', function() { - var ttl = new TTL(genericTracks); + var ttl = new TextTrackList(genericTracks); ttl.addTrack_({id: '100', addEventListener: noop}); equal(ttl.length, genericTracks.length + 1, 'the length is ' + (genericTracks.length + 1)); @@ -43,7 +48,7 @@ test('length is updated when new tracks are added or removed', function() { }); test('can access items by index', function() { - var ttl = new TTL(genericTracks), + var ttl = new TextTrackList(genericTracks), i = 0, length = ttl.length; @@ -55,7 +60,7 @@ test('can access items by index', function() { }); test('can access new items by index', function() { - var ttl = new TTL(genericTracks); + var ttl = new TextTrackList(genericTracks); ttl.addTrack_({id: '100', addEventListener: noop}); equal(ttl[3].id, '100', 'id of item at index 3 is 100'); @@ -64,7 +69,7 @@ test('can access new items by index', function() { }); test('cannot access removed items by index', function() { - var ttl = new TTL(genericTracks); + var ttl = new TextTrackList(genericTracks); ttl.addTrack_({id: '100', addEventListener: noop}); ttl.addTrack_({id: '101', addEventListener: noop}); @@ -79,7 +84,7 @@ test('cannot access removed items by index', function() { }); test('new item available at old index', function() { - var ttl = new TTL(genericTracks); + var ttl = new TextTrackList(genericTracks); ttl.addTrack_({id: '100', addEventListener: noop}); equal(ttl[3].id, '100', 'id of item at index 3 is 100'); @@ -92,7 +97,7 @@ test('new item available at old index', function() { }); test('a "addtrack" event is triggered when new tracks are added', function() { - var ttl = new TTL(genericTracks), + var ttl = new TextTrackList(genericTracks), tracks = 0, adds = 0, addHandler = function(e) { @@ -117,7 +122,7 @@ test('a "addtrack" event is triggered when new tracks are added', function() { }); test('a "removetrack" event is triggered when tracks are removed', function() { - var ttl = new TTL(genericTracks), + var ttl = new TextTrackList(genericTracks), tracks = 0, rms = 0, rmHandler = function(e) { @@ -141,8 +146,8 @@ test('a "removetrack" event is triggered when tracks are removed', function() { }); test('trigger "change" event when "modechange" is fired on a track', function() { - var tt = new vjs.EventEmitter(), - ttl = new TTL([tt]), + var tt = new EventEmitter(), + ttl = new TextTrackList([tt]), changes = 0, changeHandler = function() { changes++; @@ -162,12 +167,12 @@ test('trigger "change" event when "modechange" is fired on a track', function() }); test('trigger "change" event when mode changes on a TextTracl', function() { - var tt = new vjs.TextTrack({ + var tt = new TextTrack({ player: { on: noop } }), - ttl = new TTL([tt]), + ttl = new TextTrackList([tt]), changes = 0, changeHandler = function() { changes++; diff --git a/test/unit/tracks/text-track-settings.js b/test/unit/tracks/text-track-settings.js index a675fb137e..d7bfcdb2af 100644 --- a/test/unit/tracks/text-track-settings.js +++ b/test/unit/tracks/text-track-settings.js @@ -1,16 +1,21 @@ -module('Text Track Settings', { - beforeEach: function() { - window.localStorage.clear(); - } -}); +import TextTrackSettings from '../../../src/js/tracks/text-track-settings.js'; +import TestHelpers from '../test-helpers.js'; +import * as Events from '../../../src/js/events.js'; +import window from 'global/window'; var tracks = [{ kind: 'captions', label: 'test' }]; +q.module('Text Track Settings', { + beforeEach: function() { + window.localStorage.clear(); + } +}); + test('should update settings', function() { - var player = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ tracks: tracks, persistTextTrackSettings: true }), @@ -39,12 +44,12 @@ test('should update settings', function() { equal(player.el().querySelector('.vjs-font-family select').selectedIndex, 1, 'font-family is set to new value'); equal(player.el().querySelector('.vjs-font-percent select').selectedIndex, 3, 'font-percent is set to new value'); - vjs.trigger(player.el().querySelector('.vjs-done-button'), 'click'); + Events.trigger(player.el().querySelector('.vjs-done-button'), 'click'); deepEqual(JSON.parse(window.localStorage.getItem('vjs-text-track-settings')), newSettings, 'values are saved'); }); test('should restore default settings', function() { - var player = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ tracks: tracks, persistTextTrackSettings: true }); @@ -59,9 +64,9 @@ test('should restore default settings', function() { player.el().querySelector('.vjs-font-family select').selectedIndex = 1; player.el().querySelector('.vjs-font-percent select').selectedIndex = 3; - vjs.trigger(player.el().querySelector('.vjs-done-button'), 'click'); - vjs.trigger(player.el().querySelector('.vjs-default-button'), 'click'); - vjs.trigger(player.el().querySelector('.vjs-done-button'), 'click'); + Events.trigger(player.el().querySelector('.vjs-done-button'), 'click'); + Events.trigger(player.el().querySelector('.vjs-default-button'), 'click'); + Events.trigger(player.el().querySelector('.vjs-done-button'), 'click'); deepEqual(player.textTrackSettings.getValues(), {}, 'values are defaulted'); deepEqual(window.localStorage.getItem('vjs-text-track-settings'), null, 'values are saved'); @@ -78,88 +83,88 @@ test('should restore default settings', function() { }); test('should open on click', function() { - var player = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ tracks: tracks }); - vjs.trigger(player.el().querySelector('.vjs-texttrack-settings'), 'click'); + Events.trigger(player.el().querySelector('.vjs-texttrack-settings'), 'click'); ok(!player.textTrackSettings.hasClass('vjs-hidden'), 'settings open'); }); test('should close on done click', function() { - var player = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ tracks: tracks }); - vjs.trigger(player.el().querySelector('.vjs-texttrack-settings'), 'click'); - vjs.trigger(player.el().querySelector('.vjs-done-button'), 'click'); + Events.trigger(player.el().querySelector('.vjs-texttrack-settings'), 'click'); + Events.trigger(player.el().querySelector('.vjs-done-button'), 'click'); ok(player.textTrackSettings.hasClass('vjs-hidden'), 'settings closed'); }); test('if persist option is set, restore settings on init', function() { var player, - oldRestoreSettings = vjs.TextTrackSettings.prototype.restoreSettings, + oldRestoreSettings = TextTrackSettings.prototype.restoreSettings, restore = 0; - vjs.TextTrackSettings.prototype.restoreSettings = function() { + TextTrackSettings.prototype.restoreSettings = function() { restore++; }; - player = PlayerTest.makePlayer({ + player = TestHelpers.makePlayer({ tracks: tracks, persistTextTrackSettings: true }); equal(restore, 1, 'restore was called'); - vjs.TextTrackSettings.prototype.restoreSettings = oldRestoreSettings; + TextTrackSettings.prototype.restoreSettings = oldRestoreSettings; }); test('if persist option is set, save settings when "done"', function() { - var player = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ tracks: tracks, persistTextTrackSettings: true }), - oldSaveSettings = vjs.TextTrackSettings.prototype.saveSettings, + oldSaveSettings = TextTrackSettings.prototype.saveSettings, save = 0; - vjs.TextTrackSettings.prototype.saveSettings = function() { + TextTrackSettings.prototype.saveSettings = function() { save++; }; - vjs.trigger(player.el().querySelector('.vjs-done-button'), 'click'); + Events.trigger(player.el().querySelector('.vjs-done-button'), 'click'); equal(save, 1, 'save was called'); - vjs.TextTrackSettings.prototype.saveSettings = oldSaveSettings; + TextTrackSettings.prototype.saveSettings = oldSaveSettings; }); test('do not try to restore or save settings if persist option is not set', function() { var player, - oldRestoreSettings = vjs.TextTrackSettings.prototype.restoreSettings, - oldSaveSettings = vjs.TextTrackSettings.prototype.saveSettings, + oldRestoreSettings = TextTrackSettings.prototype.restoreSettings, + oldSaveSettings = TextTrackSettings.prototype.saveSettings, save = 0, restore = 0; - vjs.TextTrackSettings.prototype.restoreSettings = function() { + TextTrackSettings.prototype.restoreSettings = function() { restore++; }; - vjs.TextTrackSettings.prototype.saveSettings = function() { + TextTrackSettings.prototype.saveSettings = function() { save++; }; - player = PlayerTest.makePlayer({ + player = TestHelpers.makePlayer({ tracks: tracks, persistTextTrackSettings: false }); equal(restore, 0, 'restore was not called'); - vjs.trigger(player.el().querySelector('.vjs-done-button'), 'click'); + Events.trigger(player.el().querySelector('.vjs-done-button'), 'click'); // saveSettings is called but does nothing equal(save, 1, 'save was not called'); - vjs.TextTrackSettings.prototype.saveSettings = oldSaveSettings; - vjs.TextTrackSettings.prototype.restoreSettings = oldRestoreSettings; + TextTrackSettings.prototype.saveSettings = oldSaveSettings; + TextTrackSettings.prototype.restoreSettings = oldRestoreSettings; }); test('should restore saved settings', function() { @@ -178,7 +183,7 @@ test('should restore saved settings', function() { window.localStorage.setItem('vjs-text-track-settings', JSON.stringify(newSettings)); - player = PlayerTest.makePlayer({ + player = TestHelpers.makePlayer({ tracks: tracks, persistTextTrackSettings: true }); @@ -202,7 +207,7 @@ test('should not restore saved settings', function() { window.localStorage.setItem('vjs-text-track-settings', JSON.stringify(newSettings)); - player = PlayerTest.makePlayer({ + player = TestHelpers.makePlayer({ tracks: tracks, persistTextTrackSettings: false }); diff --git a/test/unit/tracks/text-track.js b/test/unit/tracks/text-track.js index 2873598e2b..0a40f003ff 100644 --- a/test/unit/tracks/text-track.js +++ b/test/unit/tracks/text-track.js @@ -1,21 +1,20 @@ -(function() { -'use strict'; +import TextTrack from '../../../src/js/tracks/text-track.js'; +import window from 'global/window'; +import TestHelpers from '../test-helpers.js'; -module('Text Track'); - -var TT = vjs.TextTrack, - noop = Function.prototype, - defaultPlayer = { - textTracks: noop, - on: noop, - off: noop, - currentTime: noop - }; +var noop = Function.prototype; +var defaultPlayer = { + textTracks: noop, + on: noop, + off: noop, + currentTime: noop +}; +q.module('Text Track'); test('text-track requires a player', function() { window.throws(function() { - new TT(); + new TextTrack(); }, new Error('A player was not provided.'), 'a player is required for text track'); @@ -27,7 +26,7 @@ test('can create a TextTrack with various properties', function() { language = 'en', id = '1', mode = 'disabled', - tt = new TT({ + tt = new TextTrack({ player: defaultPlayer, kind: kind, label: label, @@ -44,7 +43,7 @@ test('can create a TextTrack with various properties', function() { }); test('defaults when items not provided', function() { - var tt = new TT({ + var tt = new TextTrack({ player: defaultPlayer }); @@ -55,7 +54,7 @@ test('defaults when items not provided', function() { }); test('kind can only be one of several options, defaults to subtitles', function() { - var tt = new TT({ + var tt = new TextTrack({ player: defaultPlayer, kind: 'foo' }); @@ -63,35 +62,35 @@ test('kind can only be one of several options, defaults to subtitles', function( equal(tt.kind, 'subtitles', 'the kind is set to subtitles, not foo'); notEqual(tt.kind, 'foo', 'the kind is set to subtitles, not foo'); - tt = new TT({ + tt = new TextTrack({ player: defaultPlayer, kind: 'subtitles' }); equal(tt.kind, 'subtitles', 'the kind is set to subtitles'); - tt = new TT({ + tt = new TextTrack({ player: defaultPlayer, kind: 'captions' }); equal(tt.kind, 'captions', 'the kind is set to captions'); - tt = new TT({ + tt = new TextTrack({ player: defaultPlayer, kind: 'descriptions' }); equal(tt.kind, 'descriptions', 'the kind is set to descriptions'); - tt = new TT({ + tt = new TextTrack({ player: defaultPlayer, kind: 'chapters' }); equal(tt.kind, 'chapters', 'the kind is set to chapters'); - tt = new TT({ + tt = new TextTrack({ player: defaultPlayer, kind: 'metadata' }); @@ -100,7 +99,7 @@ test('kind can only be one of several options, defaults to subtitles', function( }); test('mode can only be one of several options, defaults to disabled', function() { - var tt = new TT({ + var tt = new TextTrack({ player: defaultPlayer, mode: 'foo' }); @@ -108,21 +107,21 @@ test('mode can only be one of several options, defaults to disabled', function() equal(tt.mode, 'disabled', 'the mode is set to disabled, not foo'); notEqual(tt.mode, 'foo', 'the mode is set to disabld, not foo'); - tt = new TT({ + tt = new TextTrack({ player: defaultPlayer, mode: 'disabled' }); equal(tt.mode, 'disabled', 'the mode is set to disabled'); - tt = new TT({ + tt = new TextTrack({ player: defaultPlayer, mode: 'hidden' }); equal(tt.mode, 'hidden', 'the mode is set to hidden'); - tt = new TT({ + tt = new TextTrack({ player: defaultPlayer, mode: 'showing' }); @@ -136,7 +135,7 @@ test('kind, label, language, id, cue, and activeCues are read only', function() language = 'en', id = '1', mode = 'disabled', - tt = new TT({ + tt = new TextTrack({ player: defaultPlayer, kind: kind, label: label, @@ -161,7 +160,7 @@ test('kind, label, language, id, cue, and activeCues are read only', function() }); test('mode can only be set to a few options', function() { - var tt = new TT({ + var tt = new TextTrack({ player: defaultPlayer }); @@ -186,7 +185,7 @@ test('mode can only be set to a few options', function() { }); test('cues and activeCues return a TextTrackCueList', function() { - var tt = new TT({ + var tt = new TextTrack({ player: defaultPlayer }); @@ -195,7 +194,7 @@ test('cues and activeCues return a TextTrackCueList', function() { }); test('cues can be added and removed from a TextTrack', function() { - var tt = new TT({ + var tt = new TextTrack({ player: defaultPlayer }), cues; @@ -221,10 +220,10 @@ test('cues can be added and removed from a TextTrack', function() { }); test('fires cuechange when cues become active and inactive', function() { - var player = PlayerTest.makePlayer(), + var player = TestHelpers.makePlayer(), changes = 0, cuechangeHandler, - tt = new TT({ + tt = new TextTrack({ player: player, mode: 'showing' }); @@ -258,5 +257,3 @@ test('fires cuechange when cues become active and inactive', function() { equal(changes, 4, 'a cuechange event trigger addEventListener and oncuechange'); }); - -})(); diff --git a/test/unit/tracks/tracks.js b/test/unit/tracks/tracks.js index d4e0425ede..60ae46112e 100644 --- a/test/unit/tracks/tracks.js +++ b/test/unit/tracks/tracks.js @@ -1,11 +1,22 @@ -module('Tracks'); +import { CaptionsButton } from '../../../src/js/tracks/text-track-controls.js'; +import { SubtitlesButton } from '../../../src/js/tracks/text-track-controls.js'; +import { ChaptersButton } from '../../../src/js/tracks/text-track-controls.js'; +import { TextTrackDisplay } from '../../../src/js/tracks/text-track-controls.js'; +import Html5 from '../../../src/js/media/html5.js'; +import Flash from '../../../src/js/media/flash.js'; +import MediaTechController from '../../../src/js/media/media.js'; +import Component from '../../../src/js/component.js'; -var ChaptersButton = vjs.ChaptersButton; +import * as Lib from '../../../src/js/lib.js'; +import TestHelpers from '../test-helpers.js'; +import document from 'global/document'; + +q.module('Tracks'); test('should place title list item into ul', function() { var player, chaptersButton; - player = PlayerTest.makePlayer(); + player = TestHelpers.makePlayer(); chaptersButton = new ChaptersButton(player); @@ -21,7 +32,7 @@ test('Player track methods call the tech', function() { var player, calls = 0; - player = PlayerTest.makePlayer(); + player = TestHelpers.makePlayer(); player.tech.textTracks = function() { calls++; @@ -38,7 +49,7 @@ test('Player track methods call the tech', function() { test('TextTrackDisplay initializes tracks on player ready', function() { var calls = 0, - ttd = new vjs.TextTrackDisplay({ + ttd = new TextTrackDisplay({ on: Function.prototype, addTextTracks: function() { calls--; @@ -55,27 +66,27 @@ test('TextTrackDisplay initializes tracks on player ready', function() { }); test('html5 tech supports native text tracks if the video supports it', function() { - var oldTestVid = vjs.TEST_VID; + var oldTestVid = Lib.TEST_VID; - vjs.TEST_VID = { + Lib.TEST_VID = { textTracks: [] }; - ok(vjs.Html5.supportsNativeTextTracks(), 'if textTracks are available on video element, native text tracks are supported'); + ok(Html5.supportsNativeTextTracks(), 'if textTracks are available on video element, native text tracks are supported'); - vjs.TEST_VID = oldTestVid; + Lib.TEST_VID = oldTestVid; }); test('listen to remove and add track events in native text tracks', function() { - var oldTestVid = vjs.TEST_VID, + var oldTestVid = Lib.TEST_VID, player, options, oldTextTracks, events = {}, html; - oldTextTracks = vjs.Html5.prototype.textTracks; - vjs.Html5.prototype.textTracks = function() { + oldTextTracks = Html5.prototype.textTracks; + Html5.prototype.textTracks = function() { return { addEventListener: function(type, handler) { events[type] = true; @@ -83,7 +94,7 @@ test('listen to remove and add track events in native text tracks', function() { }; }; - vjs.TEST_VID = { + Lib.TEST_VID = { textTracks: [] }; @@ -106,13 +117,13 @@ test('listen to remove and add track events in native text tracks', function() { player.player_ = player; player.options_ = options = {}; - html = new vjs.Html5(player, options); + html = new Html5(player, options); ok(events['removetrack'], 'removetrack listener was added'); ok(events['addtrack'], 'addtrack listener was added'); - vjs.TEST_VID = oldTestVid; - vjs.Html5.prototype.textTracks = oldTextTracks; + Lib.TEST_VID = oldTestVid; + Html5.prototype.textTracks = oldTextTracks; }); test('update texttrack buttons on removetrack or addtrack', function() { @@ -127,25 +138,25 @@ test('update texttrack buttons on removetrack or addtrack', function() { oldSubsUpdate, oldChaptersUpdate; - oldCaptionsUpdate = vjs.CaptionsButton.prototype.update; - oldSubsUpdate = vjs.SubtitlesButton.prototype.update; - oldChaptersUpdate = vjs.ChaptersButton.prototype.update; - vjs.CaptionsButton.prototype.update = function() { + oldCaptionsUpdate = CaptionsButton.prototype.update; + oldSubsUpdate = SubtitlesButton.prototype.update; + oldChaptersUpdate = ChaptersButton.prototype.update; + CaptionsButton.prototype.update = function() { update++; oldCaptionsUpdate.call(this); }; - vjs.SubtitlesButton.prototype.update = function() { + SubtitlesButton.prototype.update = function() { update++; oldSubsUpdate.call(this); }; - vjs.ChaptersButton.prototype.update = function() { + ChaptersButton.prototype.update = function() { update++; oldChaptersUpdate.call(this); }; - vjs.MediaTechController.prototype['featuresNativeTextTracks'] = true; - oldTextTracks = videojs.MediaTechController.prototype.textTracks; - vjs.MediaTechController.prototype.textTracks = function() { + MediaTechController.prototype['featuresNativeTextTracks'] = true; + oldTextTracks = MediaTechController.prototype.textTracks; + MediaTechController.prototype.textTracks = function() { return { length: 0, addEventListener: function(type, handler) { @@ -171,7 +182,7 @@ test('update texttrack buttons on removetrack or addtrack', function() { track.src = 'es.vtt'; tag.appendChild(track); - player = PlayerTest.makePlayer({}, tag); + player = TestHelpers.makePlayer({}, tag); player.player_ = player; @@ -189,17 +200,17 @@ test('update texttrack buttons on removetrack or addtrack', function() { equal(update, 9, 'update was called on the three buttons for remove track'); - vjs.MediaTechController.prototype.textTracks = oldTextTracks; - vjs.MediaTechController.prototype['featuresNativeTextTracks'] = false; - vjs.CaptionsButton.prototype.update = oldCaptionsUpdate; - vjs.SubtitlesButton.prototype.update = oldSubsUpdate; - vjs.ChaptersButton.prototype.update = oldChaptersUpdate; + MediaTechController.prototype.textTracks = oldTextTracks; + MediaTechController.prototype['featuresNativeTextTracks'] = false; + CaptionsButton.prototype.update = oldCaptionsUpdate; + SubtitlesButton.prototype.update = oldSubsUpdate; + ChaptersButton.prototype.update = oldChaptersUpdate; }); test('if native text tracks are not supported, create a texttrackdisplay', function() { - var oldTestVid = vjs.TEST_VID, - oldIsFirefox = vjs.IS_FIREFOX, - oldTextTrackDisplay = window['videojs']['TextTrackDisplay'], + var oldTestVid = Lib.TEST_VID, + oldIsFirefox = Lib.IS_FIREFOX, + oldTextTrackDisplay = Component.getComponent('TextTrackDisplay'), called = false, player, tag, @@ -221,29 +232,29 @@ test('if native text tracks are not supported, create a texttrackdisplay', funct track.src = 'es.vtt'; tag.appendChild(track); - vjs.TEST_VID = { + Lib.TEST_VID = { textTracks: [] }; - vjs.IS_FIREFOX = true; - window['videojs']['TextTrackDisplay'] = function() { + Lib.IS_FIREFOX = true; + Component.registerComponent('TextTrackDisplay', function() { called = true; - }; + }); - player = PlayerTest.makePlayer({}, tag); + player = TestHelpers.makePlayer({}, tag); ok(called, 'text track display was created'); - vjs.TEST_VID = oldTestVid; - vjs.IS_FIREFOX = oldIsFirefox; - window['videojs']['TextTrackDisplay'] = oldTextTrackDisplay; + Lib.TEST_VID = oldTestVid; + Lib.IS_FIREFOX = oldIsFirefox; + Component.registerComponent('TextTrackDisplay', oldTextTrackDisplay); }); test('Player track methods call the tech', function() { var player, calls = 0; - player = PlayerTest.makePlayer(); + player = TestHelpers.makePlayer(); player.tech.textTracks = function() { calls++; @@ -259,37 +270,37 @@ test('Player track methods call the tech', function() { }); test('html5 tech supports native text tracks if the video supports it, unless mode is a number', function() { - var oldTestVid = vjs.TEST_VID; + var oldTestVid = Lib.TEST_VID; - vjs.TEST_VID = { + Lib.TEST_VID = { textTracks: [{ mode: 0 }] }; - ok(!vjs.Html5.supportsNativeTextTracks(), 'native text tracks are not supported if mode is a number'); + ok(!Html5.supportsNativeTextTracks(), 'native text tracks are not supported if mode is a number'); - vjs.TEST_VID = oldTestVid; + Lib.TEST_VID = oldTestVid; }); test('html5 tech supports native text tracks if the video supports it, unless it is firefox', function() { - var oldTestVid = vjs.TEST_VID, - oldIsFirefox = vjs.IS_FIREFOX; + var oldTestVid = Lib.TEST_VID, + oldIsFirefox = Lib.IS_FIREFOX; - vjs.TEST_VID = { + Lib.TEST_VID = { textTracks: [] }; - vjs.IS_FIREFOX = true; + Lib.IS_FIREFOX = true; - ok(!vjs.Html5.supportsNativeTextTracks(), 'if textTracks are available on video element, native text tracks are supported'); + ok(!Html5.supportsNativeTextTracks(), 'if textTracks are available on video element, native text tracks are supported'); - vjs.TEST_VID = oldTestVid; - vjs.IS_FIREFOX = oldIsFirefox; + Lib.TEST_VID = oldTestVid; + Lib.IS_FIREFOX = oldIsFirefox; }); test('when switching techs, we should not get a new text track', function() { - var player = PlayerTest.makePlayer({ + var player = TestHelpers.makePlayer({ html5: { nativeTextTracks: false } diff --git a/test/unit/util.js b/test/unit/util.js index 67534bc67a..bc2f5eee92 100644 --- a/test/unit/util.js +++ b/test/unit/util.js @@ -1,6 +1,6 @@ -module('Util'); +import * as Util from '../../src/js/util.js'; -var Util = vjs.Util; +q.module('Util'); test('should merge options objects', function(){ var ob1, ob2, ob3;