diff --git a/package.json b/package.json index 72b11b9b0f..3a5d7cf6d7 100644 --- a/package.json +++ b/package.json @@ -13,17 +13,19 @@ "homepage": "http://videojs.com", "author": "Steve Heffernan", "scripts": { - "test": "grunt test" + "test": "grunt test", + "build": "browserify -d --standalone 'videojs' . -o bundle.js" }, "repository": { "type": "git", "url": "https://github.com/videojs/video.js.git" }, - "main": "./dist/video-js/video.js", + "main": "./src/js/video.js", "dependencies": { "videojs-swf": "4.4.2" }, "devDependencies": { + "browserify": "^4.2.1", "calcdeps": "~0.1.7", "chg": "~0.1.8", "contribflow": "~0.2.0", diff --git a/src/js/big-play-button.js b/src/js/big-play-button.js index 08d382c972..e180833ecd 100644 --- a/src/js/big-play-button.js +++ b/src/js/big-play-button.js @@ -1,3 +1,7 @@ +var BigPlayButton, Button; + +Button = require('./button.js'); + /* Big Play Button ================================================================================ */ /** @@ -8,16 +12,18 @@ * @class * @constructor */ -vjs.BigPlayButton = vjs.Button.extend(); +BigPlayButton = Button.extend(); -vjs.BigPlayButton.prototype.createEl = function(){ - return vjs.Button.prototype.createEl.call(this, 'div', { +BigPlayButton.prototype.createEl = function(){ + return Button.prototype.createEl.call(this, 'div', { className: 'vjs-big-play-button', innerHTML: '', 'aria-label': 'play video' }); }; -vjs.BigPlayButton.prototype.onClick = function(){ +BigPlayButton.prototype.onClick = function(){ this.player_.play(); }; + +module.exports = BigPlayButton; diff --git a/src/js/button.js b/src/js/button.js index 36d9c3ee04..0b349a06b9 100644 --- a/src/js/button.js +++ b/src/js/button.js @@ -1,3 +1,9 @@ +var Button, Component, vjslib, vjsevents; + +Component = require('./component.js'); +vjslib = require('./lib.js'); +vjsevents = require('./events.js'); + /* Button - Base class for all buttons ================================================================================ */ /** @@ -7,13 +13,13 @@ * @class * @constructor */ -vjs.Button = vjs.Component.extend({ +Button = Component.extend({ /** * @constructor * @inheritDoc */ init: function(player, options){ - vjs.Component.call(this, player, options); + Component.call(this, player, options); this.emitTapEvents(); @@ -24,26 +30,26 @@ vjs.Button = vjs.Component.extend({ } }); -vjs.Button.prototype.createEl = function(type, props){ +Button.prototype.createEl = function(type, props){ var el; // Add standard Aria and Tabindex info - props = vjs.obj.merge({ + props = vjslib.obj.merge({ className: this.buildCSSClass(), 'role': 'button', 'aria-live': 'polite', // let the screen reader user know that the text of the button may change tabIndex: 0 }, props); - el = vjs.Component.prototype.createEl.call(this, type, props); + el = Component.prototype.createEl.call(this, type, props); // if innerHTML hasn't been overridden (bigPlayButton), add content elements if (!props.innerHTML) { - this.contentEl_ = vjs.createEl('div', { + this.contentEl_ = vjslib.createEl('div', { className: 'vjs-control-content' }); - this.controlText_ = vjs.createEl('span', { + this.controlText_ = vjslib.createEl('span', { className: 'vjs-control-text', innerHTML: this.buttonText || 'Need Text' }); @@ -55,21 +61,21 @@ vjs.Button.prototype.createEl = function(type, props){ return el; }; -vjs.Button.prototype.buildCSSClass = function(){ +Button.prototype.buildCSSClass = function(){ // TODO: Change vjs-control to vjs-button? - return 'vjs-control ' + vjs.Component.prototype.buildCSSClass.call(this); + return 'vjs-control ' + Component.prototype.buildCSSClass.call(this); }; // Click - Override with specific functionality for button -vjs.Button.prototype.onClick = function(){}; +Button.prototype.onClick = function(){}; // Focus - Add keyboard functionality to element -vjs.Button.prototype.onFocus = function(){ - vjs.on(document, 'keyup', vjs.bind(this, this.onKeyPress)); +Button.prototype.onFocus = function(){ + vjsevents.on(document, 'keyup', vjslib.bind(this, this.onKeyPress)); }; // KeyPress (document level) - Trigger click when keys are pressed -vjs.Button.prototype.onKeyPress = function(event){ +Button.prototype.onKeyPress = function(event){ // Check for space bar (32) or enter (13) keys if (event.which == 32 || event.which == 13) { event.preventDefault(); @@ -78,6 +84,8 @@ vjs.Button.prototype.onKeyPress = function(event){ }; // Blur - Remove keyboard triggers -vjs.Button.prototype.onBlur = function(){ - vjs.off(document, 'keyup', vjs.bind(this, this.onKeyPress)); +Button.prototype.onBlur = function(){ + vjsevents.off(document, 'keyup', vjslib.bind(this, this.onKeyPress)); }; + +module.exports = Button; diff --git a/src/js/cdn.js b/src/js/cdn.js index 3b5fa80e57..3029cf88b1 100644 --- a/src/js/cdn.js +++ b/src/js/cdn.js @@ -1,3 +1,5 @@ +module.exports = function sendGAEvent() { + /** * Google Analytics tracking pixel for the freely hosted version of Video.js * at vjs.zencdn.net. We'll use this data to develop a support matrix of @@ -53,4 +55,6 @@ // Custom Var: vjsv is the variable name and 1.0.0 is the VJS version +'&utme=8(vjsv)9(v0.0.0)' ; -})(new Image(),window,navigator,encodeURIComponent); \ No newline at end of file +})(new Image(),window,navigator,encodeURIComponent); + +} diff --git a/src/js/component.js b/src/js/component.js index b6ff71bd89..8ae925eff7 100644 --- a/src/js/component.js +++ b/src/js/component.js @@ -1,3 +1,10 @@ +var Component, CoreObject, vjslib, vjsutil, vjsevents; + +CoreObject = require('./core-object.js'); +vjslib = require('./lib.js'); +vjsutil = require('./util.js') +vjsevents = require('./events.js'); + /** * @fileoverview Player Component - Base class for all UI objects * @@ -32,7 +39,7 @@ * @constructor * @extends vjs.CoreObject */ -vjs.Component = vjs.CoreObject.extend({ +Component = CoreObject.extend({ /** * the constructor function for the class * @@ -42,13 +49,13 @@ vjs.Component = vjs.CoreObject.extend({ this.player_ = player; // Make a copy of prototype.options_ to protect against overriding global defaults - this.options_ = vjs.obj.copy(this.options_); + this.options_ = vjslib.obj.copy(this.options_); // Updated options with supplied options options = this.options(options); // Get ID from options, element, or create using player ID and unique ID - this.id_ = options['id'] || ((options['el'] && options['el']['id']) ? options['el']['id'] : player.id() + '_component_' + vjs.guid++ ); + this.id_ = options['id'] || ((options['el'] && options['el']['id']) ? options['el']['id'] : player.id() + '_component_' + vjslib.guid++ ); this.name_ = options['name'] || null; @@ -75,7 +82,7 @@ vjs.Component = vjs.CoreObject.extend({ /** * Dispose of the component and all child components */ -vjs.Component.prototype.dispose = function(){ +Component.prototype.dispose = function(){ this.trigger({ type: 'dispose', 'bubbles': false }); // Dispose all children. @@ -100,7 +107,7 @@ vjs.Component.prototype.dispose = function(){ this.el_.parentNode.removeChild(this.el_); } - vjs.removeData(this.el_); + vjslib.removeData(this.el_); this.el_ = null; }; @@ -110,14 +117,14 @@ vjs.Component.prototype.dispose = function(){ * @type {vjs.Player} * @private */ -vjs.Component.prototype.player_ = true; +Component.prototype.player_ = true; /** * Return the component's player * * @return {vjs.Player} */ -vjs.Component.prototype.player = function(){ +Component.prototype.player = function(){ return this.player_; }; @@ -127,7 +134,7 @@ vjs.Component.prototype.player = function(){ * @type {Object} * @private */ -vjs.Component.prototype.options_; +Component.prototype.options_; /** * Deep merge of options objects @@ -170,10 +177,10 @@ vjs.Component.prototype.options_; * @param {Object} obj Object of new option values * @return {Object} A NEW object of this.options_ and obj merged */ -vjs.Component.prototype.options = function(obj){ +Component.prototype.options = function(obj){ if (obj === undefined) return this.options_; - return this.options_ = vjs.util.mergeOptions(this.options_, obj); + return this.options_ = vjsutil.mergeOptions(this.options_, obj); }; /** @@ -182,7 +189,7 @@ vjs.Component.prototype.options = function(obj){ * @type {Element} * @private */ -vjs.Component.prototype.el_; +Component.prototype.el_; /** * Create the component's DOM element @@ -191,8 +198,8 @@ vjs.Component.prototype.el_; * @param {Object=} attributes An object of element attributes that should be set on the element * @return {Element} */ -vjs.Component.prototype.createEl = function(tagName, attributes){ - return vjs.createEl(tagName, attributes); +Component.prototype.createEl = function(tagName, attributes){ + return vjslib.createEl(tagName, attributes); }; /** @@ -202,7 +209,7 @@ vjs.Component.prototype.createEl = function(tagName, attributes){ * * @return {Element} */ -vjs.Component.prototype.el = function(){ +Component.prototype.el = function(){ return this.el_; }; @@ -213,7 +220,7 @@ vjs.Component.prototype.el = function(){ * @type {Element} * @private */ -vjs.Component.prototype.contentEl_; +Component.prototype.contentEl_; /** * Return the component's DOM element for embedding content. @@ -221,7 +228,7 @@ vjs.Component.prototype.contentEl_; * * @return {Element} */ -vjs.Component.prototype.contentEl = function(){ +Component.prototype.contentEl = function(){ return this.contentEl_ || this.el_; }; @@ -231,7 +238,7 @@ vjs.Component.prototype.contentEl = function(){ * @type {String} * @private */ -vjs.Component.prototype.id_; +Component.prototype.id_; /** * Get the component's ID @@ -240,7 +247,7 @@ vjs.Component.prototype.id_; * * @return {String} */ -vjs.Component.prototype.id = function(){ +Component.prototype.id = function(){ return this.id_; }; @@ -250,7 +257,7 @@ vjs.Component.prototype.id = function(){ * @type {String} * @private */ -vjs.Component.prototype.name_; +Component.prototype.name_; /** * Get the component's name. The name is often used to reference the component. @@ -259,7 +266,7 @@ vjs.Component.prototype.name_; * * @return {String} */ -vjs.Component.prototype.name = function(){ +Component.prototype.name = function(){ return this.name_; }; @@ -269,7 +276,7 @@ vjs.Component.prototype.name = function(){ * @type {Array} * @private */ -vjs.Component.prototype.children_; +Component.prototype.children_; /** * Get an array of all child components @@ -278,7 +285,7 @@ vjs.Component.prototype.children_; * * @return {Array} The children */ -vjs.Component.prototype.children = function(){ +Component.prototype.children = function(){ return this.children_; }; @@ -288,14 +295,14 @@ vjs.Component.prototype.children = function(){ * @type {Object} * @private */ -vjs.Component.prototype.childIndex_; +Component.prototype.childIndex_; /** * Returns a child component with the provided ID * * @return {vjs.Component} */ -vjs.Component.prototype.getChildById = function(id){ +Component.prototype.getChildById = function(id){ return this.childIndex_[id]; }; @@ -305,14 +312,14 @@ vjs.Component.prototype.getChildById = function(id){ * @type {Object} * @private */ -vjs.Component.prototype.childNameIndex_; +Component.prototype.childNameIndex_; /** * Returns a child component with the provided name * * @return {vjs.Component} */ -vjs.Component.prototype.getChild = function(name){ +Component.prototype.getChild = function(name){ return this.childNameIndex_[name]; }; @@ -344,8 +351,10 @@ vjs.Component.prototype.getChild = function(name){ * @return {vjs.Component} The child component (created by this process if a string was used) * @suppress {accessControls|checkRegExp|checkTypes|checkVars|const|constantProperty|deprecated|duplicate|es5Strict|fileoverviewTags|globalThis|invalidCasts|missingProperties|nonStandardJsDocs|strictModuleDepCheck|undefinedNames|undefinedVars|unknownDefines|uselessCode|visibility} */ -vjs.Component.prototype.addChild = function(child, options){ - var component, componentClass, componentName, componentId; +Component.prototype.addChild = function(child, options){ + var component, componentClass, componentName, componentId, components; + + components = require('./components.js'); // If string, create new component with options if (typeof child === 'string') { @@ -356,7 +365,7 @@ vjs.Component.prototype.addChild = function(child, options){ options = options || {}; // Assume name of set is a lowercased name of the UI Class (PlayButton, etc.) - componentClass = options['componentClass'] || vjs.capitalize(componentName); + componentClass = options['componentClass'] || vjslib.capitalize(componentName); // Set name through options options['name'] = componentName; @@ -365,7 +374,7 @@ vjs.Component.prototype.addChild = function(child, options){ // If there's no .player_, this is a player // 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. - component = new window['videojs'][componentClass](this.player_ || this, options); + component = new components[componentClass](this.player_ || this, options); // child is a component instance } else { @@ -402,7 +411,7 @@ vjs.Component.prototype.addChild = function(child, options){ * * @param {vjs.Component} component Component to remove */ -vjs.Component.prototype.removeChild = function(component){ +Component.prototype.removeChild = function(component){ if (typeof component === 'string') { component = this.getChild(component); } @@ -463,7 +472,7 @@ vjs.Component.prototype.removeChild = function(component){ * }); * */ -vjs.Component.prototype.initChildren = function(){ +Component.prototype.initChildren = function(){ var parent, children, child, name, opts; parent = this; @@ -471,7 +480,7 @@ vjs.Component.prototype.initChildren = function(){ if (children) { // Allow for an array of children details to passed in the options - if (vjs.obj.isArray(children)) { + if (vjslib.obj.isArray(children)) { for (var i = 0; i < children.length; i++) { child = children[i]; @@ -486,7 +495,7 @@ vjs.Component.prototype.initChildren = function(){ parent[name] = parent.addChild(name, opts); } } else { - vjs.obj.each(children, function(name, opts){ + vjslib.obj.each(children, function(name, opts){ // Allow for disabling default components // e.g. vjs.options['children']['posterImage'] = false if (opts === false) return; @@ -503,7 +512,7 @@ vjs.Component.prototype.initChildren = function(){ * * @return {String} The constructed class name */ -vjs.Component.prototype.buildCSSClass = function(){ +Component.prototype.buildCSSClass = function(){ // Child classes can include a function that does: // return 'CLASS NAME' + this._super(); return ''; @@ -528,8 +537,8 @@ vjs.Component.prototype.buildCSSClass = function(){ * @param {Function} fn The event listener * @return {vjs.Component} self */ -vjs.Component.prototype.on = function(type, fn){ - vjs.on(this.el_, type, vjs.bind(this, fn)); +Component.prototype.on = function(type, fn){ + vjsevents.on(this.el_, type, vjslib.bind(this, fn)); return this; }; @@ -542,8 +551,8 @@ vjs.Component.prototype.on = function(type, fn){ * @param {Function=} fn Event listener. Without fn it will remove all listeners for a type. * @return {vjs.Component} */ -vjs.Component.prototype.off = function(type, fn){ - vjs.off(this.el_, type, fn); +Component.prototype.off = function(type, fn){ + vjsevents.off(this.el_, type, fn); return this; }; @@ -554,8 +563,8 @@ vjs.Component.prototype.off = function(type, fn){ * @param {Function} fn Event listener * @return {vjs.Component} */ -vjs.Component.prototype.one = function(type, fn) { - vjs.one(this.el_, type, vjs.bind(this, fn)); +Component.prototype.one = function(type, fn) { + vjsevents.one(this.el_, type, vjslib.bind(this, fn)); return this; }; @@ -568,8 +577,8 @@ vjs.Component.prototype.one = function(type, fn) { * @param {Event|Object} event The event object to be passed to the listener * @return {vjs.Component} self */ -vjs.Component.prototype.trigger = function(type, event){ - vjs.trigger(this.el_, type, event); +Component.prototype.trigger = function(type, event){ + vjsevents.trigger(this.el_, type, event); return this; }; @@ -582,7 +591,7 @@ vjs.Component.prototype.trigger = function(type, event){ * @private * @type {Boolean} */ -vjs.Component.prototype.isReady_; +Component.prototype.isReady_; /** * Trigger ready as soon as initialization is finished @@ -594,7 +603,7 @@ vjs.Component.prototype.isReady_; * @type {Boolean} * @private */ -vjs.Component.prototype.isReadyOnInitFinish_ = true; +Component.prototype.isReadyOnInitFinish_ = true; /** * List of ready listeners @@ -602,7 +611,7 @@ vjs.Component.prototype.isReadyOnInitFinish_ = true; * @type {Array} * @private */ -vjs.Component.prototype.readyQueue_; +Component.prototype.readyQueue_; /** * Bind a listener to the component's ready state @@ -613,7 +622,7 @@ vjs.Component.prototype.readyQueue_; * @param {Function} fn Ready listener * @return {vjs.Component} */ -vjs.Component.prototype.ready = function(fn){ +Component.prototype.ready = function(fn){ if (fn) { if (this.isReady_) { fn.call(this); @@ -632,7 +641,7 @@ vjs.Component.prototype.ready = function(fn){ * * @return {vjs.Component} */ -vjs.Component.prototype.triggerReady = function(){ +Component.prototype.triggerReady = function(){ this.isReady_ = true; var readyQueue = this.readyQueue_; @@ -660,8 +669,8 @@ vjs.Component.prototype.triggerReady = function(){ * @param {String} classToAdd Classname to add * @return {vjs.Component} */ -vjs.Component.prototype.addClass = function(classToAdd){ - vjs.addClass(this.el_, classToAdd); +Component.prototype.addClass = function(classToAdd){ + vjslib.addClass(this.el_, classToAdd); return this; }; @@ -671,8 +680,8 @@ vjs.Component.prototype.addClass = function(classToAdd){ * @param {String} classToRemove Classname to remove * @return {vjs.Component} */ -vjs.Component.prototype.removeClass = function(classToRemove){ - vjs.removeClass(this.el_, classToRemove); +Component.prototype.removeClass = function(classToRemove){ + vjslib.removeClass(this.el_, classToRemove); return this; }; @@ -681,7 +690,7 @@ vjs.Component.prototype.removeClass = function(classToRemove){ * * @return {vjs.Component} */ -vjs.Component.prototype.show = function(){ +Component.prototype.show = function(){ this.el_.style.display = 'block'; return this; }; @@ -691,7 +700,7 @@ vjs.Component.prototype.show = function(){ * * @return {vjs.Component} */ -vjs.Component.prototype.hide = function(){ +Component.prototype.hide = function(){ this.el_.style.display = 'none'; return this; }; @@ -703,7 +712,7 @@ vjs.Component.prototype.hide = function(){ * @return {vjs.Component} * @private */ -vjs.Component.prototype.lockShowing = function(){ +Component.prototype.lockShowing = function(){ this.addClass('vjs-lock-showing'); return this; }; @@ -715,7 +724,7 @@ vjs.Component.prototype.lockShowing = function(){ * @return {vjs.Component} * @private */ -vjs.Component.prototype.unlockShowing = function(){ +Component.prototype.unlockShowing = function(){ this.removeClass('vjs-lock-showing'); return this; }; @@ -726,7 +735,7 @@ vjs.Component.prototype.unlockShowing = function(){ * Currently private because we're movign towards more css-based states. * @private */ -vjs.Component.prototype.disable = function(){ +Component.prototype.disable = function(){ this.hide(); this.show = function(){}; }; @@ -744,7 +753,7 @@ vjs.Component.prototype.disable = function(){ * @return {vjs.Component} This component, when setting the width * @return {Number|String} The width, when getting */ -vjs.Component.prototype.width = function(num, skipListeners){ +Component.prototype.width = function(num, skipListeners){ return this.dimension('width', num, skipListeners); }; @@ -761,7 +770,7 @@ vjs.Component.prototype.width = function(num, skipListeners){ * @return {vjs.Component} This component, when setting the height * @return {Number|String} The height, when getting */ -vjs.Component.prototype.height = function(num, skipListeners){ +Component.prototype.height = function(num, skipListeners){ return this.dimension('height', num, skipListeners); }; @@ -772,7 +781,7 @@ vjs.Component.prototype.height = function(num, skipListeners){ * @param {Number|String} height * @return {vjs.Component} The component */ -vjs.Component.prototype.dimensions = function(width, height){ +Component.prototype.dimensions = function(width, height){ // Skip resize listeners on width for optimization return this.width(width, true).height(height); }; @@ -795,7 +804,7 @@ vjs.Component.prototype.dimensions = function(width, height){ * @return {Number|String} The dimension if nothing was set * @private */ -vjs.Component.prototype.dimension = function(widthOrHeight, num, skipListeners){ +Component.prototype.dimension = function(widthOrHeight, num, skipListeners){ if (num !== undefined) { // Check if using css width/height (% or px) and adjust @@ -830,7 +839,7 @@ vjs.Component.prototype.dimension = function(widthOrHeight, num, skipListeners){ // TODO: handle display:none and no dimension style using px } else { - return parseInt(this.el_['offset'+vjs.capitalize(widthOrHeight)], 10); + return parseInt(this.el_['offset'+vjslib.capitalize(widthOrHeight)], 10); // ComputedStyle version. // Only difference is if the element is hidden it will return @@ -851,7 +860,7 @@ vjs.Component.prototype.dimension = function(widthOrHeight, num, skipListeners){ * Fired when the width and/or height of the component changes * @event resize */ -vjs.Component.prototype.onResize; +Component.prototype.onResize; /** * Emit 'tap' events when touch events are supported @@ -863,7 +872,7 @@ vjs.Component.prototype.onResize; * overhead is especially bad. * @private */ -vjs.Component.prototype.emitTapEvents = function(){ +Component.prototype.emitTapEvents = function(){ var touchStart, firstTouch, touchTime, couldBeTap, noTap, xdiff, ydiff, touchDistance, tapMovementThreshold; @@ -951,11 +960,11 @@ vjs.Component.prototype.emitTapEvents = function(){ * whenever touch events happen, and this can be turned off by components that * want touch events to act differently. */ -vjs.Component.prototype.enableTouchActivity = function() { +Component.prototype.enableTouchActivity = function() { var report, touchHolding, touchEnd; // listener for reporting that the user is active - report = vjs.bind(this.player(), this.player().reportUserActivity); + report = vjslib.bind(this.player(), this.player().reportUserActivity); this.on('touchstart', function() { report(); @@ -978,3 +987,4 @@ vjs.Component.prototype.enableTouchActivity = function() { this.on('touchcancel', touchEnd); }; +module.exports = Component; diff --git a/src/js/components.js b/src/js/components.js new file mode 100644 index 0000000000..c1098de6ad --- /dev/null +++ b/src/js/components.js @@ -0,0 +1,74 @@ +var menu, slider, tracks, progress, timedisplay, volume; + +menu = require('./menu.js'); +slider = require('./slider.js'); +tracks = require('./tracks.js'); +progress = require('./control-bar/progress-control.js'); +timedisplay = require('./control-bar/time-display.js'); +volume = require('./control-bar/volume-control.js'); + +module.exports = { + Component: require('./component.js'), + Button: require('./button.js'), + + Html5: require('./media/html5.js'), + Flash: require('./media/flash.js'), + MediaLoader: require('./media/loader.js'), + MediaTechController: require('./media/media.js'), + + BigPlayButton: require('./big-play-button.js'), + + ErrorDisplay: require('./error-display.js'), + MediaError: require('./media-error.js'), + + LoadingSpinner: require('./loading-spinner.js'), + + Menu: menu.Menu, + MenuItem: menu.MenuItem, + MenuButton: menu.MenuButton, + + PosterImage: require('./poster.js'), + + Slider: slider.Slider, + SliderHandle: slider.SliderHandle, + + TextTrack: tracks.TextTrack, + CaptionsTrack: tracks.CaptionsTrack, + SubtitlesTrack: tracks.SubtitlesTrack, + ChaptersTrack: tracks.ChaptersTrack, + + TextTrackDisplay: tracks.TextTrackDisplay, + TextTrackMenuItem: tracks.TextTrackMenuItem, + OffTextTrackMenuItem: tracks.OffTextTrackMenuItem, + ChaptersTrackMenuItem: tracks.ChaptersTrackMenuItem, + + TextTrackButton: tracks.TextTrackButton, + CaptionsButton: tracks.CaptionsButton, + SubtitlesButton: tracks.SubtitlesButton, + ChaptersButton: tracks.ChaptersButton, + + // CONTROL BAR ITEMS + ControlBar: require('./control-bar/control-bar.js'), + FullscreenToggle: require('./control-bar/fullscreen-toggle.js'), + LiveDisplay: require('./control-bar/live-display.js'), + MuteToggle: require('./control-bar/mute-toggle.js'), + PlayToggle: require('./control-bar/play-toggle.js'), + PlaybackRateMenuButton: require('./control-bar/playback-rate-menu-button.js'), + + ProgressControl: progress.ProgressControl, + SeekBar: progress.SeekBar, + LoadProgressBar: progress.LoadProgressBar, + PlayProgressBar: progress.PlayProgressBar, + SeekHandle: progress.SeekHandle, + + CurrentTimeDisplay: timedisplay.CurrentTimeDisplay, + DurationDisplay: timedisplay.DurationDisplay, + TimeDivider: timedisplay.TimeDivider, + RemainingTimeDisplay: timedisplay.RemainingTimeDisplay, + + VolumeControl: volume.VolumeControl, + VolumeBar: volume.VolumeBar, + VolumeLevel: volume.VolumeLevel, + VolumeHandle: volume.VolumeHandle, + VolumeMenuButton: require('./control-bar/volume-menu-button.js') +} diff --git a/src/js/control-bar/control-bar.js b/src/js/control-bar/control-bar.js index 3db1031319..7a15159d94 100644 --- a/src/js/control-bar/control-bar.js +++ b/src/js/control-bar/control-bar.js @@ -1,3 +1,8 @@ +var ControlBar, Component, vjslib; + +Component = require('../component.js'); +vjslib = require('../lib.js'); + /** * Container of main controls * @param {vjs.Player|Object} player @@ -6,9 +11,9 @@ * @constructor * @extends vjs.Component */ -vjs.ControlBar = vjs.Component.extend(); +ControlBar = Component.extend(); -vjs.ControlBar.prototype.options_ = { +ControlBar.prototype.options_ = { loadEvent: 'play', children: { 'playToggle': {}, @@ -26,8 +31,10 @@ vjs.ControlBar.prototype.options_ = { } }; -vjs.ControlBar.prototype.createEl = function(){ - return vjs.createEl('div', { +ControlBar.prototype.createEl = function(){ + return vjslib.createEl('div', { className: 'vjs-control-bar' }); }; + +module.exports = ControlBar; diff --git a/src/js/control-bar/fullscreen-toggle.js b/src/js/control-bar/fullscreen-toggle.js index 1fb9ce7156..8f2c392a95 100644 --- a/src/js/control-bar/fullscreen-toggle.js +++ b/src/js/control-bar/fullscreen-toggle.js @@ -1,3 +1,7 @@ +var FullscreenToggle, Button; + +Button = require('../button.js'); + /** * Toggle fullscreen video * @param {vjs.Player|Object} player @@ -5,24 +9,24 @@ * @class * @extends vjs.Button */ -vjs.FullscreenToggle = vjs.Button.extend({ +FullscreenToggle = Button.extend({ /** * @constructor * @memberof vjs.FullscreenToggle * @instance */ init: function(player, options){ - vjs.Button.call(this, player, options); + Button.call(this, player, options); } }); -vjs.FullscreenToggle.prototype.buttonText = 'Fullscreen'; +FullscreenToggle.prototype.buttonText = 'Fullscreen'; -vjs.FullscreenToggle.prototype.buildCSSClass = function(){ - return 'vjs-fullscreen-control ' + vjs.Button.prototype.buildCSSClass.call(this); +FullscreenToggle.prototype.buildCSSClass = function(){ + return 'vjs-fullscreen-control ' + Button.prototype.buildCSSClass.call(this); }; -vjs.FullscreenToggle.prototype.onClick = function(){ +FullscreenToggle.prototype.onClick = function(){ if (!this.player_.isFullscreen()) { this.player_.requestFullscreen(); this.controlText_.innerHTML = 'Non-Fullscreen'; @@ -31,3 +35,5 @@ vjs.FullscreenToggle.prototype.onClick = function(){ this.controlText_.innerHTML = 'Fullscreen'; } }; + +module.exports = FullscreenToggle; diff --git a/src/js/control-bar/live-display.js b/src/js/control-bar/live-display.js index dd44922fe1..ec68494f55 100644 --- a/src/js/control-bar/live-display.js +++ b/src/js/control-bar/live-display.js @@ -1,3 +1,8 @@ +var LiveDisplay, Component, vjslib; + +Component = require('../component.js'); +vjslib = require('../lib.js'); + /** * Displays the live indicator * TODO - Future make it click to snap to live @@ -5,18 +10,18 @@ * @param {Object=} options * @constructor */ -vjs.LiveDisplay = vjs.Component.extend({ +LiveDisplay = Component.extend({ init: function(player, options){ - vjs.Component.call(this, player, options); + Component.call(this, player, options); } }); -vjs.LiveDisplay.prototype.createEl = function(){ - var el = vjs.Component.prototype.createEl.call(this, 'div', { +LiveDisplay.prototype.createEl = function(){ + var el = Component.prototype.createEl.call(this, 'div', { className: 'vjs-live-controls vjs-control' }); - this.contentEl_ = vjs.createEl('div', { + this.contentEl_ = vjslib.createEl('div', { className: 'vjs-live-display', innerHTML: 'Stream Type LIVE', 'aria-live': 'off' @@ -26,3 +31,5 @@ vjs.LiveDisplay.prototype.createEl = function(){ return el; }; + +module.exports = LiveDisplay; diff --git a/src/js/control-bar/mute-toggle.js b/src/js/control-bar/mute-toggle.js index 07221504e3..e6f4ff375a 100644 --- a/src/js/control-bar/mute-toggle.js +++ b/src/js/control-bar/mute-toggle.js @@ -1,3 +1,8 @@ +var MuteToggle, Button, vjslib; + +Button = require('../button.js'); +vjslib = require('../lib.js'); + /** * A button component for muting the audio * @@ -5,18 +10,18 @@ * @param {Object=} options * @constructor */ -vjs.MuteToggle = vjs.Button.extend({ +MuteToggle = Button.extend({ /** @constructor */ init: function(player, options){ - vjs.Button.call(this, player, options); + Button.call(this, player, options); - player.on('volumechange', vjs.bind(this, this.update)); + player.on('volumechange', vjslib.bind(this, this.update)); // hide mute toggle if the current tech doesn't support volume control if (player.tech && player.tech.features && player.tech.features['volumeControl'] === false) { this.addClass('vjs-hidden'); } - player.on('loadstart', vjs.bind(this, function(){ + player.on('loadstart', vjslib.bind(this, function(){ if (player.tech.features && player.tech.features['volumeControl'] === false) { this.addClass('vjs-hidden'); } else { @@ -26,18 +31,18 @@ vjs.MuteToggle = vjs.Button.extend({ } }); -vjs.MuteToggle.prototype.createEl = function(){ - return vjs.Button.prototype.createEl.call(this, 'div', { +MuteToggle.prototype.createEl = function(){ + return Button.prototype.createEl.call(this, 'div', { className: 'vjs-mute-control vjs-control', innerHTML: '
Mute
' }); }; -vjs.MuteToggle.prototype.onClick = function(){ +MuteToggle.prototype.onClick = function(){ this.player_.muted( this.player_.muted() ? false : true ); }; -vjs.MuteToggle.prototype.update = function(){ +MuteToggle.prototype.update = function(){ var vol = this.player_.volume(), level = 3; @@ -64,7 +69,9 @@ vjs.MuteToggle.prototype.update = function(){ /* TODO improve muted icon classes */ for (var i = 0; i < 4; i++) { - vjs.removeClass(this.el_, 'vjs-vol-'+i); + vjslib.removeClass(this.el_, 'vjs-vol-'+i); } - vjs.addClass(this.el_, 'vjs-vol-'+level); + vjslib.addClass(this.el_, 'vjs-vol-'+level); }; + +module.exports = MuteToggle; diff --git a/src/js/control-bar/play-toggle.js b/src/js/control-bar/play-toggle.js index 57758cd92e..05059d2339 100644 --- a/src/js/control-bar/play-toggle.js +++ b/src/js/control-bar/play-toggle.js @@ -1,3 +1,8 @@ +var PlayToggle, Button, vjslib; + +Button = require('../button.js'); +vjslib = require('../lib.js'); + /** * Button to toggle between play and pause * @param {vjs.Player|Object} player @@ -5,24 +10,24 @@ * @class * @constructor */ -vjs.PlayToggle = vjs.Button.extend({ +PlayToggle = Button.extend({ /** @constructor */ init: function(player, options){ - vjs.Button.call(this, player, options); + Button.call(this, player, options); - player.on('play', vjs.bind(this, this.onPlay)); - player.on('pause', vjs.bind(this, this.onPause)); + player.on('play', vjslib.bind(this, this.onPlay)); + player.on('pause', vjslib.bind(this, this.onPause)); } }); -vjs.PlayToggle.prototype.buttonText = 'Play'; +PlayToggle.prototype.buttonText = 'Play'; -vjs.PlayToggle.prototype.buildCSSClass = function(){ - return 'vjs-play-control ' + vjs.Button.prototype.buildCSSClass.call(this); +PlayToggle.prototype.buildCSSClass = function(){ + return 'vjs-play-control ' + Button.prototype.buildCSSClass.call(this); }; // OnClick - Toggle between play and pause -vjs.PlayToggle.prototype.onClick = function(){ +PlayToggle.prototype.onClick = function(){ if (this.player_.paused()) { this.player_.play(); } else { @@ -31,15 +36,17 @@ vjs.PlayToggle.prototype.onClick = function(){ }; // OnPlay - Add the vjs-playing class to the element so it can change appearance -vjs.PlayToggle.prototype.onPlay = function(){ - vjs.removeClass(this.el_, 'vjs-paused'); - vjs.addClass(this.el_, 'vjs-playing'); +PlayToggle.prototype.onPlay = function(){ + vjslib.removeClass(this.el_, 'vjs-paused'); + vjslib.addClass(this.el_, 'vjs-playing'); this.el_.children[0].children[0].innerHTML = 'Pause'; // change the button text to "Pause" }; // OnPause - Add the vjs-paused class to the element so it can change appearance -vjs.PlayToggle.prototype.onPause = function(){ - vjs.removeClass(this.el_, 'vjs-playing'); - vjs.addClass(this.el_, 'vjs-paused'); +PlayToggle.prototype.onPause = function(){ + vjslib.removeClass(this.el_, 'vjs-playing'); + vjslib.addClass(this.el_, 'vjs-paused'); this.el_.children[0].children[0].innerHTML = 'Play'; // change the button text to "Play" }; + +module.exports = PlayToggle; diff --git a/src/js/control-bar/playback-rate-menu-button.js b/src/js/control-bar/playback-rate-menu-button.js index 42bf2e286e..9c203cf194 100644 --- a/src/js/control-bar/playback-rate-menu-button.js +++ b/src/js/control-bar/playback-rate-menu-button.js @@ -1,3 +1,9 @@ +var PlaybackRateMenuButton, Component, vjsmenu, vjslib; + +vjsmenu = require('../menu.js'); +vjslib = require('../lib.js'); +Component = require('../component.js'); + /** * The component for controlling the playback rate * @@ -5,26 +11,26 @@ * @param {Object=} options * @constructor */ -vjs.PlaybackRateMenuButton = vjs.MenuButton.extend({ +PlaybackRateMenuButton = vjsmenu.MenuButton.extend({ /** @constructor */ init: function(player, options){ - vjs.MenuButton.call(this, player, options); + vjsmenu.MenuButton.call(this, player, options); this.updateVisibility(); this.updateLabel(); - player.on('loadstart', vjs.bind(this, this.updateVisibility)); - player.on('ratechange', vjs.bind(this, this.updateLabel)); + player.on('loadstart', vjslib.bind(this, this.updateVisibility)); + player.on('ratechange', vjslib.bind(this, this.updateLabel)); } }); -vjs.PlaybackRateMenuButton.prototype.createEl = function(){ - var el = vjs.Component.prototype.createEl.call(this, 'div', { +PlaybackRateMenuButton.prototype.createEl = function(){ + var el = Component.prototype.createEl.call(this, 'div', { className: 'vjs-playback-rate vjs-menu-button vjs-control', innerHTML: '
Playback Rate
' }); - this.labelEl_ = vjs.createEl('div', { + this.labelEl_ = vjslib.createEl('div', { className: 'vjs-playback-rate-value', innerHTML: 1.0 }); @@ -35,14 +41,14 @@ vjs.PlaybackRateMenuButton.prototype.createEl = function(){ }; // Menu creation -vjs.PlaybackRateMenuButton.prototype.createMenu = function(){ - var menu = new vjs.Menu(this.player()); +PlaybackRateMenuButton.prototype.createMenu = function(){ + var menu = new vjsmenu.Menu(this.player()); var rates = this.player().options()['playbackRates']; if (rates) { for (var i = rates.length - 1; i >= 0; i--) { menu.addChild( - new vjs.PlaybackRateMenuItem(this.player(), { 'rate': rates[i] + 'x'}) + new PlaybackRateMenuItem(this.player(), { 'rate': rates[i] + 'x'}) ); }; } @@ -50,12 +56,12 @@ vjs.PlaybackRateMenuButton.prototype.createMenu = function(){ return menu; }; -vjs.PlaybackRateMenuButton.prototype.updateARIAAttributes = function(){ +PlaybackRateMenuButton.prototype.updateARIAAttributes = function(){ // Current playback rate this.el().setAttribute('aria-valuenow', this.player().playbackRate()); }; -vjs.PlaybackRateMenuButton.prototype.onClick = function(){ +PlaybackRateMenuButton.prototype.onClick = function(){ // select next rate option var currentRate = this.player().playbackRate(); var rates = this.player().options()['playbackRates']; @@ -70,7 +76,7 @@ vjs.PlaybackRateMenuButton.prototype.onClick = function(){ this.player().playbackRate(newRate); }; -vjs.PlaybackRateMenuButton.prototype.playbackRateSupported = function(){ +PlaybackRateMenuButton.prototype.playbackRateSupported = function(){ return this.player().tech && this.player().tech.features['playbackRate'] && this.player().options()['playbackRates'] @@ -81,7 +87,7 @@ vjs.PlaybackRateMenuButton.prototype.playbackRateSupported = function(){ /** * Hide playback rate controls when they're no playback rate options to select */ -vjs.PlaybackRateMenuButton.prototype.updateVisibility = function(){ +PlaybackRateMenuButton.prototype.updateVisibility = function(){ if (this.playbackRateSupported()) { this.removeClass('vjs-hidden'); } else { @@ -92,7 +98,7 @@ vjs.PlaybackRateMenuButton.prototype.updateVisibility = function(){ /** * Update button label when rate changed */ -vjs.PlaybackRateMenuButton.prototype.updateLabel = function(){ +PlaybackRateMenuButton.prototype.updateLabel = function(){ if (this.playbackRateSupported()) { this.labelEl_.innerHTML = this.player().playbackRate() + 'x'; } @@ -103,7 +109,7 @@ vjs.PlaybackRateMenuButton.prototype.updateLabel = function(){ * * @constructor */ -vjs.PlaybackRateMenuItem = vjs.MenuItem.extend({ +PlaybackRateMenuItem = vjsmenu.MenuItem.extend({ contentElType: 'button', /** @constructor */ init: function(player, options){ @@ -113,17 +119,19 @@ vjs.PlaybackRateMenuItem = vjs.MenuItem.extend({ // Modify options for parent MenuItem class's init. options['label'] = label; options['selected'] = rate === 1; - vjs.MenuItem.call(this, player, options); + vjsmenu.MenuItem.call(this, player, options); - this.player().on('ratechange', vjs.bind(this, this.update)); + this.player().on('ratechange', vjslib.bind(this, this.update)); } }); -vjs.PlaybackRateMenuItem.prototype.onClick = function(){ - vjs.MenuItem.prototype.onClick.call(this); +PlaybackRateMenuItem.prototype.onClick = function(){ + vjsmenu.MenuItem.prototype.onClick.call(this); this.player().playbackRate(this.rate); }; -vjs.PlaybackRateMenuItem.prototype.update = function(){ +PlaybackRateMenuItem.prototype.update = function(){ this.selected(this.player().playbackRate() == this.rate); }; + +module.exports = PlaybackRateMenuButton; diff --git a/src/js/control-bar/progress-control.js b/src/js/control-bar/progress-control.js index 7c0dee699e..c8ac91e86c 100644 --- a/src/js/control-bar/progress-control.js +++ b/src/js/control-bar/progress-control.js @@ -1,3 +1,9 @@ +var ProgressControl, SeekBar, LoadProgressBar, PlayProgressBar, SeekHandle, Component, vjslib, slider; + +Component = require('../component.js'); +vjslib = require('../lib.js'); +slider = require('../slider.js'); + /** * The Progress Control component contains the seek bar, load progress, * and play progress @@ -6,21 +12,21 @@ * @param {Object=} options * @constructor */ -vjs.ProgressControl = vjs.Component.extend({ +ProgressControl = Component.extend({ /** @constructor */ init: function(player, options){ - vjs.Component.call(this, player, options); + Component.call(this, player, options); } }); -vjs.ProgressControl.prototype.options_ = { +ProgressControl.prototype.options_ = { children: { 'seekBar': {} } }; -vjs.ProgressControl.prototype.createEl = function(){ - return vjs.Component.prototype.createEl.call(this, 'div', { +ProgressControl.prototype.createEl = function(){ + return Component.prototype.createEl.call(this, 'div', { className: 'vjs-progress-control vjs-control' }); }; @@ -32,16 +38,16 @@ vjs.ProgressControl.prototype.createEl = function(){ * @param {Object=} options * @constructor */ -vjs.SeekBar = vjs.Slider.extend({ +SeekBar = slider.Slider.extend({ /** @constructor */ init: function(player, options){ - vjs.Slider.call(this, player, options); - player.on('timeupdate', vjs.bind(this, this.updateARIAAttributes)); - player.ready(vjs.bind(this, this.updateARIAAttributes)); + slider.Slider.call(this, player, options); + player.on('timeupdate', vjslib.bind(this, this.updateARIAAttributes)); + player.ready(vjslib.bind(this, this.updateARIAAttributes)); } }); -vjs.SeekBar.prototype.options_ = { +SeekBar.prototype.options_ = { children: { 'loadProgressBar': {}, 'playProgressBar': {}, @@ -51,28 +57,28 @@ vjs.SeekBar.prototype.options_ = { 'handleName': 'seekHandle' }; -vjs.SeekBar.prototype.playerEvent = 'timeupdate'; +SeekBar.prototype.playerEvent = 'timeupdate'; -vjs.SeekBar.prototype.createEl = function(){ - return vjs.Slider.prototype.createEl.call(this, 'div', { +SeekBar.prototype.createEl = function(){ + return slider.Slider.prototype.createEl.call(this, 'div', { className: 'vjs-progress-holder', 'aria-label': 'video progress bar' }); }; -vjs.SeekBar.prototype.updateARIAAttributes = function(){ +SeekBar.prototype.updateARIAAttributes = function(){ // Allows for smooth scrubbing, when player can't keep up. var time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime(); - this.el_.setAttribute('aria-valuenow',vjs.round(this.getPercent()*100, 2)); // machine readable value of progress bar (percentage complete) - this.el_.setAttribute('aria-valuetext',vjs.formatTime(time, this.player_.duration())); // human readable value of progress bar (time complete) + 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) }; -vjs.SeekBar.prototype.getPercent = function(){ +SeekBar.prototype.getPercent = function(){ return this.player_.currentTime() / this.player_.duration(); }; -vjs.SeekBar.prototype.onMouseDown = function(event){ - vjs.Slider.prototype.onMouseDown.call(this, event); +SeekBar.prototype.onMouseDown = function(event){ + slider.Slider.prototype.onMouseDown.call(this, event); this.player_.scrubbing = true; @@ -80,7 +86,7 @@ vjs.SeekBar.prototype.onMouseDown = function(event){ this.player_.pause(); }; -vjs.SeekBar.prototype.onMouseMove = function(event){ +SeekBar.prototype.onMouseMove = function(event){ var newTime = this.calculateDistance(event) * this.player_.duration(); // Don't let video end while scrubbing. @@ -90,8 +96,8 @@ vjs.SeekBar.prototype.onMouseMove = function(event){ this.player_.currentTime(newTime); }; -vjs.SeekBar.prototype.onMouseUp = function(event){ - vjs.Slider.prototype.onMouseUp.call(this, event); +SeekBar.prototype.onMouseUp = function(event){ + slider.Slider.prototype.onMouseUp.call(this, event); this.player_.scrubbing = false; if (this.videoWasPlaying) { @@ -99,11 +105,11 @@ vjs.SeekBar.prototype.onMouseUp = function(event){ } }; -vjs.SeekBar.prototype.stepForward = function(){ +SeekBar.prototype.stepForward = function(){ this.player_.currentTime(this.player_.currentTime() + 5); // more quickly fast forward for keyboard-only users }; -vjs.SeekBar.prototype.stepBack = function(){ +SeekBar.prototype.stepBack = function(){ this.player_.currentTime(this.player_.currentTime() - 5); // more quickly rewind for keyboard-only users }; @@ -115,23 +121,23 @@ vjs.SeekBar.prototype.stepBack = function(){ * @param {Object=} options * @constructor */ -vjs.LoadProgressBar = vjs.Component.extend({ +LoadProgressBar = Component.extend({ /** @constructor */ init: function(player, options){ - vjs.Component.call(this, player, options); - player.on('progress', vjs.bind(this, this.update)); + Component.call(this, player, options); + player.on('progress', vjslib.bind(this, this.update)); } }); -vjs.LoadProgressBar.prototype.createEl = function(){ - return vjs.Component.prototype.createEl.call(this, 'div', { +LoadProgressBar.prototype.createEl = function(){ + return Component.prototype.createEl.call(this, 'div', { className: 'vjs-load-progress', innerHTML: 'Loaded: 0%' }); }; -vjs.LoadProgressBar.prototype.update = function(){ - if (this.el_.style) { this.el_.style.width = vjs.round(this.player_.bufferedPercent() * 100, 2) + '%'; } +LoadProgressBar.prototype.update = function(){ + if (this.el_.style) { this.el_.style.width = vjslib.round(this.player_.bufferedPercent() * 100, 2) + '%'; } }; @@ -142,15 +148,15 @@ vjs.LoadProgressBar.prototype.update = function(){ * @param {Object=} options * @constructor */ -vjs.PlayProgressBar = vjs.Component.extend({ +PlayProgressBar = Component.extend({ /** @constructor */ init: function(player, options){ - vjs.Component.call(this, player, options); + Component.call(this, player, options); } }); -vjs.PlayProgressBar.prototype.createEl = function(){ - return vjs.Component.prototype.createEl.call(this, 'div', { +PlayProgressBar.prototype.createEl = function(){ + return Component.prototype.createEl.call(this, 'div', { className: 'vjs-play-progress', innerHTML: 'Progress: 0%' }); @@ -164,10 +170,10 @@ vjs.PlayProgressBar.prototype.createEl = function(){ * @param {Object=} options * @constructor */ -vjs.SeekHandle = vjs.SliderHandle.extend({ +SeekHandle = slider.SliderHandle.extend({ init: function(player, options) { - vjs.SliderHandle.call(this, player, options); - player.on('timeupdate', vjs.bind(this, this.updateContent)); + slider.SliderHandle.call(this, player, options); + player.on('timeupdate', vjslib.bind(this, this.updateContent)); } }); @@ -177,17 +183,26 @@ vjs.SeekHandle = vjs.SliderHandle.extend({ * @type {String} * @private */ -vjs.SeekHandle.prototype.defaultValue = '00:00'; +SeekHandle.prototype.defaultValue = '00:00'; /** @inheritDoc */ -vjs.SeekHandle.prototype.createEl = function() { - return vjs.SliderHandle.prototype.createEl.call(this, 'div', { +SeekHandle.prototype.createEl = function() { + return slider.SliderHandle.prototype.createEl.call(this, 'div', { className: 'vjs-seek-handle', 'aria-live': 'off' }); }; -vjs.SeekHandle.prototype.updateContent = function() { +SeekHandle.prototype.updateContent = function() { var time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime(); - this.el_.innerHTML = '' + vjs.formatTime(time, this.player_.duration()) + ''; + this.el_.innerHTML = '' + vjslib.formatTime(time, this.player_.duration()) + ''; }; + +module.exports = { + ProgressControl: ProgressControl, + LoadProgressBar: LoadProgressBar, + PlayProgressBar: PlayProgressBar, + SeekBar: SeekBar, + SeekHandle: SeekHandle +}; + diff --git a/src/js/control-bar/time-display.js b/src/js/control-bar/time-display.js index dbbb7e5c9d..3b38efe670 100644 --- a/src/js/control-bar/time-display.js +++ b/src/js/control-bar/time-display.js @@ -1,24 +1,29 @@ +var CurrentTimeDisplay, DurationDisplay, TimeDivider, RemainingTimeDisplay, Component, vjslib; + +Component = require('../component.js'); +vjslib = require('../lib.js'); + /** * Displays the current time * @param {vjs.Player|Object} player * @param {Object=} options * @constructor */ -vjs.CurrentTimeDisplay = vjs.Component.extend({ +CurrentTimeDisplay = Component.extend({ /** @constructor */ init: function(player, options){ - vjs.Component.call(this, player, options); + Component.call(this, player, options); - player.on('timeupdate', vjs.bind(this, this.updateContent)); + player.on('timeupdate', vjslib.bind(this, this.updateContent)); } }); -vjs.CurrentTimeDisplay.prototype.createEl = function(){ - var el = vjs.Component.prototype.createEl.call(this, 'div', { +CurrentTimeDisplay.prototype.createEl = function(){ + var el = Component.prototype.createEl.call(this, 'div', { className: 'vjs-current-time vjs-time-controls vjs-control' }); - this.contentEl_ = vjs.createEl('div', { + this.contentEl_ = vjslib.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 @@ -28,10 +33,10 @@ vjs.CurrentTimeDisplay.prototype.createEl = function(){ return el; }; -vjs.CurrentTimeDisplay.prototype.updateContent = function(){ +CurrentTimeDisplay.prototype.updateContent = function(){ // Allows for smooth scrubbing, when player can't keep up. var time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime(); - this.contentEl_.innerHTML = 'Current Time ' + vjs.formatTime(time, this.player_.duration()); + this.contentEl_.innerHTML = 'Current Time ' + vjslib.formatTime(time, this.player_.duration()); }; /** @@ -40,26 +45,26 @@ vjs.CurrentTimeDisplay.prototype.updateContent = function(){ * @param {Object=} options * @constructor */ -vjs.DurationDisplay = vjs.Component.extend({ +DurationDisplay = Component.extend({ /** @constructor */ init: function(player, options){ - vjs.Component.call(this, player, options); + Component.call(this, player, options); // this might need to be changed to 'durationchange' instead of 'timeupdate' eventually, // however the durationchange event fires before this.player_.duration() is set, // so the value cannot be written out using this method. // Once the order of durationchange and this.player_.duration() being set is figured out, // this can be updated. - player.on('timeupdate', vjs.bind(this, this.updateContent)); + player.on('timeupdate', vjslib.bind(this, this.updateContent)); } }); -vjs.DurationDisplay.prototype.createEl = function(){ - var el = vjs.Component.prototype.createEl.call(this, 'div', { +DurationDisplay.prototype.createEl = function(){ + var el = Component.prototype.createEl.call(this, 'div', { className: 'vjs-duration vjs-time-controls vjs-control' }); - this.contentEl_ = vjs.createEl('div', { + this.contentEl_ = vjslib.createEl('div', { className: 'vjs-duration-display', innerHTML: '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 @@ -69,10 +74,10 @@ vjs.DurationDisplay.prototype.createEl = function(){ return el; }; -vjs.DurationDisplay.prototype.updateContent = function(){ +DurationDisplay.prototype.updateContent = function(){ var duration = this.player_.duration(); if (duration) { - this.contentEl_.innerHTML = 'Duration Time ' + vjs.formatTime(duration); // label the duration time for screen reader users + this.contentEl_.innerHTML = 'Duration Time ' + vjslib.formatTime(duration); // label the duration time for screen reader users } }; @@ -85,15 +90,15 @@ vjs.DurationDisplay.prototype.updateContent = function(){ * @param {Object=} options * @constructor */ -vjs.TimeDivider = vjs.Component.extend({ +TimeDivider = Component.extend({ /** @constructor */ init: function(player, options){ - vjs.Component.call(this, player, options); + Component.call(this, player, options); } }); -vjs.TimeDivider.prototype.createEl = function(){ - return vjs.Component.prototype.createEl.call(this, 'div', { +TimeDivider.prototype.createEl = function(){ + return Component.prototype.createEl.call(this, 'div', { className: 'vjs-time-divider', innerHTML: '
/
' }); @@ -105,21 +110,21 @@ vjs.TimeDivider.prototype.createEl = function(){ * @param {Object=} options * @constructor */ -vjs.RemainingTimeDisplay = vjs.Component.extend({ +RemainingTimeDisplay = Component.extend({ /** @constructor */ init: function(player, options){ - vjs.Component.call(this, player, options); + Component.call(this, player, options); - player.on('timeupdate', vjs.bind(this, this.updateContent)); + player.on('timeupdate', vjslib.bind(this, this.updateContent)); } }); -vjs.RemainingTimeDisplay.prototype.createEl = function(){ - var el = vjs.Component.prototype.createEl.call(this, 'div', { +RemainingTimeDisplay.prototype.createEl = function(){ + var el = Component.prototype.createEl.call(this, 'div', { className: 'vjs-remaining-time vjs-time-controls vjs-control' }); - this.contentEl_ = vjs.createEl('div', { + this.contentEl_ = vjslib.createEl('div', { className: 'vjs-remaining-time-display', innerHTML: '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 @@ -129,12 +134,19 @@ vjs.RemainingTimeDisplay.prototype.createEl = function(){ return el; }; -vjs.RemainingTimeDisplay.prototype.updateContent = function(){ +RemainingTimeDisplay.prototype.updateContent = function(){ if (this.player_.duration()) { - this.contentEl_.innerHTML = 'Remaining Time ' + '-'+ vjs.formatTime(this.player_.remainingTime()); + this.contentEl_.innerHTML = 'Remaining Time ' + '-'+ vjslib.formatTime(this.player_.remainingTime()); } // Allows for smooth scrubbing, when player can't keep up. // var time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime(); // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration()); }; + +module.exports = { + CurrentTimeDisplay: CurrentTimeDisplay, + DurationDisplay: DurationDisplay, + TimeDivider: TimeDivider, + RemainingTimeDisplay: RemainingTimeDisplay +}; diff --git a/src/js/control-bar/volume-control.js b/src/js/control-bar/volume-control.js index 64ec52d247..5f95464f13 100644 --- a/src/js/control-bar/volume-control.js +++ b/src/js/control-bar/volume-control.js @@ -1,3 +1,9 @@ +var VolumeControl, VolumeBar, VolumeLevel, VolumeLevel, VolumeHandle, Component, vjslib, slider; + +Component = require('../component.js'); +vjslib = require('../lib.js'); +slider = require('../slider.js'); + /** * The component for controlling the volume level * @@ -5,16 +11,16 @@ * @param {Object=} options * @constructor */ -vjs.VolumeControl = vjs.Component.extend({ +VolumeControl = Component.extend({ /** @constructor */ init: function(player, options){ - vjs.Component.call(this, player, options); + Component.call(this, player, options); // hide volume controls when they're not supported by the current tech if (player.tech && player.tech.features && player.tech.features['volumeControl'] === false) { this.addClass('vjs-hidden'); } - player.on('loadstart', vjs.bind(this, function(){ + player.on('loadstart', vjslib.bind(this, function(){ if (player.tech.features && player.tech.features['volumeControl'] === false) { this.addClass('vjs-hidden'); } else { @@ -24,14 +30,14 @@ vjs.VolumeControl = vjs.Component.extend({ } }); -vjs.VolumeControl.prototype.options_ = { +VolumeControl.prototype.options_ = { children: { 'volumeBar': {} } }; -vjs.VolumeControl.prototype.createEl = function(){ - return vjs.Component.prototype.createEl.call(this, 'div', { +VolumeControl.prototype.createEl = function(){ + return Component.prototype.createEl.call(this, 'div', { className: 'vjs-volume-control vjs-control' }); }; @@ -43,22 +49,22 @@ vjs.VolumeControl.prototype.createEl = function(){ * @param {Object=} options * @constructor */ -vjs.VolumeBar = vjs.Slider.extend({ +VolumeBar = slider.Slider.extend({ /** @constructor */ init: function(player, options){ - vjs.Slider.call(this, player, options); - player.on('volumechange', vjs.bind(this, this.updateARIAAttributes)); - player.ready(vjs.bind(this, this.updateARIAAttributes)); + slider.Slider.call(this, player, options); + player.on('volumechange', vjslib.bind(this, this.updateARIAAttributes)); + player.ready(vjslib.bind(this, this.updateARIAAttributes)); } }); -vjs.VolumeBar.prototype.updateARIAAttributes = function(){ +VolumeBar.prototype.updateARIAAttributes = function(){ // Current value of volume bar as a percentage - this.el_.setAttribute('aria-valuenow',vjs.round(this.player_.volume()*100, 2)); - this.el_.setAttribute('aria-valuetext',vjs.round(this.player_.volume()*100, 2)+'%'); + this.el_.setAttribute('aria-valuenow',vjslib.round(this.player_.volume()*100, 2)); + this.el_.setAttribute('aria-valuetext',vjslib.round(this.player_.volume()*100, 2)+'%'); }; -vjs.VolumeBar.prototype.options_ = { +VolumeBar.prototype.options_ = { children: { 'volumeLevel': {}, 'volumeHandle': {} @@ -67,16 +73,16 @@ vjs.VolumeBar.prototype.options_ = { 'handleName': 'volumeHandle' }; -vjs.VolumeBar.prototype.playerEvent = 'volumechange'; +VolumeBar.prototype.playerEvent = 'volumechange'; -vjs.VolumeBar.prototype.createEl = function(){ - return vjs.Slider.prototype.createEl.call(this, 'div', { +VolumeBar.prototype.createEl = function(){ + return slider.Slider.prototype.createEl.call(this, 'div', { className: 'vjs-volume-bar', 'aria-label': 'volume level' }); }; -vjs.VolumeBar.prototype.onMouseMove = function(event) { +VolumeBar.prototype.onMouseMove = function(event) { if (this.player_.muted()) { this.player_.muted(false); } @@ -84,7 +90,7 @@ vjs.VolumeBar.prototype.onMouseMove = function(event) { this.player_.volume(this.calculateDistance(event)); }; -vjs.VolumeBar.prototype.getPercent = function(){ +VolumeBar.prototype.getPercent = function(){ if (this.player_.muted()) { return 0; } else { @@ -92,11 +98,11 @@ vjs.VolumeBar.prototype.getPercent = function(){ } }; -vjs.VolumeBar.prototype.stepForward = function(){ +VolumeBar.prototype.stepForward = function(){ this.player_.volume(this.player_.volume() + 0.1); }; -vjs.VolumeBar.prototype.stepBack = function(){ +VolumeBar.prototype.stepBack = function(){ this.player_.volume(this.player_.volume() - 0.1); }; @@ -107,15 +113,15 @@ vjs.VolumeBar.prototype.stepBack = function(){ * @param {Object=} options * @constructor */ -vjs.VolumeLevel = vjs.Component.extend({ +VolumeLevel = Component.extend({ /** @constructor */ init: function(player, options){ - vjs.Component.call(this, player, options); + Component.call(this, player, options); } }); -vjs.VolumeLevel.prototype.createEl = function(){ - return vjs.Component.prototype.createEl.call(this, 'div', { +VolumeLevel.prototype.createEl = function(){ + return Component.prototype.createEl.call(this, 'div', { className: 'vjs-volume-level', innerHTML: '' }); @@ -128,13 +134,20 @@ vjs.VolumeLevel.prototype.createEl = function(){ * @param {Object=} options * @constructor */ - vjs.VolumeHandle = vjs.SliderHandle.extend(); + VolumeHandle = slider.SliderHandle.extend(); - vjs.VolumeHandle.prototype.defaultValue = '00:00'; + VolumeHandle.prototype.defaultValue = '00:00'; /** @inheritDoc */ - vjs.VolumeHandle.prototype.createEl = function(){ - return vjs.SliderHandle.prototype.createEl.call(this, 'div', { + VolumeHandle.prototype.createEl = function(){ + return slider.SliderHandle.prototype.createEl.call(this, 'div', { className: 'vjs-volume-handle' }); }; + +module.exports = { + VolumeControl: VolumeControl, + VolumeBar: VolumeBar, + VolumeLevel: VolumeLevel, + VolumeHandle: VolumeHandle +}; diff --git a/src/js/control-bar/volume-menu-button.js b/src/js/control-bar/volume-menu-button.js index 21b2836f80..4e27227ddd 100644 --- a/src/js/control-bar/volume-menu-button.js +++ b/src/js/control-bar/volume-menu-button.js @@ -1,20 +1,28 @@ +var VolumeMenuButton, Button, MuteToggle, menu, volume, vjslib; + +Button = require('../button.js'); +MuteToggle = require('./mute-toggle.js'); +menu = require('../menu.js'); +volume = require('./volume-control.js'); +vjslib = require('../lib.js'); + /** * Menu button with a popup for showing the volume slider. * @constructor */ -vjs.VolumeMenuButton = vjs.MenuButton.extend({ +VolumeMenuButton = menu.MenuButton.extend({ /** @constructor */ init: function(player, options){ - vjs.MenuButton.call(this, player, options); + menu.MenuButton.call(this, player, options); // Same listeners as MuteToggle - player.on('volumechange', vjs.bind(this, this.update)); + player.on('volumechange', vjslib.bind(this, this.update)); // hide mute toggle if the current tech doesn't support volume control if (player.tech && player.tech.features && player.tech.features.volumeControl === false) { this.addClass('vjs-hidden'); } - player.on('loadstart', vjs.bind(this, function(){ + player.on('loadstart', vjslib.bind(this, function(){ if (player.tech.features && player.tech.features.volumeControl === false) { this.addClass('vjs-hidden'); } else { @@ -25,24 +33,27 @@ vjs.VolumeMenuButton = vjs.MenuButton.extend({ } }); -vjs.VolumeMenuButton.prototype.createMenu = function(){ - var menu = new vjs.Menu(this.player_, { +VolumeMenuButton.prototype.createMenu = function(){ + var menu = new menu.Menu(this.player_, { contentElType: 'div' }); - var vc = new vjs.VolumeBar(this.player_, vjs.obj.merge({vertical: true}, this.options_.volumeBar)); + var vc = new volume.VolumeBar(this.player_, vjslib.obj.merge({vertical: true}, this.options_.volumeBar)); menu.addChild(vc); return menu; }; -vjs.VolumeMenuButton.prototype.onClick = function(){ - vjs.MuteToggle.prototype.onClick.call(this); - vjs.MenuButton.prototype.onClick.call(this); +VolumeMenuButton.prototype.onClick = function(){ + MuteToggle.prototype.onClick.call(this); + menu.MenuButton.prototype.onClick.call(this); }; -vjs.VolumeMenuButton.prototype.createEl = function(){ - return vjs.Button.prototype.createEl.call(this, 'div', { +VolumeMenuButton.prototype.createEl = function(){ + return Button.prototype.createEl.call(this, 'div', { className: 'vjs-volume-menu-button vjs-menu-button vjs-control', innerHTML: '
Mute
' }); }; -vjs.VolumeMenuButton.prototype.update = vjs.MuteToggle.prototype.update; + +VolumeMenuButton.prototype.update = MuteToggle.prototype.update; + +module.exports = VolumeMenuButton; diff --git a/src/js/core-object.js b/src/js/core-object.js index 619aad05b2..64c107975f 100644 --- a/src/js/core-object.js +++ b/src/js/core-object.js @@ -1,3 +1,7 @@ +var CoreObject, vjslib; + +vjslib = require('./lib.js'); + /** * Core Object/Class for objects that use inheritance + contstructors * @@ -49,7 +53,7 @@ * @class * @constructor */ -vjs.CoreObject = vjs['CoreObject'] = function(){}; +CoreObject = function(){}; // Manually exporting vjs['CoreObject'] here for Closure Compiler // because of the use of the extend/create class methods // If we didn't do this, those functions would get flattend to something like @@ -67,7 +71,7 @@ vjs.CoreObject = vjs['CoreObject'] = function(){}; * @return {vjs.CoreObject} An object that inherits from CoreObject * @this {*} */ -vjs.CoreObject.extend = function(props){ +CoreObject.extend = function(props){ var init, subObj; props = props || {}; @@ -89,15 +93,15 @@ vjs.CoreObject.extend = function(props){ }; // Inherit from this object's prototype - subObj.prototype = vjs.obj.create(this.prototype); + subObj.prototype = vjslib.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; // Make the class extendable - subObj.extend = vjs.CoreObject.extend; + subObj.extend = CoreObject.extend; // Make a function for creating instances - subObj.create = vjs.CoreObject.create; + subObj.create = CoreObject.create; // Extend subObj's prototype with functions and other properties from props for (var name in props) { @@ -117,9 +121,9 @@ vjs.CoreObject.extend = function(props){ * @return {vjs.CoreObject} An instance of a CoreObject subclass * @this {*} */ -vjs.CoreObject.create = function(){ +CoreObject.create = function(){ // Create a new object that inherits from this object's prototype - var inst = vjs.obj.create(this.prototype); + var inst = vjslib.obj.create(this.prototype); // Apply this constructor function to the new object this.apply(inst, arguments); @@ -127,3 +131,5 @@ vjs.CoreObject.create = function(){ // Return the new object return inst; }; + +module.exports = CoreObject; diff --git a/src/js/core.js b/src/js/core.js index 1f7e165259..cac2e25ac5 100644 --- a/src/js/core.js +++ b/src/js/core.js @@ -1,11 +1,21 @@ +var vjs, Player, CoreObject, options, vjslib, plugins; + +Player = require('./player.js'); +plugins = require('./plugins.js'); +options = require('./options.js'); +vjslib = require('./lib.js'); +CoreObject = require('./core-object.js'); + /** * @fileoverview Main function src. */ -// HTML5 Shiv. Must be in to support older browsers. -document.createElement('video'); -document.createElement('audio'); -document.createElement('track'); +var elementShiv = function() { + // HTML5 Shiv. Must be in to support older browsers. + document.createElement('video'); + document.createElement('audio'); + document.createElement('track'); +} /** * Doubles as the main function for users to create a player instance and also @@ -23,7 +33,7 @@ document.createElement('track'); * @return {vjs.Player} A player instance * @namespace */ -var vjs = function(id, options, ready){ +vjs = function(id, options, ready){ var tag; // Element of ID // Allow for element or ID to be passed in @@ -36,12 +46,12 @@ var vjs = function(id, options, ready){ } // If a player instance has already been created for this ID return it. - if (vjs.players[id]) { - return vjs.players[id]; + if (Player.players[id]) { + return Player.players[id]; // Otherwise get element for ID } else { - tag = vjs.el(id); + tag = vjslib.el(id); } // ID is a media element @@ -56,81 +66,26 @@ var vjs = function(id, options, ready){ // Element may have a player attr referring to an already created player instance. // If not, set up a new player and return the instance. - return tag['player'] || new vjs.Player(tag, options, ready); + return tag['player'] || new Player(tag, options, ready); }; +vjs.options = options; +vjs.plugins = plugins; +vjs.Player = Player; + // Extended name, also available externally, window.videojs -var videojs = vjs; -window.videojs = window.vjs = vjs; +//var videojs = vjs; +//window.videojs = window.vjs = vjs; // CDN Version. Used to target right flash swf. vjs.CDN_VERSION = 'GENERATED_CDN_VSN'; vjs.ACCESS_PROTOCOL = ('https:' == document.location.protocol ? 'https://' : 'http://'); -/** - * Global Player instance options, surfaced from vjs.Player.prototype.options_ - * vjs.options = vjs.Player.prototype.options_ - * All options should use string keys so they avoid - * renaming by closure compiler - * @type {Object} - */ -vjs.options = { - // Default order of fallback technology - 'techOrder': ['html5','flash'], - // techOrder: ['flash','html5'], - - 'html5': {}, - 'flash': {}, - - // Default of web browser is 300x150. Should rely on source width/height. - 'width': 300, - 'height': 150, - // defaultVolume: 0.85, - 'defaultVolume': 0.00, // The freakin seaguls are driving me crazy! - - // default playback rates - 'playbackRates': [], - // Add playback rate selection by adding rates - // 'playbackRates': [0.5, 1, 1.5, 2], - - // Included control sets - 'children': { - 'mediaLoader': {}, - 'posterImage': {}, - 'textTrackDisplay': {}, - 'loadingSpinner': {}, - 'bigPlayButton': {}, - 'controlBar': {}, - 'errorDisplay': {} - }, - - // Default message to show when a video cannot be played. - 'notSupportedMessage': 'No compatible source was found for this video.' -}; - // Set CDN Version of swf // The added (+) blocks the replace from changing this GENERATED_CDN_VSN string if (vjs.CDN_VERSION !== 'GENERATED'+'_CDN_VSN') { - videojs.options['flash']['swf'] = vjs.ACCESS_PROTOCOL + 'vjs.zencdn.net/'+vjs.CDN_VERSION+'/video-js.swf'; + options['flash']['swf'] = vjs.ACCESS_PROTOCOL + 'vjs.zencdn.net/'+vjs.CDN_VERSION+'/video-js.swf'; } -/** - * Global player list - * @type {Object} - */ -vjs.players = {}; - -/*! - * Custom Universal Module Definition (UMD) - * - * Video.js will never be a non-browser lib so we can simplify UMD a bunch and - * still support requirejs and browserify. This also needs to be closure - * compiler compatible, so string keys are used. - */ -if (typeof define === 'function' && define['amd']) { - define([], function(){ return videojs; }); - -// checking that module is an object too because of umdjs/umd#35 -} else if (typeof exports === 'object' && typeof module === 'object') { - module['exports'] = videojs; -} +module.exports = vjs; +module.exports.elementShiv = elementShiv; diff --git a/src/js/error-display.js b/src/js/error-display.js index 98803b8eff..ae30f5dea9 100644 --- a/src/js/error-display.js +++ b/src/js/error-display.js @@ -1,31 +1,38 @@ +var ErrorDisplay, Component, vjslib; + +Component = require('./component.js'); +vjslib = require('./lib.js'); + /** * Display that an error has occurred making the video unplayable * @param {vjs.Player|Object} player * @param {Object=} options * @constructor */ -vjs.ErrorDisplay = vjs.Component.extend({ +ErrorDisplay = Component.extend({ init: function(player, options){ - vjs.Component.call(this, player, options); + Component.call(this, player, options); this.update(); - player.on('error', vjs.bind(this, this.update)); + player.on('error', vjslib.bind(this, this.update)); } }); -vjs.ErrorDisplay.prototype.createEl = function(){ - var el = vjs.Component.prototype.createEl.call(this, 'div', { +ErrorDisplay.prototype.createEl = function(){ + var el = Component.prototype.createEl.call(this, 'div', { className: 'vjs-error-display' }); - this.contentEl_ = vjs.createEl('div'); + this.contentEl_ = vjslib.createEl('div'); el.appendChild(this.contentEl_); return el; }; -vjs.ErrorDisplay.prototype.update = function(){ +ErrorDisplay.prototype.update = function(){ if (this.player().error()) { this.contentEl_.innerHTML = this.player().error().message; } }; + +module.exports = ErrorDisplay; diff --git a/src/js/events.js b/src/js/events.js index b8a232202f..99e91a87b8 100644 --- a/src/js/events.js +++ b/src/js/events.js @@ -1,3 +1,7 @@ +var on, off, cleanUpEvents, fixEvent, trigger, one, handleMultipleEvents, vjslib; + +vjslib = require('./lib.js'); + /** * @fileoverview Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/) * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible) @@ -15,19 +19,19 @@ * @param {Function} fn Event listener. * @private */ -vjs.on = function(elem, type, fn){ - if (vjs.obj.isArray(type)) { - return _handleMultipleEvents(vjs.on, elem, type, fn); +on = function(elem, type, fn){ + if (vjslib.obj.isArray(type)) { + return handleMultipleEvents(on, elem, type, fn); } - var data = vjs.getData(elem); + var data = vjslib.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 = vjs.guid++; + if (!fn.guid) fn.guid = vjslib.guid++; data.handlers[type].push(fn); @@ -37,7 +41,7 @@ vjs.on = function(elem, type, fn){ data.dispatcher = function (event){ if (data.disabled) return; - event = vjs.fixEvent(event); + event = fixEvent(event); var handlers = data.handlers[event.type]; @@ -72,23 +76,23 @@ vjs.on = function(elem, type, fn){ * @param {Function} fn Specific listener to remove. Don't incldue to remove listeners for an event type. * @private */ -vjs.off = function(elem, type, fn) { +off = function(elem, type, fn) { // Don't want to add a cache object through getData if not needed - if (!vjs.hasData(elem)) return; + if (!vjslib.hasData(elem)) return; - var data = vjs.getData(elem); + var data = vjslib.getData(elem); // If no events exist, nothing to unbind if (!data.handlers) { return; } - if (vjs.obj.isArray(type)) { - return _handleMultipleEvents(vjs.off, elem, type, fn); + if (vjslib.obj.isArray(type)) { + return handleMultipleEvents(off, elem, type, fn); } // Utility function var removeType = function(t){ data.handlers[t] = []; - vjs.cleanUpEvents(elem,t); + cleanUpEvents(elem,t); }; // Are we removing all bound events? @@ -117,7 +121,7 @@ vjs.off = function(elem, type, fn) { } } - vjs.cleanUpEvents(elem, type); + cleanUpEvents(elem, type); }; /** @@ -126,8 +130,8 @@ vjs.off = function(elem, type, fn) { * @param {String} type Type of event to clean up * @private */ -vjs.cleanUpEvents = function(elem, type) { - var data = vjs.getData(elem); +cleanUpEvents = function(elem, type) { + var data = vjslib.getData(elem); // Remove the events of a particular type if there are none left if (data.handlers[type].length === 0) { @@ -144,7 +148,7 @@ vjs.cleanUpEvents = function(elem, type) { } // Remove the events object if there are no types left - if (vjs.isEmpty(data.handlers)) { + if (vjslib.isEmpty(data.handlers)) { delete data.handlers; delete data.dispatcher; delete data.disabled; @@ -155,8 +159,8 @@ vjs.cleanUpEvents = function(elem, type) { } // Finally remove the expando if there is no data left - if (vjs.isEmpty(data)) { - vjs.removeData(elem); + if (vjslib.isEmpty(data)) { + vjslib.removeData(elem); } }; @@ -166,7 +170,7 @@ vjs.cleanUpEvents = function(elem, type) { * @return {Object} * @private */ -vjs.fixEvent = function(event) { +fixEvent = function(event) { function returnTrue() { return true; } function returnFalse() { return false; } @@ -276,11 +280,11 @@ vjs.fixEvent = function(event) { * @param {String} event Type of event to trigger * @private */ -vjs.trigger = function(elem, event) { +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 = (vjs.hasData(elem)) ? vjs.getData(elem) : {}; + var elemData = (vjslib.hasData(elem)) ? vjslib.getData(elem) : {}; var parent = elem.parentNode || elem.ownerDocument; // type = event.type || event, // handler; @@ -290,7 +294,7 @@ vjs.trigger = function(elem, event) { event = { type:event, target:elem }; } // Normalizes the event properties. - event = vjs.fixEvent(event); + event = fixEvent(event); // If the passed element has a dispatcher, executes the established handlers. if (elemData.dispatcher) { @@ -300,11 +304,11 @@ vjs.trigger = function(elem, event) { // Unless explicitly stopped or the event does not bubble (e.g. media events) // recursively calls this function to bubble the event up the DOM. if (parent && !event.isPropagationStopped() && event.bubbles !== false) { - vjs.trigger(parent, event); + trigger(parent, event); // If at the top of the DOM, triggers the default action unless disabled. } else if (!parent && !event.defaultPrevented) { - var targetData = vjs.getData(event.target); + var targetData = vjslib.getData(event.target); // Checks if the target has a default action for this event. if (event.target[event.type]) { @@ -349,17 +353,17 @@ vjs.trigger = function(elem, event) { * @param {Function} fn * @private */ -vjs.one = function(elem, type, fn) { - if (vjs.obj.isArray(type)) { - return _handleMultipleEvents(vjs.one, elem, type, fn); +one = function(elem, type, fn) { + if (vjslib.obj.isArray(type)) { + return handleMultipleEvents(one, elem, type, fn); } var func = function(){ - vjs.off(elem, type, func); + off(elem, type, func); fn.apply(this, arguments); }; // copy the guid to the new function so it can removed using the original function's ID - func.guid = fn.guid = fn.guid || vjs.guid++; - vjs.on(elem, type, func); + func.guid = fn.guid = fn.guid || vjslib.guid++; + on(elem, type, func); }; /** @@ -370,8 +374,15 @@ vjs.one = function(elem, type, fn) { * @param {Function} callback Event listener. * @private */ -function _handleMultipleEvents(fn, elem, type, callback) { - vjs.arr.forEach(type, function(type) { +handleMultipleEvents = function(fn, elem, type, callback) { + vjslib.arr.forEach(type, function(type) { fn(elem, type, callback); //Call the event method for each one of the types }); -} +}; + +module.exports = { + on: on, + off: off, + trigger: trigger, + one: one +}; diff --git a/src/js/fullscreen-api.js b/src/js/fullscreen-api.js index 911619c66c..bbd91a973f 100644 --- a/src/js/fullscreen-api.js +++ b/src/js/fullscreen-api.js @@ -1,82 +1,81 @@ -(function(){ - var apiMap, specApi, browserApi, i; +var fullscreenAPI, apiMap, specApi, browserApi, i; - /** - * Store the browser-specifc methods for the fullscreen API - * @type {Object|undefined} - * @private - */ - vjs.browser.fullscreenAPI; +/** + * Store the browser-specifc methods for the fullscreen API + * @type {Object|undefined} + * @private + */ +//vjs.browser.fullscreenAPI; - // browser API methods - // map approach from Screenful.js - https://github.com/sindresorhus/screenfull.js - apiMap = [ - // Spec: https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html - [ - 'requestFullscreen', - 'exitFullscreen', - 'fullscreenElement', - 'fullscreenEnabled', - 'fullscreenchange', - 'fullscreenerror' - ], - // WebKit - [ - 'webkitRequestFullscreen', - 'webkitExitFullscreen', - 'webkitFullscreenElement', - 'webkitFullscreenEnabled', - 'webkitfullscreenchange', - 'webkitfullscreenerror' - ], - // Old WebKit (Safari 5.1) - [ - 'webkitRequestFullScreen', - 'webkitCancelFullScreen', - 'webkitCurrentFullScreenElement', - 'webkitCancelFullScreen', - 'webkitfullscreenchange', - 'webkitfullscreenerror' - ], - // Mozilla - [ - 'mozRequestFullScreen', - 'mozCancelFullScreen', - 'mozFullScreenElement', - 'mozFullScreenEnabled', - 'mozfullscreenchange', - 'mozfullscreenerror' - ], - // Microsoft - [ - 'msRequestFullscreen', - 'msExitFullscreen', - 'msFullscreenElement', - 'msFullscreenEnabled', - 'MSFullscreenChange', - 'MSFullscreenError' - ] - ]; +// browser API methods +// map approach from Screenful.js - https://github.com/sindresorhus/screenfull.js +apiMap = [ + // Spec: https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html + [ + 'requestFullscreen', + 'exitFullscreen', + 'fullscreenElement', + 'fullscreenEnabled', + 'fullscreenchange', + 'fullscreenerror' + ], + // WebKit + [ + 'webkitRequestFullscreen', + 'webkitExitFullscreen', + 'webkitFullscreenElement', + 'webkitFullscreenEnabled', + 'webkitfullscreenchange', + 'webkitfullscreenerror' + ], + // Old WebKit (Safari 5.1) + [ + 'webkitRequestFullScreen', + 'webkitCancelFullScreen', + 'webkitCurrentFullScreenElement', + 'webkitCancelFullScreen', + 'webkitfullscreenchange', + 'webkitfullscreenerror' + ], + // Mozilla + [ + 'mozRequestFullScreen', + 'mozCancelFullScreen', + 'mozFullScreenElement', + 'mozFullScreenEnabled', + 'mozfullscreenchange', + 'mozfullscreenerror' + ], + // Microsoft + [ + 'msRequestFullscreen', + 'msExitFullscreen', + 'msFullscreenElement', + 'msFullscreenEnabled', + 'MSFullscreenChange', + 'MSFullscreenError' + ] +]; - specApi = apiMap[0]; +specApi = apiMap[0]; - // determine the supported set of functions - for (i=0; i= 10; +Flash.isSupported = function(){ + return Flash.version()[0] >= 10; // return swfobject.hasFlashPlayerVersion('10'); }; -vjs.Flash.canPlaySource = function(srcObj){ +Flash.canPlaySource = function(srcObj){ var type; if (!srcObj.type) { @@ -373,25 +379,25 @@ vjs.Flash.canPlaySource = function(srcObj){ } type = srcObj.type.replace(/;.*/,'').toLowerCase(); - if (type in vjs.Flash.formats || type in vjs.Flash.streamingFormats) { + if (type in Flash.formats || type in Flash.streamingFormats) { return 'maybe'; } }; -vjs.Flash.formats = { +Flash.formats = { 'video/flv': 'FLV', 'video/x-flv': 'FLV', 'video/mp4': 'MP4', 'video/m4v': 'MP4' }; -vjs.Flash.streamingFormats = { +Flash.streamingFormats = { 'rtmp/mp4': 'MP4', 'rtmp/flv': 'FLV' }; -vjs.Flash['onReady'] = function(currSwf){ - var el = vjs.el(currSwf); +Flash['onReady'] = function(currSwf){ + var el = vjslib.el(currSwf); // Get player from box // On firefox reloads, el might already have a player @@ -404,12 +410,12 @@ vjs.Flash['onReady'] = function(currSwf){ // Update reference to playback technology element tech.el_ = el; - vjs.Flash.checkReady(tech); + Flash.checkReady(tech); }; // The SWF isn't alwasy ready when it says it is. Sometimes the API functions still need to be added to the object. // If it's not ready, we set a timeout to check again shortly. -vjs.Flash.checkReady = function(tech){ +Flash.checkReady = function(tech){ // Check if API property exists if (tech.el().vjs_getProperty) { @@ -421,21 +427,21 @@ vjs.Flash.checkReady = function(tech){ } else { setTimeout(function(){ - vjs.Flash.checkReady(tech); + Flash.checkReady(tech); }, 50); } }; // Trigger events from the swf on the player -vjs.Flash['onEvent'] = function(swfID, eventName){ - var player = vjs.el(swfID)['player']; +Flash['onEvent'] = function(swfID, eventName){ + var player = vjslib.el(swfID)['player']; player.trigger(eventName); }; // Log errors from the swf -vjs.Flash['onError'] = function(swfID, err){ - var player = vjs.el(swfID)['player']; +Flash['onError'] = function(swfID, err){ + var player = vjslib.el(swfID)['player']; var msg = 'FLASH: '+err; if (err == 'srcnotfound') { @@ -448,7 +454,7 @@ vjs.Flash['onError'] = function(swfID, err){ }; // Flash Version Check -vjs.Flash.version = function(){ +Flash.version = function(){ var version = '0,0,0'; // IE @@ -467,11 +473,11 @@ vjs.Flash.version = function(){ }; // Flash embedding method. Only used in non-iframe mode -vjs.Flash.embed = function(swf, placeHolder, flashVars, params, attributes){ - var code = vjs.Flash.getEmbedCode(swf, flashVars, params, attributes), +Flash.embed = function(swf, placeHolder, flashVars, params, attributes){ + var code = Flash.getEmbedCode(swf, flashVars, params, attributes), // Get element by embedding code and retrieving created element - obj = vjs.createEl('div', { innerHTML: code }).childNodes[0], + obj = vjslib.createEl('div', { innerHTML: code }).childNodes[0], par = placeHolder.parentNode ; @@ -489,7 +495,7 @@ vjs.Flash.embed = function(swf, placeHolder, flashVars, params, attributes){ }; -vjs.Flash.getEmbedCode = function(swf, flashVars, params, attributes){ +Flash.getEmbedCode = function(swf, flashVars, params, attributes){ var objTag = ''; }); - attributes = vjs.obj.merge({ + attributes = vjslib.obj.merge({ // Add swf to attributes (need both for IE and Others to work) 'data': swf, @@ -527,18 +533,18 @@ vjs.Flash.getEmbedCode = function(swf, flashVars, params, attributes){ }, attributes); // Create Attributes string - vjs.obj.each(attributes, function(key, val){ + vjslib.obj.each(attributes, function(key, val){ attrsString += (key + '="' + val + '" '); }); return objTag + attrsString + '>' + paramsString + ''; }; -vjs.Flash.streamFromParts = function(connection, stream) { +Flash.streamFromParts = function(connection, stream) { return connection + '&' + stream; }; -vjs.Flash.streamToParts = function(src) { +Flash.streamToParts = function(src) { var parts = { connection: '', stream: '' @@ -570,14 +576,16 @@ vjs.Flash.streamToParts = function(src) { return parts; }; -vjs.Flash.isStreamingType = function(srcType) { - return srcType in vjs.Flash.streamingFormats; +Flash.isStreamingType = function(srcType) { + return srcType in Flash.streamingFormats; }; // RTMP has four variations, any string starting // with one of these protocols should be valid -vjs.Flash.RTMP_RE = /^rtmp[set]?:\/\//i; +Flash.RTMP_RE = /^rtmp[set]?:\/\//i; -vjs.Flash.isStreamingSrc = function(src) { - return vjs.Flash.RTMP_RE.test(src); +Flash.isStreamingSrc = function(src) { + return Flash.RTMP_RE.test(src); }; + +module.exports = Flash; diff --git a/src/js/media/html5.js b/src/js/media/html5.js index 19dcc3cf7b..208c038aff 100644 --- a/src/js/media/html5.js +++ b/src/js/media/html5.js @@ -1,3 +1,9 @@ +var Html5, MediaTechController, vjslib, vjsevents; + +MediaTechController = require('./media.js'); +vjslib = require('../lib.js'); +vjsevents = require('../events.js'); + /** * @fileoverview HTML5 Media Controller - Wrapper for HTML5 Media API */ @@ -9,22 +15,22 @@ * @param {Function=} ready * @constructor */ -vjs.Html5 = vjs.MediaTechController.extend({ +Html5 = MediaTechController.extend({ /** @constructor */ init: function(player, options, ready){ // volume cannot be changed from 1 on iOS - this.features['volumeControl'] = vjs.Html5.canControlVolume(); + this.features['volumeControl'] = Html5.canControlVolume(); // just in case; or is it excessively... - this.features['playbackRate'] = vjs.Html5.canControlPlaybackRate(); + this.features['playbackRate'] = Html5.canControlPlaybackRate(); // In iOS, if you move a video element in the DOM, it breaks video playback. - this.features['movingMediaElementInDOM'] = !vjs.IS_IOS; + this.features['movingMediaElementInDOM'] = !vjslib.IS_IOS; // HTML video is able to automatically resize when going to fullscreen this.features['fullscreenResize'] = true; - vjs.MediaTechController.call(this, player, options, ready); + MediaTechController.call(this, player, options, ready); this.setupTriggers(); var source = options['source']; @@ -38,7 +44,7 @@ vjs.Html5 = vjs.MediaTechController.extend({ // 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 (vjs.TOUCH_ENABLED && player.options()['nativeControlsForTouch'] !== false) { + if (vjslib.TOUCH_ENABLED && player.options()['nativeControlsForTouch'] !== false) { this.useNativeControls(); } @@ -57,11 +63,11 @@ vjs.Html5 = vjs.MediaTechController.extend({ } }); -vjs.Html5.prototype.dispose = function(){ - vjs.MediaTechController.prototype.dispose.call(this); +Html5.prototype.dispose = function(){ + MediaTechController.prototype.dispose.call(this); }; -vjs.Html5.prototype.createEl = function(){ +Html5.prototype.createEl = function(){ var player = this.player_, // If possible, reuse original tag for HTML5 playback technology element el = player.tag, @@ -76,11 +82,11 @@ vjs.Html5.prototype.createEl = function(){ // If the original tag is still there, clone and remove it. if (el) { clone = el.cloneNode(false); - vjs.Html5.disposeMediaElement(el); + Html5.disposeMediaElement(el); el = clone; player.tag = null; } else { - el = vjs.createEl('video', { + el = vjslib.createEl('video', { id:player.id() + '_html5_api', className:'vjs-tech' }); @@ -88,7 +94,7 @@ vjs.Html5.prototype.createEl = function(){ // associate the player with the new tag el['player'] = player; - vjs.insertFirst(el, player.el()); + vjslib.insertFirst(el, player.el()); } // Update specific tag settings, in case they were overridden @@ -107,13 +113,13 @@ vjs.Html5.prototype.createEl = function(){ // Make video events trigger player events // May seem verbose here, but makes other APIs possible. // Triggers removed using this.off when disposed -vjs.Html5.prototype.setupTriggers = function(){ - for (var i = vjs.Html5.Events.length - 1; i >= 0; i--) { - vjs.on(this.el_, vjs.Html5.Events[i], vjs.bind(this, this.eventHandler)); +Html5.prototype.setupTriggers = function(){ + for (var i = Html5.Events.length - 1; i >= 0; i--) { + vjsevents.on(this.el_, Html5.Events[i], vjslib.bind(this, this.eventHandler)); } }; -vjs.Html5.prototype.eventHandler = function(evt){ +Html5.prototype.eventHandler = function(evt){ // In the case of an error, set the error prop on the player // and let the player handle triggering the event. if (evt.type == 'error') { @@ -128,7 +134,7 @@ vjs.Html5.prototype.eventHandler = function(evt){ } }; -vjs.Html5.prototype.useNativeControls = function(){ +Html5.prototype.useNativeControls = function(){ var tech, player, controlsOn, controlsOff, cleanUp; tech = this; @@ -160,43 +166,43 @@ vjs.Html5.prototype.useNativeControls = function(){ }; -vjs.Html5.prototype.play = function(){ this.el_.play(); }; -vjs.Html5.prototype.pause = function(){ this.el_.pause(); }; -vjs.Html5.prototype.paused = function(){ return this.el_.paused; }; +Html5.prototype.play = function(){ this.el_.play(); }; +Html5.prototype.pause = function(){ this.el_.pause(); }; +Html5.prototype.paused = function(){ return this.el_.paused; }; -vjs.Html5.prototype.currentTime = function(){ return this.el_.currentTime; }; -vjs.Html5.prototype.setCurrentTime = function(seconds){ +Html5.prototype.currentTime = function(){ return this.el_.currentTime; }; +Html5.prototype.setCurrentTime = function(seconds){ try { this.el_.currentTime = seconds; } catch(e) { - vjs.log(e, 'Video is not ready. (Video.js)'); + vjslib.log(e, 'Video is not ready. (Video.js)'); // this.warning(VideoJS.warnings.videoNotReady); } }; -vjs.Html5.prototype.duration = function(){ return this.el_.duration || 0; }; -vjs.Html5.prototype.buffered = function(){ return this.el_.buffered; }; +Html5.prototype.duration = function(){ return this.el_.duration || 0; }; +Html5.prototype.buffered = function(){ return this.el_.buffered; }; -vjs.Html5.prototype.volume = function(){ return this.el_.volume; }; -vjs.Html5.prototype.setVolume = function(percentAsDecimal){ this.el_.volume = percentAsDecimal; }; -vjs.Html5.prototype.muted = function(){ return this.el_.muted; }; -vjs.Html5.prototype.setMuted = function(muted){ this.el_.muted = muted; }; +Html5.prototype.volume = function(){ return this.el_.volume; }; +Html5.prototype.setVolume = function(percentAsDecimal){ this.el_.volume = percentAsDecimal; }; +Html5.prototype.muted = function(){ return this.el_.muted; }; +Html5.prototype.setMuted = function(muted){ this.el_.muted = muted; }; -vjs.Html5.prototype.width = function(){ return this.el_.offsetWidth; }; -vjs.Html5.prototype.height = function(){ return this.el_.offsetHeight; }; +Html5.prototype.width = function(){ return this.el_.offsetWidth; }; +Html5.prototype.height = function(){ return this.el_.offsetHeight; }; -vjs.Html5.prototype.supportsFullScreen = function(){ +Html5.prototype.supportsFullScreen = function(){ if (typeof this.el_.webkitEnterFullScreen == 'function') { // Seems to be broken in Chromium/Chrome && Safari in Leopard - if (/Android/.test(vjs.USER_AGENT) || !/Chrome|Mac OS X 10.5/.test(vjs.USER_AGENT)) { + if (/Android/.test(vjslib.USER_AGENT) || !/Chrome|Mac OS X 10.5/.test(vjslib.USER_AGENT)) { return true; } } return false; }; -vjs.Html5.prototype.enterFullScreen = function(){ +Html5.prototype.enterFullScreen = function(){ var video = this.el_; if (video.paused && video.networkState <= video.HAVE_METADATA) { // attempt to prime the video element for programmatic access @@ -213,56 +219,56 @@ vjs.Html5.prototype.enterFullScreen = function(){ video.webkitEnterFullScreen(); } }; -vjs.Html5.prototype.exitFullScreen = function(){ +Html5.prototype.exitFullScreen = function(){ this.el_.webkitExitFullScreen(); }; -vjs.Html5.prototype.src = function(src){ this.el_.src = src; }; -vjs.Html5.prototype.load = function(){ this.el_.load(); }; -vjs.Html5.prototype.currentSrc = function(){ return this.el_.currentSrc; }; +Html5.prototype.src = function(src){ this.el_.src = src; }; +Html5.prototype.load = function(){ this.el_.load(); }; +Html5.prototype.currentSrc = function(){ return this.el_.currentSrc; }; -vjs.Html5.prototype.poster = function(){ return this.el_.poster; }; -vjs.Html5.prototype.setPoster = function(val){ this.el_.poster = val; }; +Html5.prototype.poster = function(){ return this.el_.poster; }; +Html5.prototype.setPoster = function(val){ this.el_.poster = val; }; -vjs.Html5.prototype.preload = function(){ return this.el_.preload; }; -vjs.Html5.prototype.setPreload = function(val){ this.el_.preload = val; }; +Html5.prototype.preload = function(){ return this.el_.preload; }; +Html5.prototype.setPreload = function(val){ this.el_.preload = val; }; -vjs.Html5.prototype.autoplay = function(){ return this.el_.autoplay; }; -vjs.Html5.prototype.setAutoplay = function(val){ this.el_.autoplay = val; }; +Html5.prototype.autoplay = function(){ return this.el_.autoplay; }; +Html5.prototype.setAutoplay = function(val){ this.el_.autoplay = val; }; -vjs.Html5.prototype.controls = function(){ return this.el_.controls; }; -vjs.Html5.prototype.setControls = function(val){ this.el_.controls = !!val; }; +Html5.prototype.controls = function(){ return this.el_.controls; }; +Html5.prototype.setControls = function(val){ this.el_.controls = !!val; }; -vjs.Html5.prototype.loop = function(){ return this.el_.loop; }; -vjs.Html5.prototype.setLoop = function(val){ this.el_.loop = val; }; +Html5.prototype.loop = function(){ return this.el_.loop; }; +Html5.prototype.setLoop = function(val){ this.el_.loop = val; }; -vjs.Html5.prototype.error = function(){ return this.el_.error; }; -vjs.Html5.prototype.seeking = function(){ return this.el_.seeking; }; -vjs.Html5.prototype.ended = function(){ return this.el_.ended; }; -vjs.Html5.prototype.defaultMuted = function(){ return this.el_.defaultMuted; }; +Html5.prototype.error = function(){ return this.el_.error; }; +Html5.prototype.seeking = function(){ return this.el_.seeking; }; +Html5.prototype.ended = function(){ return this.el_.ended; }; +Html5.prototype.defaultMuted = function(){ return this.el_.defaultMuted; }; -vjs.Html5.prototype.playbackRate = function(){ return this.el_.playbackRate; }; -vjs.Html5.prototype.setPlaybackRate = function(val){ this.el_.playbackRate = val; }; +Html5.prototype.playbackRate = function(){ return this.el_.playbackRate; }; +Html5.prototype.setPlaybackRate = function(val){ this.el_.playbackRate = val; }; -vjs.Html5.prototype.networkState = function(){ return this.el_.networkState; }; +Html5.prototype.networkState = function(){ return this.el_.networkState; }; /* HTML5 Support Testing ---------------------------------------------------- */ -vjs.Html5.isSupported = function(){ +Html5.isSupported = function(){ // ie9 with no Media Player is a LIAR! (#984) try { - vjs.TEST_VID['volume'] = 0.5; + vjslib.TEST_VID['volume'] = 0.5; } catch (e) { return false; } - return !!vjs.TEST_VID.canPlayType; + return !!vjslib.TEST_VID.canPlayType; }; -vjs.Html5.canPlaySource = function(srcObj){ +Html5.canPlaySource = function(srcObj){ // IE9 on Windows 7 without MediaPlayer throws an error here // https://github.com/videojs/video.js/issues/519 try { - return !!vjs.TEST_VID.canPlayType(srcObj.type); + return !!vjslib.TEST_VID.canPlayType(srcObj.type); } catch(e) { return ''; } @@ -271,16 +277,16 @@ vjs.Html5.canPlaySource = function(srcObj){ // Check Media Type }; -vjs.Html5.canControlVolume = function(){ - var volume = vjs.TEST_VID.volume; - vjs.TEST_VID.volume = (volume / 2) + 0.1; - return volume !== vjs.TEST_VID.volume; +Html5.canControlVolume = function(){ + var volume = vjslib.TEST_VID.volume; + vjslib.TEST_VID.volume = (volume / 2) + 0.1; + return volume !== vjslib.TEST_VID.volume; }; -vjs.Html5.canControlPlaybackRate = function(){ - var playbackRate = vjs.TEST_VID.playbackRate; - vjs.TEST_VID.playbackRate = (playbackRate / 2) + 0.1; - return playbackRate !== vjs.TEST_VID.playbackRate; +Html5.canControlPlaybackRate = function(){ + var playbackRate = vjslib.TEST_VID.playbackRate; + vjslib.TEST_VID.playbackRate = (playbackRate / 2) + 0.1; + return playbackRate !== vjslib.TEST_VID.playbackRate; }; // HTML5 Feature detection and Device Fixes --------------------------------- // @@ -289,14 +295,14 @@ vjs.Html5.canControlPlaybackRate = function(){ mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i, mp4RE = /^video\/mp4/i; - vjs.Html5.patchCanPlayType = function() { + Html5.patchCanPlayType = function() { // Android 4.0 and above can play HLS to some extent but it reports being unable to do so - if (vjs.ANDROID_VERSION >= 4.0) { + if (vjslib.ANDROID_VERSION >= 4.0) { if (!canPlayType) { - canPlayType = vjs.TEST_VID.constructor.prototype.canPlayType; + canPlayType = vjslib.TEST_VID.constructor.prototype.canPlayType; } - vjs.TEST_VID.constructor.prototype.canPlayType = function(type) { + vjslib.TEST_VID.constructor.prototype.canPlayType = function(type) { if (type && mpegurlRE.test(type)) { return 'maybe'; } @@ -305,12 +311,12 @@ vjs.Html5.canControlPlaybackRate = function(){ } // Override Android 2.2 and less canPlayType method which is broken - if (vjs.IS_OLD_ANDROID) { + if (vjslib.IS_OLD_ANDROID) { if (!canPlayType) { - canPlayType = vjs.TEST_VID.constructor.prototype.canPlayType; + canPlayType = vjslib.TEST_VID.constructor.prototype.canPlayType; } - vjs.TEST_VID.constructor.prototype.canPlayType = function(type){ + vjslib.TEST_VID.constructor.prototype.canPlayType = function(type){ if (type && mp4RE.test(type)) { return 'maybe'; } @@ -319,21 +325,21 @@ vjs.Html5.canControlPlaybackRate = function(){ } }; - vjs.Html5.unpatchCanPlayType = function() { - var r = vjs.TEST_VID.constructor.prototype.canPlayType; - vjs.TEST_VID.constructor.prototype.canPlayType = canPlayType; + Html5.unpatchCanPlayType = function() { + var r = vjslib.TEST_VID.constructor.prototype.canPlayType; + vjslib.TEST_VID.constructor.prototype.canPlayType = canPlayType; canPlayType = null; return r; }; // by default, patch the video element - vjs.Html5.patchCanPlayType(); + Html5.patchCanPlayType(); })(); // List of all HTML5 events (various uses). -vjs.Html5.Events = 'loadstart,suspend,abort,error,emptied,stalled,loadedmetadata,loadeddata,canplay,canplaythrough,playing,waiting,seeking,seeked,ended,durationchange,timeupdate,progress,play,pause,ratechange,volumechange'.split(','); +Html5.Events = 'loadstart,suspend,abort,error,emptied,stalled,loadedmetadata,loadeddata,canplay,canplaythrough,playing,waiting,seeking,seeked,ended,durationchange,timeupdate,progress,play,pause,ratechange,volumechange'.split(','); -vjs.Html5.disposeMediaElement = function(el){ +Html5.disposeMediaElement = function(el){ if (!el) { return; } el['player'] = null; @@ -364,3 +370,5 @@ vjs.Html5.disposeMediaElement = function(el){ })(); } }; + +module.exports = Html5; diff --git a/src/js/media/loader.js b/src/js/media/loader.js index 98db7dbfc6..077f0d959c 100644 --- a/src/js/media/loader.js +++ b/src/js/media/loader.js @@ -1,20 +1,27 @@ +var MediaLoader, Component, vjslib; + +Component = require('../component.js'); +vjslib = require('../lib.js'); + /** * The Media Loader is the component that decides which playback technology to load * when the player is initialized. * * @constructor */ -vjs.MediaLoader = vjs.Component.extend({ +MediaLoader = Component.extend({ /** @constructor */ init: function(player, options, ready){ - vjs.Component.call(this, player, options, ready); + var components = require('../components.js'); + + Component.call(this, player, options, ready); // If there are no sources when the player is initialized, // load the first supported playback technology. if (!player.options_['sources'] || player.options_['sources'].length === 0) { for (var i=0,j=player.options_['techOrder']; i 0) { @@ -283,12 +299,12 @@ vjs.Player.prototype.loadTech = function(techName, source){ } // Initialize tech instance - this.tech = new window['videojs'][techName](this, techOptions); + this.tech = new components[techName](this, techOptions); this.tech.ready(techReady); }; -vjs.Player.prototype.unloadTech = function(){ +Player.prototype.unloadTech = function(){ this.isReady_ = false; // Turn off any manual progress or timeupdate tracking @@ -319,7 +335,7 @@ vjs.Player.prototype.unloadTech = function(){ ================================================================================ */ // Manually trigger progress events based on changes to the buffered amount // Many flash players and older HTML5 browsers don't send progress or progress-like events -vjs.Player.prototype.manualProgressOn = function(){ +Player.prototype.manualProgressOn = function(){ this.manualProgress = true; // Trigger progress watching when a source begins loading @@ -341,14 +357,14 @@ vjs.Player.prototype.manualProgressOn = function(){ } }; -vjs.Player.prototype.manualProgressOff = function(){ +Player.prototype.manualProgressOff = function(){ this.manualProgress = false; this.stopTrackingProgress(); }; -vjs.Player.prototype.trackProgress = function(){ +Player.prototype.trackProgress = function(){ - this.progressInterval = setInterval(vjs.bind(this, function(){ + this.progressInterval = setInterval(vjslib.bind(this, function(){ // Don't trigger unless buffered amount is greater than last time // log(this.cache_.bufferEnd, this.buffered().end(0), this.duration()) /* TODO: update for multiple buffered regions */ @@ -360,10 +376,10 @@ vjs.Player.prototype.trackProgress = function(){ } }), 500); }; -vjs.Player.prototype.stopTrackingProgress = function(){ clearInterval(this.progressInterval); }; +Player.prototype.stopTrackingProgress = function(){ clearInterval(this.progressInterval); }; /*! Time Tracking -------------------------------------------------------------- */ -vjs.Player.prototype.manualTimeUpdatesOn = function(){ +Player.prototype.manualTimeUpdatesOn = function(){ this.manualTimeUpdates = true; this.on('play', this.trackCurrentTime); @@ -381,22 +397,22 @@ vjs.Player.prototype.manualTimeUpdatesOn = function(){ } }; -vjs.Player.prototype.manualTimeUpdatesOff = function(){ +Player.prototype.manualTimeUpdatesOff = function(){ this.manualTimeUpdates = false; this.stopTrackingCurrentTime(); this.off('play', this.trackCurrentTime); this.off('pause', this.stopTrackingCurrentTime); }; -vjs.Player.prototype.trackCurrentTime = function(){ +Player.prototype.trackCurrentTime = function(){ if (this.currentTimeInterval) { this.stopTrackingCurrentTime(); } - this.currentTimeInterval = setInterval(vjs.bind(this, function(){ + this.currentTimeInterval = setInterval(vjslib.bind(this, function(){ this.trigger('timeupdate'); }), 250); // 42 = 24 fps // 250 is what Webkit uses // FF uses 15 }; // Turn off play progress tracking (when paused or dragging) -vjs.Player.prototype.stopTrackingCurrentTime = function(){ +Player.prototype.stopTrackingCurrentTime = function(){ clearInterval(this.currentTimeInterval); // #1002 - if the video ends right before the next timeupdate would happen, @@ -410,7 +426,7 @@ vjs.Player.prototype.stopTrackingCurrentTime = function(){ * Fired when the user agent begins looking for media data * @event loadstart */ -vjs.Player.prototype.onLoadStart = function() { +Player.prototype.onLoadStart = function() { // TODO: Update to use `emptied` event instead. See #1277. // reset the error state @@ -430,9 +446,9 @@ vjs.Player.prototype.onLoadStart = function() { } }; -vjs.Player.prototype.hasStarted_ = false; +Player.prototype.hasStarted_ = false; -vjs.Player.prototype.hasStarted = function(hasStarted){ +Player.prototype.hasStarted = function(hasStarted){ if (hasStarted !== undefined) { // only update if this is a new value if (this.hasStarted_ !== hasStarted) { @@ -454,27 +470,27 @@ vjs.Player.prototype.hasStarted = function(hasStarted){ * Fired when the player has initial duration and dimension information * @event loadedmetadata */ -vjs.Player.prototype.onLoadedMetaData; +Player.prototype.onLoadedMetaData; /** * Fired when the player has downloaded data at the current playback position * @event loadeddata */ -vjs.Player.prototype.onLoadedData; +Player.prototype.onLoadedData; /** * Fired when the player has finished downloading the source data * @event loadedalldata */ -vjs.Player.prototype.onLoadedAllData; +Player.prototype.onLoadedAllData; /** * Fired whenever the media begins or resumes playback * @event play */ -vjs.Player.prototype.onPlay = function(){ - vjs.removeClass(this.el_, 'vjs-paused'); - vjs.addClass(this.el_, 'vjs-playing'); +Player.prototype.onPlay = function(){ + vjslib.removeClass(this.el_, 'vjs-paused'); + vjslib.addClass(this.el_, 'vjs-playing'); }; /** @@ -486,7 +502,7 @@ vjs.Player.prototype.onPlay = function(){ * * @event firstplay */ -vjs.Player.prototype.onFirstPlay = function(){ +Player.prototype.onFirstPlay = function(){ //If the first starttime attribute is specified //then we will start at the given offset in seconds if(this.options_['starttime']){ @@ -500,9 +516,9 @@ vjs.Player.prototype.onFirstPlay = function(){ * Fired whenever the media has been paused * @event pause */ -vjs.Player.prototype.onPause = function(){ - vjs.removeClass(this.el_, 'vjs-playing'); - vjs.addClass(this.el_, 'vjs-paused'); +Player.prototype.onPause = function(){ + vjslib.removeClass(this.el_, 'vjs-playing'); + vjslib.addClass(this.el_, 'vjs-paused'); }; /** @@ -512,13 +528,13 @@ vjs.Player.prototype.onPause = function(){ * playback technology in use. * @event timeupdate */ -vjs.Player.prototype.onTimeUpdate; +Player.prototype.onTimeUpdate; /** * Fired while the user agent is downloading media data * @event progress */ -vjs.Player.prototype.onProgress = function(){ +Player.prototype.onProgress = function(){ // Add custom event for when source is finished downloading. if (this.bufferedPercent() == 1) { this.trigger('loadedalldata'); @@ -529,7 +545,7 @@ vjs.Player.prototype.onProgress = function(){ * Fired when the end of the media resource is reached (currentTime == duration) * @event ended */ -vjs.Player.prototype.onEnded = function(){ +Player.prototype.onEnded = function(){ if (this.options_['loop']) { this.currentTime(0); this.play(); @@ -540,7 +556,7 @@ vjs.Player.prototype.onEnded = function(){ * Fired when the duration of the media resource is first known or changed * @event durationchange */ -vjs.Player.prototype.onDurationChange = function(){ +Player.prototype.onDurationChange = function(){ // Allows for cacheing value instead of asking player each time. // We need to get the techGet response and check for a value so we don't // accidentally cause the stack to blow up. @@ -563,13 +579,13 @@ vjs.Player.prototype.onDurationChange = function(){ * Fired when the volume changes * @event volumechange */ -vjs.Player.prototype.onVolumeChange; +Player.prototype.onVolumeChange; /** * Fired when the player switches in or out of fullscreen mode * @event fullscreenchange */ -vjs.Player.prototype.onFullscreenChange = function() { +Player.prototype.onFullscreenChange = function() { if (this.isFullscreen()) { this.addClass('vjs-fullscreen'); } else { @@ -584,14 +600,14 @@ vjs.Player.prototype.onFullscreenChange = function() { * Object for cached values. * @private */ -vjs.Player.prototype.cache_; +Player.prototype.cache_; -vjs.Player.prototype.getCache = function(){ +Player.prototype.getCache = function(){ return this.cache_; }; // Pass values to the playback tech -vjs.Player.prototype.techCall = function(method, arg){ +Player.prototype.techCall = function(method, arg){ // If it's not ready yet, call method when it is if (this.tech && !this.tech.isReady_) { this.tech.ready(function(){ @@ -603,14 +619,14 @@ vjs.Player.prototype.techCall = function(method, arg){ try { this.tech[method](arg); } catch(e) { - vjs.log(e); + vjslib.log(e); throw e; } } }; // Get calls can't wait for the tech, and sometimes don't need to. -vjs.Player.prototype.techGet = function(method){ +Player.prototype.techGet = function(method){ if (this.tech && this.tech.isReady_) { // Flash likes to die and reload when you hide or reposition it. @@ -621,14 +637,14 @@ vjs.Player.prototype.techGet = function(method){ } catch(e) { // When building additional tech libs, an expected method may not be defined yet if (this.tech[method] === undefined) { - vjs.log('Video.js: ' + method + ' method not defined for '+this.techName+' playback technology.', e); + vjslib.log('Video.js: ' + method + ' method not defined for '+this.techName+' playback technology.', e); } else { // When a method isn't available on the object it throws a TypeError if (e.name == 'TypeError') { - vjs.log('Video.js: ' + method + ' unavailable on '+this.techName+' playback technology element.', e); + vjslib.log('Video.js: ' + method + ' unavailable on '+this.techName+' playback technology element.', e); this.tech.isReady_ = false; } else { - vjs.log(e); + vjslib.log(e); } } throw e; @@ -645,7 +661,7 @@ vjs.Player.prototype.techGet = function(method){ * * @return {vjs.Player} self */ -vjs.Player.prototype.play = function(){ +Player.prototype.play = function(){ this.techCall('play'); return this; }; @@ -657,7 +673,7 @@ vjs.Player.prototype.play = function(){ * * @return {vjs.Player} self */ -vjs.Player.prototype.pause = function(){ +Player.prototype.pause = function(){ this.techCall('pause'); return this; }; @@ -670,7 +686,7 @@ vjs.Player.prototype.pause = function(){ * * @return {Boolean} false if the media is currently playing, or true otherwise */ -vjs.Player.prototype.paused = function(){ +Player.prototype.paused = function(){ // The initial state of paused should be true (in Safari it's actually false) return (this.techGet('paused') === false) ? false : true; }; @@ -688,7 +704,7 @@ vjs.Player.prototype.paused = function(){ * @return {Number} The time in seconds, when not setting * @return {vjs.Player} self, when the current time is set */ -vjs.Player.prototype.currentTime = function(seconds){ +Player.prototype.currentTime = function(seconds){ if (seconds !== undefined) { this.techCall('setCurrentTime', seconds); @@ -719,7 +735,7 @@ vjs.Player.prototype.currentTime = function(seconds){ * * @return {Number} The duration of the video in seconds */ -vjs.Player.prototype.duration = function(seconds){ +Player.prototype.duration = function(seconds){ if (seconds !== undefined) { // cache the last set value for optimiized scrubbing (esp. Flash) @@ -736,7 +752,7 @@ vjs.Player.prototype.duration = function(seconds){ }; // Calculates how much time is left. Not in spec, but useful. -vjs.Player.prototype.remainingTime = function(){ +Player.prototype.remainingTime = function(){ return this.duration() - this.currentTime(); }; @@ -765,7 +781,7 @@ vjs.Player.prototype.remainingTime = function(){ * * @return {Object} A mock TimeRange object (following HTML spec) */ -vjs.Player.prototype.buffered = function(){ +Player.prototype.buffered = function(){ var buffered = this.techGet('buffered'), start = 0, buflast = buffered.length - 1, @@ -778,7 +794,7 @@ vjs.Player.prototype.buffered = function(){ this.cache_.bufferEnd = end; } - return vjs.createTimeRange(start, end); + return vjslib.createTimeRange(start, end); }; /** @@ -791,7 +807,7 @@ vjs.Player.prototype.buffered = function(){ * * @return {Number} A decimal between 0 and 1 representing the percent */ -vjs.Player.prototype.bufferedPercent = function(){ +Player.prototype.bufferedPercent = function(){ return (this.duration()) ? this.buffered().end(0) / this.duration() : 0; }; @@ -810,14 +826,14 @@ vjs.Player.prototype.bufferedPercent = function(){ * @return {Number} The current volume, when getting * @return {vjs.Player} self, when setting */ -vjs.Player.prototype.volume = function(percentAsDecimal){ +Player.prototype.volume = function(percentAsDecimal){ var vol; if (percentAsDecimal !== undefined) { vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); // Force value to between 0 and 1 this.cache_.volume = vol; this.techCall('setVolume', vol); - vjs.setLocalStorage('volume', vol); + vjslib.setLocalStorage('volume', vol); return this; } @@ -840,7 +856,7 @@ vjs.Player.prototype.volume = function(percentAsDecimal){ * @return {Boolean} True if mute is on, false if not, when getting * @return {vjs.Player} self, when setting mute */ -vjs.Player.prototype.muted = function(muted){ +Player.prototype.muted = function(muted){ if (muted !== undefined) { this.techCall('setMuted', muted); return this; @@ -850,7 +866,7 @@ vjs.Player.prototype.muted = function(muted){ // Check if current tech can support native fullscreen // (e.g. with built in controls lik iOS, so not our flash swf) -vjs.Player.prototype.supportsFullScreen = function(){ +Player.prototype.supportsFullScreen = function(){ return this.techGet('supportsFullScreen') || false; }; @@ -859,7 +875,7 @@ vjs.Player.prototype.supportsFullScreen = function(){ * @type {Boolean} * @private */ -vjs.Player.prototype.isFullscreen_ = false; +Player.prototype.isFullscreen_ = false; /** * Check if the player is in fullscreen mode @@ -878,7 +894,7 @@ vjs.Player.prototype.isFullscreen_ = false; * @return {Boolean} true if fullscreen, false if not * @return {vjs.Player} self, when setting */ -vjs.Player.prototype.isFullscreen = function(isFS){ +Player.prototype.isFullscreen = function(isFS){ if (isFS !== undefined) { this.isFullscreen_ = !!isFS; return this; @@ -890,8 +906,8 @@ vjs.Player.prototype.isFullscreen = function(isFS){ * Old naming for isFullscreen() * @deprecated for lowercase 's' version */ -vjs.Player.prototype.isFullScreen = function(isFS){ - vjs.log.warn('player.isFullScreen() has been deprecated, use player.isFullscreen() with a lowercase "s")'); +Player.prototype.isFullScreen = function(isFS){ + vjslib.log.warn('player.isFullScreen() has been deprecated, use player.isFullscreen() with a lowercase "s")'); return this.isFullscreen(isFS); }; @@ -909,8 +925,8 @@ vjs.Player.prototype.isFullScreen = function(isFS){ * * @return {vjs.Player} self */ -vjs.Player.prototype.requestFullscreen = function(){ - var fsApi = vjs.browser.fullscreenAPI; +Player.prototype.requestFullscreen = function(){ + var fsApi = fullscreenApi; this.isFullscreen(true); @@ -923,12 +939,12 @@ vjs.Player.prototype.requestFullscreen = function(){ // when cancelling fullscreen. Otherwise if there's multiple // players on a page, they would all be reacting to the same fullscreen // events - vjs.on(document, fsApi['fullscreenchange'], vjs.bind(this, function(e){ + vjsevents.on(document, fsApi['fullscreenchange'], vjslib.bind(this, function(e){ this.isFullscreen(document[fsApi.fullscreenElement]); // If cancelling fullscreen, remove event listener. if (this.isFullscreen() === false) { - vjs.off(document, fsApi['fullscreenchange'], arguments.callee); + vjsevents.off(document, fsApi['fullscreenchange'], arguments.callee); } this.trigger('fullscreenchange'); @@ -954,8 +970,8 @@ vjs.Player.prototype.requestFullscreen = function(){ * Old naming for requestFullscreen * @deprecated for lower case 's' version */ -vjs.Player.prototype.requestFullScreen = function(){ - vjs.log.warn('player.requestFullScreen() has been deprecated, use player.requestFullscreen() with a lowercase "s")'); +Player.prototype.requestFullScreen = function(){ + vjslib.log.warn('player.requestFullScreen() has been deprecated, use player.requestFullscreen() with a lowercase "s")'); return this.requestFullscreen(); }; @@ -967,8 +983,8 @@ vjs.Player.prototype.requestFullScreen = function(){ * * @return {vjs.Player} self */ -vjs.Player.prototype.exitFullscreen = function(){ - var fsApi = vjs.browser.fullscreenAPI; +Player.prototype.exitFullscreen = function(){ + var fsApi = fullscreenApi; this.isFullscreen(false); // Check for browser element fullscreen support @@ -988,30 +1004,30 @@ vjs.Player.prototype.exitFullscreen = function(){ * Old naming for exitFullscreen * @deprecated for exitFullscreen */ -vjs.Player.prototype.cancelFullScreen = function(){ - vjs.log.warn('player.cancelFullScreen() has been deprecated, use player.exitFullscreen()'); +Player.prototype.cancelFullScreen = function(){ + vjslib.log.warn('player.cancelFullScreen() has been deprecated, use player.exitFullscreen()'); return this.exitFullscreen(); }; // When fullscreen isn't supported we can stretch the video container to as wide as the browser will let us. -vjs.Player.prototype.enterFullWindow = function(){ +Player.prototype.enterFullWindow = function(){ this.isFullWindow = true; // Storing original doc overflow value to return to when fullscreen is off this.docOrigOverflow = document.documentElement.style.overflow; // Add listener for esc key to exit fullscreen - vjs.on(document, 'keydown', vjs.bind(this, this.fullWindowOnEscKey)); + vjsevents.on(document, 'keydown', vjslib.bind(this, this.fullWindowOnEscKey)); // Hide any scroll bars document.documentElement.style.overflow = 'hidden'; // Apply fullscreen styles - vjs.addClass(document.body, 'vjs-full-window'); + vjslib.addClass(document.body, 'vjs-full-window'); this.trigger('enterFullWindow'); }; -vjs.Player.prototype.fullWindowOnEscKey = function(event){ +Player.prototype.fullWindowOnEscKey = function(event){ if (event.keyCode === 27) { if (this.isFullscreen() === true) { this.exitFullscreen(); @@ -1021,31 +1037,31 @@ vjs.Player.prototype.fullWindowOnEscKey = function(event){ } }; -vjs.Player.prototype.exitFullWindow = function(){ +Player.prototype.exitFullWindow = function(){ this.isFullWindow = false; - vjs.off(document, 'keydown', this.fullWindowOnEscKey); + vjsevents.off(document, 'keydown', this.fullWindowOnEscKey); // Unhide scroll bars. document.documentElement.style.overflow = this.docOrigOverflow; // Remove fullscreen styles - vjs.removeClass(document.body, 'vjs-full-window'); + vjslib.removeClass(document.body, 'vjs-full-window'); // Resize the box, controller, and poster to original sizes // this.positionAll(); this.trigger('exitFullWindow'); }; -vjs.Player.prototype.selectSource = function(sources){ +Player.prototype.selectSource = function(sources){ // Loop through each playback technology in the options order for (var i=0,j=this.options_['techOrder'];i'+this.defaultValue+'' }, props); - return vjs.Component.prototype.createEl.call(this, 'div', props); + return Component.prototype.createEl.call(this, 'div', props); +}; + +module.exports = { + Slider: Slider, + SliderHandle: SliderHandle }; diff --git a/src/js/tracks.js b/src/js/tracks.js index fd06294082..0f39945361 100644 --- a/src/js/tracks.js +++ b/src/js/tracks.js @@ -1,3 +1,13 @@ +var Player, Component, vjsmenu, vjslib, + TextTrack, CaptionsTrack, SubtitlesTrack, ChaptersTrack, + TextTrackDisplay, TextTrackMenuItem, OffTextTrackMenuItem, ChaptersTrackMenuItem, + TextTrackButton, CaptionsButton, SubtitlesButton, ChaptersButton; + +Component = require('./component.js'); +vjsmenu = require('./menu.js'); +vjslib = require('./lib.js'); +Player = require('./player.js'); + /** * @fileoverview Text Tracks * Text tracks are tracks of timed text events. @@ -14,7 +24,7 @@ * @type {Array} * @private */ -vjs.Player.prototype.textTracks_; +Player.prototype.textTracks_; /** * Get an array of associated text tracks. captions, subtitles, chapters, descriptions @@ -22,7 +32,7 @@ vjs.Player.prototype.textTracks_; * @return {Array} Array of track objects * @private */ -vjs.Player.prototype.textTracks = function(){ +Player.prototype.textTracks = function(){ this.textTracks_ = this.textTracks_ || []; return this.textTracks_; }; @@ -37,8 +47,12 @@ vjs.Player.prototype.textTracks = function(){ * @param {Object=} options Additional track options, like src * @private */ -vjs.Player.prototype.addTextTrack = function(kind, label, language, options){ - var tracks = this.textTracks_ = this.textTracks_ || []; +Player.prototype.addTextTrack = function(kind, label, language, options){ + var tracks, components; + components = require('./components.js'); + + tracks = this.textTracks_ = this.textTracks_ || []; + options = options || {}; options['kind'] = kind; @@ -47,10 +61,10 @@ vjs.Player.prototype.addTextTrack = function(kind, label, language, options){ // HTML5 Spec says default to subtitles. // Uppercase first letter to match class names - var Kind = vjs.capitalize(kind || 'subtitles'); + var Kind = vjslib.capitalize(kind || 'subtitles'); // Create correct texttrack class. CaptionsTrack, etc. - var track = new window['videojs'][Kind + 'Track'](this, options); + var track = new components[Kind + 'Track'](this, options); tracks.push(track); @@ -77,7 +91,7 @@ vjs.Player.prototype.addTextTrack = function(kind, label, language, options){ * @param {Array} trackList Array of track elements or objects (fake track elements) * @private */ -vjs.Player.prototype.addTextTracks = function(trackList){ +Player.prototype.addTextTracks = function(trackList){ var trackObj; for (var i = 0; i < trackList.length; i++) { @@ -90,7 +104,7 @@ vjs.Player.prototype.addTextTracks = function(trackList){ // Show a text track // disableSameKind: disable all other tracks of the same kind. Value should be a track kind (captions, etc.) -vjs.Player.prototype.showTextTrack = function(id, disableSameKind){ +Player.prototype.showTextTrack = function(id, disableSameKind){ var tracks = this.textTracks_, i = 0, j = tracks.length, @@ -129,16 +143,16 @@ vjs.Player.prototype.showTextTrack = function(id, disableSameKind){ * @param {Object=} options * @constructor */ -vjs.TextTrack = vjs.Component.extend({ +TextTrack = Component.extend({ /** @constructor */ init: function(player, options){ - vjs.Component.call(this, player, options); + Component.call(this, player, options); // Apply track info to track object // Options will often be a track element // Build ID if one doesn't exist - this.id_ = options['id'] || ('vjs_' + options['kind'] + '_' + options['language'] + '_' + vjs.guid++); + this.id_ = options['id'] || ('vjs_' + options['kind'] + '_' + options['language'] + '_' + vjslib.guid++); this.src_ = options['src']; // 'default' is a reserved keyword in js so we use an abbreviated version this.dflt_ = options['default'] || options['dflt']; @@ -150,7 +164,7 @@ vjs.TextTrack = vjs.Component.extend({ this.readyState_ = 0; this.mode_ = 0; - this.player_.on('fullscreenchange', vjs.bind(this, this.adjustFontSize)); + this.player_.on('fullscreenchange', vjslib.bind(this, this.adjustFontSize)); } }); @@ -158,13 +172,13 @@ vjs.TextTrack = vjs.Component.extend({ * Track kind value. Captions, subtitles, etc. * @private */ -vjs.TextTrack.prototype.kind_; +TextTrack.prototype.kind_; /** * Get the track kind value * @return {String} */ -vjs.TextTrack.prototype.kind = function(){ +TextTrack.prototype.kind = function(){ return this.kind_; }; @@ -172,13 +186,13 @@ vjs.TextTrack.prototype.kind = function(){ * Track src value * @private */ -vjs.TextTrack.prototype.src_; +TextTrack.prototype.src_; /** * Get the track src value * @return {String} */ -vjs.TextTrack.prototype.src = function(){ +TextTrack.prototype.src = function(){ return this.src_; }; @@ -187,13 +201,13 @@ vjs.TextTrack.prototype.src = function(){ * If default is used, subtitles/captions to start showing * @private */ -vjs.TextTrack.prototype.dflt_; +TextTrack.prototype.dflt_; /** * Get the track default value. ('default' is a reserved keyword) * @return {Boolean} */ -vjs.TextTrack.prototype.dflt = function(){ +TextTrack.prototype.dflt = function(){ return this.dflt_; }; @@ -201,13 +215,13 @@ vjs.TextTrack.prototype.dflt = function(){ * Track title value * @private */ -vjs.TextTrack.prototype.title_; +TextTrack.prototype.title_; /** * Get the track title value * @return {String} */ -vjs.TextTrack.prototype.title = function(){ +TextTrack.prototype.title = function(){ return this.title_; }; @@ -216,13 +230,13 @@ vjs.TextTrack.prototype.title = function(){ * Spec def: readonly attribute DOMString language; * @private */ -vjs.TextTrack.prototype.language_; +TextTrack.prototype.language_; /** * Get the track language value * @return {String} */ -vjs.TextTrack.prototype.language = function(){ +TextTrack.prototype.language = function(){ return this.language_; }; @@ -231,13 +245,13 @@ vjs.TextTrack.prototype.language = function(){ * Spec def: readonly attribute DOMString label; * @private */ -vjs.TextTrack.prototype.label_; +TextTrack.prototype.label_; /** * Get the track label value * @return {String} */ -vjs.TextTrack.prototype.label = function(){ +TextTrack.prototype.label = function(){ return this.label_; }; @@ -246,13 +260,13 @@ vjs.TextTrack.prototype.label = function(){ * Spec def: readonly attribute TextTrackCueList cues; * @private */ -vjs.TextTrack.prototype.cues_; +TextTrack.prototype.cues_; /** * Get the track cues * @return {Array} */ -vjs.TextTrack.prototype.cues = function(){ +TextTrack.prototype.cues = function(){ return this.cues_; }; @@ -261,13 +275,13 @@ vjs.TextTrack.prototype.cues = function(){ * Spec def: readonly attribute TextTrackCueList activeCues; * @private */ -vjs.TextTrack.prototype.activeCues_; +TextTrack.prototype.activeCues_; /** * Get the track active cues * @return {Array} */ -vjs.TextTrack.prototype.activeCues = function(){ +TextTrack.prototype.activeCues = function(){ return this.activeCues_; }; @@ -280,13 +294,13 @@ vjs.TextTrack.prototype.activeCues = function(){ * readonly attribute unsigned short readyState; * @private */ -vjs.TextTrack.prototype.readyState_; +TextTrack.prototype.readyState_; /** * Get the track readyState * @return {Number} */ -vjs.TextTrack.prototype.readyState = function(){ +TextTrack.prototype.readyState = function(){ return this.readyState_; }; @@ -298,13 +312,13 @@ vjs.TextTrack.prototype.readyState = function(){ * attribute unsigned short mode; * @private */ -vjs.TextTrack.prototype.mode_; +TextTrack.prototype.mode_; /** * Get the track mode * @return {Number} */ -vjs.TextTrack.prototype.mode = function(){ +TextTrack.prototype.mode = function(){ return this.mode_; }; @@ -312,7 +326,7 @@ vjs.TextTrack.prototype.mode = function(){ * Change the font size of the text track to make it larger when playing in fullscreen mode * and restore it to its normal size when not in fullscreen mode. */ -vjs.TextTrack.prototype.adjustFontSize = function(){ +TextTrack.prototype.adjustFontSize = function(){ if (this.player_.isFullScreen()) { // Scale the font by the same factor as increasing the video width to the full screen window width. // Additionally, multiply that factor by 1.4, which is the default font size for @@ -328,8 +342,8 @@ vjs.TextTrack.prototype.adjustFontSize = function(){ * Create basic div to hold cue text * @return {Element} */ -vjs.TextTrack.prototype.createEl = function(){ - return vjs.Component.prototype.createEl.call(this, 'div', { +TextTrack.prototype.createEl = function(){ + return Component.prototype.createEl.call(this, 'div', { className: 'vjs-' + this.kind_ + ' vjs-text-track' }); }; @@ -344,13 +358,13 @@ vjs.TextTrack.prototype.createEl = function(){ * The showing by default state is used in conjunction with the default attribute on track elements to indicate that the text track was enabled due to that attribute. * This allows the user agent to override the state if a later track is discovered that is more appropriate per the user's preferences. */ -vjs.TextTrack.prototype.show = function(){ +TextTrack.prototype.show = function(){ this.activate(); this.mode_ = 2; // Show element. - vjs.Component.prototype.show.call(this); + Component.prototype.show.call(this); }; /** @@ -359,14 +373,14 @@ vjs.TextTrack.prototype.show = function(){ * If no attempt has yet been made to obtain the track's cues, the user agent will perform such an attempt momentarily. * The user agent is maintaining a list of which cues are active, and events are being fired accordingly. */ -vjs.TextTrack.prototype.hide = function(){ +TextTrack.prototype.hide = function(){ // When hidden, cues are still triggered. Disable to stop triggering. this.activate(); this.mode_ = 1; // Hide element. - vjs.Component.prototype.hide.call(this); + Component.prototype.hide.call(this); }; /** @@ -374,7 +388,7 @@ vjs.TextTrack.prototype.hide = function(){ * Indicates that the text track is not active. Other than for the purposes of exposing the track in the DOM, the user agent is ignoring the text track. * No cues are active, no events are fired, and the user agent will not attempt to obtain the track's cues. */ -vjs.TextTrack.prototype.disable = function(){ +TextTrack.prototype.disable = function(){ // If showing, hide. if (this.mode_ == 2) { this.hide(); } @@ -388,7 +402,7 @@ vjs.TextTrack.prototype.disable = function(){ /** * Turn on cue tracking. Tracks that are showing OR hidden are active. */ -vjs.TextTrack.prototype.activate = function(){ +TextTrack.prototype.activate = function(){ // Load text file if it hasn't been yet. if (this.readyState_ === 0) { this.load(); } @@ -396,10 +410,10 @@ vjs.TextTrack.prototype.activate = function(){ if (this.mode_ === 0) { // Update current cue on timeupdate // Using unique ID for bind function so other tracks don't remove listener - this.player_.on('timeupdate', vjs.bind(this, this.update, this.id_)); + this.player_.on('timeupdate', vjslib.bind(this, this.update, this.id_)); // Reset cue time on media end - this.player_.on('ended', vjs.bind(this, this.reset, this.id_)); + this.player_.on('ended', vjslib.bind(this, this.reset, this.id_)); // Add to display if (this.kind_ === 'captions' || this.kind_ === 'subtitles') { @@ -411,10 +425,10 @@ vjs.TextTrack.prototype.activate = function(){ /** * Turn off cue tracking. */ -vjs.TextTrack.prototype.deactivate = function(){ +TextTrack.prototype.deactivate = function(){ // Using unique ID for bind function so other tracks don't remove listener - this.player_.off('timeupdate', vjs.bind(this, this.update, this.id_)); - this.player_.off('ended', vjs.bind(this, this.reset, this.id_)); + this.player_.off('timeupdate', vjslib.bind(this, this.update, this.id_)); + this.player_.off('ended', vjslib.bind(this, this.reset, this.id_)); this.reset(); // Reset // Remove from display @@ -435,17 +449,17 @@ vjs.TextTrack.prototype.deactivate = function(){ // // Failed to load // Indicates that the text track was enabled, but when the user agent attempted to obtain it, this failed in some way (e.g. URL could not be resolved, network error, unknown text track format). Some or all of the cues are likely missing and will not be obtained. -vjs.TextTrack.prototype.load = function(){ +TextTrack.prototype.load = function(){ // Only load if not loaded yet. if (this.readyState_ === 0) { this.readyState_ = 1; - vjs.get(this.src_, vjs.bind(this, this.parseCues), vjs.bind(this, this.onError)); + vjslib.get(this.src_, vjslib.bind(this, this.parseCues), vjslib.bind(this, this.onError)); } }; -vjs.TextTrack.prototype.onError = function(err){ +TextTrack.prototype.onError = function(err){ this.error = err; this.readyState_ = 3; this.trigger('error'); @@ -453,7 +467,7 @@ vjs.TextTrack.prototype.onError = function(err){ // Parse the WebVTT text format for cue times. // TODO: Separate parser into own class so alternative timed text formats can be used. (TTML, DFXP) -vjs.TextTrack.prototype.parseCues = function(srcContent) { +TextTrack.prototype.parseCues = function(srcContent) { var cue, time, text, lines = srcContent.split('\n'), line = '', id; @@ -461,7 +475,7 @@ vjs.TextTrack.prototype.parseCues = function(srcContent) { for (var i=1, j=lines.length; i') == -1) { id = line; // Advance to next line for timing. - line = vjs.trim(lines[++i]); + line = vjslib.trim(lines[++i]); } else { id = this.cues_.length; } @@ -491,7 +505,7 @@ vjs.TextTrack.prototype.parseCues = function(srcContent) { // Loop until a blank line or end of lines // Assumeing trim('') returns false for blank lines - while (lines[++i] && (line = vjs.trim(lines[i]))) { + while (lines[++i] && (line = vjslib.trim(lines[i]))) { text.push(line); } @@ -507,7 +521,7 @@ vjs.TextTrack.prototype.parseCues = function(srcContent) { }; -vjs.TextTrack.prototype.parseCueTime = function(timeText) { +TextTrack.prototype.parseCueTime = function(timeText) { var parts = timeText.split(':'), time = 0, hours, minutes, other, seconds, ms; @@ -548,7 +562,7 @@ vjs.TextTrack.prototype.parseCueTime = function(timeText) { }; // Update active cues whenever timeupdate events are triggered on the player. -vjs.TextTrack.prototype.update = function(){ +TextTrack.prototype.update = function(){ if (this.cues_.length > 0) { // Get current player time, adjust for track offset @@ -657,7 +671,7 @@ vjs.TextTrack.prototype.update = function(){ }; // Add cue HTML to display -vjs.TextTrack.prototype.updateDisplay = function(){ +TextTrack.prototype.updateDisplay = function(){ var cues = this.activeCues_, html = '', i=0,j=cues.length; @@ -670,7 +684,7 @@ vjs.TextTrack.prototype.updateDisplay = function(){ }; // Set all loop helper values back -vjs.TextTrack.prototype.reset = function(){ +TextTrack.prototype.reset = function(){ this.nextChange = 0; this.prevChange = this.player_.duration(); this.firstActiveIndex = 0; @@ -683,8 +697,8 @@ vjs.TextTrack.prototype.reset = function(){ * * @constructor */ -vjs.CaptionsTrack = vjs.TextTrack.extend(); -vjs.CaptionsTrack.prototype.kind_ = 'captions'; +CaptionsTrack = TextTrack.extend(); +CaptionsTrack.prototype.kind_ = 'captions'; // Exporting here because Track creation requires the track kind // to be available on global object. e.g. new window['videojs'][Kind + 'Track'] @@ -693,16 +707,16 @@ vjs.CaptionsTrack.prototype.kind_ = 'captions'; * * @constructor */ -vjs.SubtitlesTrack = vjs.TextTrack.extend(); -vjs.SubtitlesTrack.prototype.kind_ = 'subtitles'; +SubtitlesTrack = TextTrack.extend(); +SubtitlesTrack.prototype.kind_ = 'subtitles'; /** * The track component for managing the hiding and showing of chapters * * @constructor */ -vjs.ChaptersTrack = vjs.TextTrack.extend(); -vjs.ChaptersTrack.prototype.kind_ = 'chapters'; +ChaptersTrack = TextTrack.extend(); +ChaptersTrack.prototype.kind_ = 'chapters'; /* Text Track Display @@ -714,10 +728,10 @@ vjs.ChaptersTrack.prototype.kind_ = 'chapters'; * * @constructor */ -vjs.TextTrackDisplay = vjs.Component.extend({ +TextTrackDisplay = Component.extend({ /** @constructor */ init: function(player, options, ready){ - vjs.Component.call(this, player, options, ready); + Component.call(this, player, options, ready); // 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. @@ -729,8 +743,8 @@ vjs.TextTrackDisplay = vjs.Component.extend({ } }); -vjs.TextTrackDisplay.prototype.createEl = function(){ - return vjs.Component.prototype.createEl.call(this, 'div', { +TextTrackDisplay.prototype.createEl = function(){ + return Component.prototype.createEl.call(this, 'div', { className: 'vjs-text-track-display' }); }; @@ -741,7 +755,7 @@ vjs.TextTrackDisplay.prototype.createEl = function(){ * * @constructor */ -vjs.TextTrackMenuItem = vjs.MenuItem.extend({ +TextTrackMenuItem = vjsmenu.MenuItem.extend({ /** @constructor */ init: function(player, options){ var track = this.track = options['track']; @@ -749,18 +763,18 @@ vjs.TextTrackMenuItem = vjs.MenuItem.extend({ // Modify options for parent MenuItem class's init. options['label'] = track.label(); options['selected'] = track.dflt(); - vjs.MenuItem.call(this, player, options); + vjsmenu.MenuItem.call(this, player, options); - this.player_.on(track.kind() + 'trackchange', vjs.bind(this, this.update)); + this.player_.on(track.kind() + 'trackchange', vjslib.bind(this, this.update)); } }); -vjs.TextTrackMenuItem.prototype.onClick = function(){ - vjs.MenuItem.prototype.onClick.call(this); +TextTrackMenuItem.prototype.onClick = function(){ + vjsmenu.MenuItem.prototype.onClick.call(this); this.player_.showTextTrack(this.track.id_, this.track.kind()); }; -vjs.TextTrackMenuItem.prototype.update = function(){ +TextTrackMenuItem.prototype.update = function(){ this.selected(this.track.mode() == 2); }; @@ -769,7 +783,7 @@ vjs.TextTrackMenuItem.prototype.update = function(){ * * @constructor */ -vjs.OffTextTrackMenuItem = vjs.TextTrackMenuItem.extend({ +OffTextTrackMenuItem = TextTrackMenuItem.extend({ /** @constructor */ init: function(player, options){ // Create pseudo track info @@ -781,17 +795,17 @@ vjs.OffTextTrackMenuItem = vjs.TextTrackMenuItem.extend({ dflt: function(){ return false; }, mode: function(){ return false; } }; - vjs.TextTrackMenuItem.call(this, player, options); + TextTrackMenuItem.call(this, player, options); this.selected(true); } }); -vjs.OffTextTrackMenuItem.prototype.onClick = function(){ - vjs.TextTrackMenuItem.prototype.onClick.call(this); +OffTextTrackMenuItem.prototype.onClick = function(){ + TextTrackMenuItem.prototype.onClick.call(this); this.player_.showTextTrack(this.track.id_, this.track.kind()); }; -vjs.OffTextTrackMenuItem.prototype.update = function(){ +OffTextTrackMenuItem.prototype.update = function(){ var tracks = this.player_.textTracks(), i=0, j=tracks.length, track, off = true; @@ -811,10 +825,10 @@ vjs.OffTextTrackMenuItem.prototype.update = function(){ * * @constructor */ -vjs.TextTrackButton = vjs.MenuButton.extend({ +TextTrackButton = vjsmenu.MenuButton.extend({ /** @constructor */ init: function(player, options){ - vjs.MenuButton.call(this, player, options); + vjsmenu.MenuButton.call(this, player, options); if (this.items.length <= 1) { this.hide(); @@ -848,16 +862,16 @@ vjs.TextTrackButton = vjs.MenuButton.extend({ // }; // Create a menu item for each text track -vjs.TextTrackButton.prototype.createItems = function(){ +TextTrackButton.prototype.createItems = function(){ var items = [], track; // Add an OFF menu item to turn all tracks off - items.push(new vjs.OffTextTrackMenuItem(this.player_, { 'kind': this.kind_ })); + items.push(new OffTextTrackMenuItem(this.player_, { 'kind': this.kind_ })); for (var i = 0; i < this.player_.textTracks().length; i++) { track = this.player_.textTracks()[i]; if (track.kind() === this.kind_) { - items.push(new vjs.TextTrackMenuItem(this.player_, { + items.push(new TextTrackMenuItem(this.player_, { 'track': track })); } @@ -871,32 +885,32 @@ vjs.TextTrackButton.prototype.createItems = function(){ * * @constructor */ -vjs.CaptionsButton = vjs.TextTrackButton.extend({ +CaptionsButton = TextTrackButton.extend({ /** @constructor */ init: function(player, options, ready){ - vjs.TextTrackButton.call(this, player, options, ready); + TextTrackButton.call(this, player, options, ready); this.el_.setAttribute('aria-label','Captions Menu'); } }); -vjs.CaptionsButton.prototype.kind_ = 'captions'; -vjs.CaptionsButton.prototype.buttonText = 'Captions'; -vjs.CaptionsButton.prototype.className = 'vjs-captions-button'; +CaptionsButton.prototype.kind_ = 'captions'; +CaptionsButton.prototype.buttonText = 'Captions'; +CaptionsButton.prototype.className = 'vjs-captions-button'; /** * The button component for toggling and selecting subtitles * * @constructor */ -vjs.SubtitlesButton = vjs.TextTrackButton.extend({ +SubtitlesButton = TextTrackButton.extend({ /** @constructor */ init: function(player, options, ready){ - vjs.TextTrackButton.call(this, player, options, ready); + TextTrackButton.call(this, player, options, ready); this.el_.setAttribute('aria-label','Subtitles Menu'); } }); -vjs.SubtitlesButton.prototype.kind_ = 'subtitles'; -vjs.SubtitlesButton.prototype.buttonText = 'Subtitles'; -vjs.SubtitlesButton.prototype.className = 'vjs-subtitles-button'; +SubtitlesButton.prototype.kind_ = 'subtitles'; +SubtitlesButton.prototype.buttonText = 'Subtitles'; +SubtitlesButton.prototype.className = 'vjs-subtitles-button'; // Chapters act much differently than other text tracks // Cues are navigation vs. other tracks of alternative languages @@ -905,25 +919,25 @@ vjs.SubtitlesButton.prototype.className = 'vjs-subtitles-button'; * * @constructor */ -vjs.ChaptersButton = vjs.TextTrackButton.extend({ +ChaptersButton = TextTrackButton.extend({ /** @constructor */ init: function(player, options, ready){ - vjs.TextTrackButton.call(this, player, options, ready); + TextTrackButton.call(this, player, options, ready); this.el_.setAttribute('aria-label','Chapters Menu'); } }); -vjs.ChaptersButton.prototype.kind_ = 'chapters'; -vjs.ChaptersButton.prototype.buttonText = 'Chapters'; -vjs.ChaptersButton.prototype.className = 'vjs-chapters-button'; +ChaptersButton.prototype.kind_ = 'chapters'; +ChaptersButton.prototype.buttonText = 'Chapters'; +ChaptersButton.prototype.className = 'vjs-chapters-button'; // Create a menu item for each text track -vjs.ChaptersButton.prototype.createItems = function(){ +ChaptersButton.prototype.createItems = function(){ var items = [], track; for (var i = 0; i < this.player_.textTracks().length; i++) { track = this.player_.textTracks()[i]; if (track.kind() === this.kind_) { - items.push(new vjs.TextTrackMenuItem(this.player_, { + items.push(new TextTrackMenuItem(this.player_, { 'track': track })); } @@ -932,7 +946,7 @@ vjs.ChaptersButton.prototype.createItems = function(){ return items; }; -vjs.ChaptersButton.prototype.createMenu = function(){ +ChaptersButton.prototype.createMenu = function(){ var tracks = this.player_.textTracks(), i = 0, j = tracks.length, @@ -944,7 +958,7 @@ vjs.ChaptersButton.prototype.createMenu = function(){ if (track.kind() == this.kind_) { if (track.readyState() === 0) { track.load(); - track.on('loaded', vjs.bind(this, this.createMenu)); + track.on('loaded', vjslib.bind(this, this.createMenu)); } else { chaptersTrack = track; break; @@ -954,10 +968,10 @@ vjs.ChaptersButton.prototype.createMenu = function(){ var menu = this.menu; if (menu === undefined) { - menu = new vjs.Menu(this.player_); - menu.contentEl().appendChild(vjs.createEl('li', { + menu = new vjsmenu.Menu(this.player_); + menu.contentEl().appendChild(vjslib.createEl('li', { className: 'vjs-menu-title', - innerHTML: vjs.capitalize(this.kind_), + innerHTML: vjslib.capitalize(this.kind_), tabindex: -1 })); } @@ -970,7 +984,7 @@ vjs.ChaptersButton.prototype.createMenu = function(){ for (;i