3 * Video.js 5.19.2 <http://videojs.com/>
4 * Copyright Brightcove, Inc. <https://www.brightcove.com/>
5 * Available under Apache License Version 2.0
6 * <https://github.com/videojs/video.js/blob/master/LICENSE>
9 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.videojs = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
12 exports.__esModule = true;
14 var _button = _dereq_(2);
16 var _button2 = _interopRequireDefault(_button);
18 var _component = _dereq_(5);
20 var _component2 = _interopRequireDefault(_component);
22 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
24 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
26 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
28 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
29 * @file big-play-button.js
34 * The initial play button that shows before the video has played. The hiding of the
35 * `BigPlayButton` get done via CSS and `Player` states.
39 var BigPlayButton = function (_Button) {
40 _inherits(BigPlayButton, _Button);
42 function BigPlayButton() {
43 _classCallCheck(this, BigPlayButton);
45 return _possibleConstructorReturn(this, _Button.apply(this, arguments));
49 * Builds the default DOM `className`.
52 * The DOM `className` for this object. Always returns 'vjs-big-play-button'.
54 BigPlayButton.prototype.buildCSSClass = function buildCSSClass() {
55 return 'vjs-big-play-button';
59 * This gets called when a `BigPlayButton` "clicked". See {@link ClickableComponent}
60 * for more detailed information on what a click can be.
62 * @param {EventTarget~Event} event
63 * The `keydown`, `tap`, or `click` event that caused this function to be
71 BigPlayButton.prototype.handleClick = function handleClick(event) {
74 var cb = this.player_.getChild('controlBar');
75 var playToggle = cb && cb.getChild('playToggle');
82 this.setTimeout(function () {
88 }(_button2['default']);
91 * The text that should display over the `BigPlayButton`s controls. Added to for localization.
98 BigPlayButton.prototype.controlText_ = 'Play Video';
100 _component2['default'].registerComponent('BigPlayButton', BigPlayButton);
101 exports['default'] = BigPlayButton;
103 },{"2":2,"5":5}],2:[function(_dereq_,module,exports){
106 exports.__esModule = true;
108 var _clickableComponent = _dereq_(3);
110 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
112 var _component = _dereq_(5);
114 var _component2 = _interopRequireDefault(_component);
116 var _log = _dereq_(86);
118 var _log2 = _interopRequireDefault(_log);
120 var _obj = _dereq_(88);
122 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
124 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
126 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
128 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
134 * Base class for all buttons.
136 * @extends ClickableComponent
138 var Button = function (_ClickableComponent) {
139 _inherits(Button, _ClickableComponent);
142 _classCallCheck(this, Button);
144 return _possibleConstructorReturn(this, _ClickableComponent.apply(this, arguments));
148 * Create the `Button`s DOM element.
150 * @param {string} [tag=button]
151 * Element's node type. e.g. 'button'
153 * @param {Object} [props={}]
154 * An object of properties that should be set on the element.
156 * @param {Object} [attributes={}]
157 * An object of attributes that should be set on the element.
160 * The element that gets created.
162 Button.prototype.createEl = function createEl() {
163 var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'button';
164 var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
165 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
167 props = (0, _obj.assign)({
168 className: this.buildCSSClass()
171 if (tag !== 'button') {
172 _log2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.');
174 // Add properties for clickable element which is not a native HTML button
175 props = (0, _obj.assign)({
179 // Add ARIA attributes for clickable element which is not a native HTML button
180 attributes = (0, _obj.assign)({
185 // Add attributes for button element
186 attributes = (0, _obj.assign)({
188 // Necessary since the default button type is "submit"
191 // let the screen reader user know that the text of the button may change
192 'aria-live': 'polite'
195 var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes);
197 this.createControlTextEl(el);
203 * Add a child `Component` inside of this `Button`.
205 * @param {string|Component} child
206 * The name or instance of a child to add.
208 * @param {Object} [options={}]
209 * The key/value store of options that will get passed to children of
212 * @return {Component}
213 * The `Component` that gets added as a child. When using a string the
214 * `Component` will get created by this process.
216 * @deprecated since version 5
220 Button.prototype.addChild = function addChild(child) {
221 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
223 var className = this.constructor.name;
225 _log2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.');
227 // Avoid the error message generated by ClickableComponent's addChild method
228 return _component2['default'].prototype.addChild.call(this, child, options);
232 * Enable the `Button` element so that it can be activated or clicked. Use this with
233 * {@link Button#disable}.
237 Button.prototype.enable = function enable() {
238 _ClickableComponent.prototype.enable.call(this);
239 this.el_.removeAttribute('disabled');
243 * Enable the `Button` element so that it cannot be activated or clicked. Use this with
244 * {@link Button#enable}.
248 Button.prototype.disable = function disable() {
249 _ClickableComponent.prototype.disable.call(this);
250 this.el_.setAttribute('disabled', 'disabled');
254 * This gets called when a `Button` has focus and `keydown` is triggered via a key
257 * @param {EventTarget~Event} event
258 * The event that caused this function to get called.
264 Button.prototype.handleKeyPress = function handleKeyPress(event) {
266 // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button.
267 if (event.which === 32 || event.which === 13) {
271 // Pass keypress handling up for unsupported keys
272 _ClickableComponent.prototype.handleKeyPress.call(this, event);
276 }(_clickableComponent2['default']);
278 _component2['default'].registerComponent('Button', Button);
279 exports['default'] = Button;
281 },{"3":3,"5":5,"86":86,"88":88}],3:[function(_dereq_,module,exports){
284 exports.__esModule = true;
286 var _component = _dereq_(5);
288 var _component2 = _interopRequireDefault(_component);
290 var _dom = _dereq_(81);
292 var Dom = _interopRequireWildcard(_dom);
294 var _events = _dereq_(82);
296 var Events = _interopRequireWildcard(_events);
298 var _fn = _dereq_(83);
300 var Fn = _interopRequireWildcard(_fn);
302 var _log = _dereq_(86);
304 var _log2 = _interopRequireDefault(_log);
306 var _document = _dereq_(94);
308 var _document2 = _interopRequireDefault(_document);
310 var _obj = _dereq_(88);
312 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
314 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
316 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
318 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
320 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
326 * Clickable Component which is clickable or keyboard actionable,
327 * but is not a native HTML button.
331 var ClickableComponent = function (_Component) {
332 _inherits(ClickableComponent, _Component);
335 * Creates an instance of this class.
337 * @param {Player} player
338 * The `Player` that this class should be attached to.
340 * @param {Object} [options]
341 * The key/value store of player options.
343 function ClickableComponent(player, options) {
344 _classCallCheck(this, ClickableComponent);
346 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
348 _this.emitTapEvents();
355 * Create the `Component`s DOM element.
357 * @param {string} [tag=div]
358 * The element's node type.
360 * @param {Object} [props={}]
361 * An object of properties that should be set on the element.
363 * @param {Object} [attributes={}]
364 * An object of attributes that should be set on the element.
367 * The element that gets created.
371 ClickableComponent.prototype.createEl = function createEl() {
372 var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
373 var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
374 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
376 props = (0, _obj.assign)({
377 className: this.buildCSSClass(),
381 if (tag === 'button') {
382 _log2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.');
385 // Add ARIA attributes for clickable element which is not a native HTML button
386 attributes = (0, _obj.assign)({
389 // let the screen reader user know that the text of the element may change
390 'aria-live': 'polite'
393 this.tabIndex_ = props.tabIndex;
395 var el = _Component.prototype.createEl.call(this, tag, props, attributes);
397 this.createControlTextEl(el);
403 * Create a control text element on this `Component`
405 * @param {Element} [el]
406 * Parent element for the control text.
409 * The control text element that gets created.
413 ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) {
414 this.controlTextEl_ = Dom.createEl('span', {
415 className: 'vjs-control-text'
419 el.appendChild(this.controlTextEl_);
422 this.controlText(this.controlText_, el);
424 return this.controlTextEl_;
428 * Get or set the localize text to use for the controls on the `Component`.
430 * @param {string} [text]
431 * Control text for element.
433 * @param {Element} [el=this.el()]
434 * Element to set the title on.
436 * @return {string|ClickableComponent}
437 * - The control text when getting
438 * - Returns itself when setting; method can be chained.
442 ClickableComponent.prototype.controlText = function controlText(text) {
443 var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.el();
446 return this.controlText_ || 'Need Text';
449 var localizedText = this.localize(text);
451 this.controlText_ = text;
452 this.controlTextEl_.innerHTML = localizedText;
454 if (!this.nonIconControl) {
455 // Set title attribute if only an icon is shown
456 el.setAttribute('title', localizedText);
463 * Builds the default DOM `className`.
466 * The DOM `className` for this object.
470 ClickableComponent.prototype.buildCSSClass = function buildCSSClass() {
471 return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this);
475 * Enable this `Component`s element.
477 * @return {ClickableComponent}
478 * Returns itself; method can be chained.
482 ClickableComponent.prototype.enable = function enable() {
483 this.removeClass('vjs-disabled');
484 this.el_.setAttribute('aria-disabled', 'false');
485 if (typeof this.tabIndex_ !== 'undefined') {
486 this.el_.setAttribute('tabIndex', this.tabIndex_);
488 this.on('tap', this.handleClick);
489 this.on('click', this.handleClick);
490 this.on('focus', this.handleFocus);
491 this.on('blur', this.handleBlur);
496 * Disable this `Component`s element.
498 * @return {ClickableComponent}
499 * Returns itself; method can be chained.
503 ClickableComponent.prototype.disable = function disable() {
504 this.addClass('vjs-disabled');
505 this.el_.setAttribute('aria-disabled', 'true');
506 if (typeof this.tabIndex_ !== 'undefined') {
507 this.el_.removeAttribute('tabIndex');
509 this.off('tap', this.handleClick);
510 this.off('click', this.handleClick);
511 this.off('focus', this.handleFocus);
512 this.off('blur', this.handleBlur);
517 * This gets called when a `ClickableComponent` gets:
518 * - Clicked (via the `click` event, listening starts in the constructor)
519 * - Tapped (via the `tap` event, listening starts in the constructor)
520 * - The following things happen in order:
521 * 1. {@link ClickableComponent#handleFocus} is called via a `focus` event on the
522 * `ClickableComponent`.
523 * 2. {@link ClickableComponent#handleFocus} adds a listener for `keydown` on using
524 * {@link ClickableComponent#handleKeyPress}.
525 * 3. `ClickableComponent` has not had a `blur` event (`blur` means that focus was lost). The user presses
526 * the space or enter key.
527 * 4. {@link ClickableComponent#handleKeyPress} calls this function with the `keydown`
528 * event as a parameter.
530 * @param {EventTarget~Event} event
531 * The `keydown`, `tap`, or `click` event that caused this function to be
540 ClickableComponent.prototype.handleClick = function handleClick(event) {};
543 * This gets called when a `ClickableComponent` gains focus via a `focus` event.
544 * Turns on listening for `keydown` events. When they happen it
545 * calls `this.handleKeyPress`.
547 * @param {EventTarget~Event} event
548 * The `focus` event that caused this function to be called.
554 ClickableComponent.prototype.handleFocus = function handleFocus(event) {
555 Events.on(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
559 * Called when this ClickableComponent has focus and a key gets pressed down. By
560 * default it will call `this.handleClick` when the key is space or enter.
562 * @param {EventTarget~Event} event
563 * The `keydown` event that caused this function to be called.
569 ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) {
571 // Support Space (32) or Enter (13) key operation to fire a click event
572 if (event.which === 32 || event.which === 13) {
573 event.preventDefault();
574 this.handleClick(event);
575 } else if (_Component.prototype.handleKeyPress) {
577 // Pass keypress handling up for unsupported keys
578 _Component.prototype.handleKeyPress.call(this, event);
583 * Called when a `ClickableComponent` loses focus. Turns off the listener for
584 * `keydown` events. Which Stops `this.handleKeyPress` from getting called.
586 * @param {EventTarget~Event} event
587 * The `blur` event that caused this function to be called.
593 ClickableComponent.prototype.handleBlur = function handleBlur(event) {
594 Events.off(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
597 return ClickableComponent;
598 }(_component2['default']);
600 _component2['default'].registerComponent('ClickableComponent', ClickableComponent);
601 exports['default'] = ClickableComponent;
603 },{"5":5,"81":81,"82":82,"83":83,"86":86,"88":88,"94":94}],4:[function(_dereq_,module,exports){
606 exports.__esModule = true;
608 var _button = _dereq_(2);
610 var _button2 = _interopRequireDefault(_button);
612 var _component = _dereq_(5);
614 var _component2 = _interopRequireDefault(_component);
616 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
618 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
620 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
622 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
623 * @file close-button.js
628 * The `CloseButton` is a `{@link Button}` that fires a `close` event when
633 var CloseButton = function (_Button) {
634 _inherits(CloseButton, _Button);
637 * Creates an instance of the this class.
639 * @param {Player} player
640 * The `Player` that this class should be attached to.
642 * @param {Object} [options]
643 * The key/value store of player options.
645 function CloseButton(player, options) {
646 _classCallCheck(this, CloseButton);
648 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
650 _this.controlText(options && options.controlText || _this.localize('Close'));
655 * Builds the default DOM `className`.
658 * The DOM `className` for this object.
662 CloseButton.prototype.buildCSSClass = function buildCSSClass() {
663 return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this);
667 * This gets called when a `CloseButton` gets clicked. See
668 * {@link ClickableComponent#handleClick} for more information on when this will be
671 * @param {EventTarget~Event} event
672 * The `keydown`, `tap`, or `click` event that caused this function to be
677 * @fires CloseButton#close
681 CloseButton.prototype.handleClick = function handleClick(event) {
684 * Triggered when the a `CloseButton` is clicked.
686 * @event CloseButton#close
687 * @type {EventTarget~Event}
689 * @property {boolean} [bubbles=false]
690 * set to false so that the close event does not
691 * bubble up to parents if there is no listener
693 this.trigger({ type: 'close', bubbles: false });
697 }(_button2['default']);
699 _component2['default'].registerComponent('CloseButton', CloseButton);
700 exports['default'] = CloseButton;
702 },{"2":2,"5":5}],5:[function(_dereq_,module,exports){
705 exports.__esModule = true;
707 var _window = _dereq_(95);
709 var _window2 = _interopRequireDefault(_window);
711 var _dom = _dereq_(81);
713 var Dom = _interopRequireWildcard(_dom);
715 var _fn = _dereq_(83);
717 var Fn = _interopRequireWildcard(_fn);
719 var _guid = _dereq_(85);
721 var Guid = _interopRequireWildcard(_guid);
723 var _events = _dereq_(82);
725 var Events = _interopRequireWildcard(_events);
727 var _log = _dereq_(86);
729 var _log2 = _interopRequireDefault(_log);
731 var _toTitleCase = _dereq_(91);
733 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
735 var _mergeOptions = _dereq_(87);
737 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
739 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
741 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
743 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
744 * Player Component - Base class for all UI objects
751 * Base class for all UI Components.
752 * Components are UI objects which represent both a javascript object and an element
753 * in the DOM. They can be children of other components, and can have
754 * children themselves.
756 * Components can also use methods from {@link EventTarget}
758 var Component = function () {
761 * A callback that is called when a component is ready. Does not have any
762 * paramters and any callback value will be ignored.
764 * @callback Component~ReadyCallback
769 * Creates an instance of this class.
771 * @param {Player} player
772 * The `Player` that this class should be attached to.
774 * @param {Object} [options]
775 * The key/value store of player options.
777 * @param {Object[]} [options.children]
778 * An array of children objects to intialize this component with. Children objects have
779 * a name property that will be used if more than one component of the same type needs to be
782 * @param {Component~ReadyCallback} [ready]
783 * Function that gets called when the `Component` is ready.
785 function Component(player, options, ready) {
786 _classCallCheck(this, Component);
788 // The component might be the player itself and we can't pass `this` to super
789 if (!player && this.play) {
790 this.player_ = player = this; // eslint-disable-line
792 this.player_ = player;
795 // Make a copy of prototype.options_ to protect against overriding defaults
796 this.options_ = (0, _mergeOptions2['default'])({}, this.options_);
798 // Updated options with supplied options
799 options = this.options_ = (0, _mergeOptions2['default'])(this.options_, options);
801 // Get ID from options or options element if one is supplied
802 this.id_ = options.id || options.el && options.el.id;
804 // If there was no ID from the options, generate one
806 // Don't require the player ID function in the case of mock players
807 var id = player && player.id && player.id() || 'no_player';
809 this.id_ = id + '_component_' + Guid.newGUID();
812 this.name_ = options.name || null;
814 // Create element if one wasn't provided in options
816 this.el_ = options.el;
817 } else if (options.createEl !== false) {
818 this.el_ = this.createEl();
822 this.childIndex_ = {};
823 this.childNameIndex_ = {};
825 // Add any child components in options
826 if (options.initChildren !== false) {
831 // Don't want to trigger ready here or it will before init is actually
832 // finished for all children that run this constructor
834 if (options.reportTouchActivity !== false) {
835 this.enableTouchActivity();
840 * Dispose of the `Component` and all child components.
842 * @fires Component#dispose
846 Component.prototype.dispose = function dispose() {
849 * Triggered when a `Component` is disposed.
851 * @event Component#dispose
852 * @type {EventTarget~Event}
854 * @property {boolean} [bubbles=false]
855 * set to false so that the close event does not
858 this.trigger({ type: 'dispose', bubbles: false });
860 // Dispose all children.
861 if (this.children_) {
862 for (var i = this.children_.length - 1; i >= 0; i--) {
863 if (this.children_[i].dispose) {
864 this.children_[i].dispose();
869 // Delete child references
870 this.children_ = null;
871 this.childIndex_ = null;
872 this.childNameIndex_ = null;
874 // Remove all event listeners.
877 // Remove element from DOM
878 if (this.el_.parentNode) {
879 this.el_.parentNode.removeChild(this.el_);
882 Dom.removeElData(this.el_);
887 * Return the {@link Player} that the `Component` has attached to.
890 * The player that this `Component` has attached to.
894 Component.prototype.player = function player() {
899 * Deep merge of options objects with new options.
900 * > Note: When both `obj` and `options` contain properties whose values are objects.
901 * The two properties get merged using {@link module:mergeOptions}
903 * @param {Object} obj
904 * The object that contains new options.
907 * A new object of `this.options_` and `obj` merged together.
909 * @deprecated since version 5
913 Component.prototype.options = function options(obj) {
914 _log2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0');
917 return this.options_;
920 this.options_ = (0, _mergeOptions2['default'])(this.options_, obj);
921 return this.options_;
925 * Get the `Component`s DOM element
928 * The DOM element for this `Component`.
932 Component.prototype.el = function el() {
937 * Create the `Component`s DOM element.
939 * @param {string} [tagName]
940 * Element's DOM node type. e.g. 'div'
942 * @param {Object} [properties]
943 * An object of properties that should be set.
945 * @param {Object} [attributes]
946 * An object of attributes that should be set.
949 * The element that gets created.
953 Component.prototype.createEl = function createEl(tagName, properties, attributes) {
954 return Dom.createEl(tagName, properties, attributes);
958 * Localize a string given the string in english.
960 * @param {string} string
961 * The string to localize.
964 * The localized string or if no localization exists the english string.
968 Component.prototype.localize = function localize(string) {
969 var code = this.player_.language && this.player_.language();
970 var languages = this.player_.languages && this.player_.languages();
972 if (!code || !languages) {
976 var language = languages[code];
978 if (language && language[string]) {
979 return language[string];
982 var primaryCode = code.split('-')[0];
983 var primaryLang = languages[primaryCode];
985 if (primaryLang && primaryLang[string]) {
986 return primaryLang[string];
993 * Return the `Component`s DOM element. This is where children get inserted.
994 * This will usually be the the same as the element returned in {@link Component#el}.
997 * The content element for this `Component`.
1001 Component.prototype.contentEl = function contentEl() {
1002 return this.contentEl_ || this.el_;
1006 * Get this `Component`s ID
1009 * The id of this `Component`
1013 Component.prototype.id = function id() {
1018 * Get the `Component`s name. The name gets used to reference the `Component`
1019 * and is set during registration.
1022 * The name of this `Component`.
1026 Component.prototype.name = function name() {
1031 * Get an array of all child components
1038 Component.prototype.children = function children() {
1039 return this.children_;
1043 * Returns the child `Component` with the given `id`.
1045 * @param {string} id
1046 * The id of the child `Component` to get.
1048 * @return {Component|undefined}
1049 * The child `Component` with the given `id` or undefined.
1053 Component.prototype.getChildById = function getChildById(id) {
1054 return this.childIndex_[id];
1058 * Returns the child `Component` with the given `name`.
1060 * @param {string} name
1061 * The name of the child `Component` to get.
1063 * @return {Component|undefined}
1064 * The child `Component` with the given `name` or undefined.
1068 Component.prototype.getChild = function getChild(name) {
1073 name = (0, _toTitleCase2['default'])(name);
1075 return this.childNameIndex_[name];
1079 * Add a child `Component` inside the current `Component`.
1082 * @param {string|Component} child
1083 * The name or instance of a child to add.
1085 * @param {Object} [options={}]
1086 * The key/value store of options that will get passed to children of
1089 * @param {number} [index=this.children_.length]
1090 * The index to attempt to add a child into.
1092 * @return {Component}
1093 * The `Component` that gets added as a child. When using a string the
1094 * `Component` will get created by this process.
1098 Component.prototype.addChild = function addChild(child) {
1099 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1100 var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.children_.length;
1102 var component = void 0;
1103 var componentName = void 0;
1105 // If child is a string, create component with options
1106 if (typeof child === 'string') {
1107 componentName = (0, _toTitleCase2['default'])(child);
1109 // Options can also be specified as a boolean,
1110 // so convert to an empty object if false.
1115 // Same as above, but true is deprecated so show a warning.
1116 if (options === true) {
1117 _log2['default'].warn('Initializing a child component with `true` is deprecated.' + 'Children should be defined in an array when possible, ' + 'but if necessary use an object instead of `true`.');
1121 var componentClassName = options.componentClass || componentName;
1123 // Set name through options
1124 options.name = componentName;
1126 // Create a new object & element for this controls set
1127 // If there's no .player_, this is a player
1128 var ComponentClass = Component.getComponent(componentClassName);
1130 if (!ComponentClass) {
1131 throw new Error('Component ' + componentClassName + ' does not exist');
1134 // data stored directly on the videojs object may be
1135 // misidentified as a component to retain
1136 // backwards-compatibility with 4.x. check to make sure the
1137 // component class can be instantiated.
1138 if (typeof ComponentClass !== 'function') {
1142 component = new ComponentClass(this.player_ || this, options);
1144 // child is a component instance
1149 this.children_.splice(index, 0, component);
1151 if (typeof component.id === 'function') {
1152 this.childIndex_[component.id()] = component;
1155 // If a name wasn't used to create the component, check if we can use the
1156 // name function of the component
1157 componentName = componentName || component.name && (0, _toTitleCase2['default'])(component.name());
1159 if (componentName) {
1160 this.childNameIndex_[componentName] = component;
1163 // Add the UI object's element to the container div (box)
1164 // Having an element is not required
1165 if (typeof component.el === 'function' && component.el()) {
1166 var childNodes = this.contentEl().children;
1167 var refNode = childNodes[index] || null;
1169 this.contentEl().insertBefore(component.el(), refNode);
1172 // Return so it can stored on parent object if desired.
1177 * Remove a child `Component` from this `Component`s list of children. Also removes
1178 * the child `Component`s element from this `Component`s element.
1180 * @param {Component} component
1181 * The child `Component` to remove.
1185 Component.prototype.removeChild = function removeChild(component) {
1186 if (typeof component === 'string') {
1187 component = this.getChild(component);
1190 if (!component || !this.children_) {
1194 var childFound = false;
1196 for (var i = this.children_.length - 1; i >= 0; i--) {
1197 if (this.children_[i] === component) {
1199 this.children_.splice(i, 1);
1208 this.childIndex_[component.id()] = null;
1209 this.childNameIndex_[component.name()] = null;
1211 var compEl = component.el();
1213 if (compEl && compEl.parentNode === this.contentEl()) {
1214 this.contentEl().removeChild(component.el());
1219 * Add and initialize default child `Component`s based upon options.
1223 Component.prototype.initChildren = function initChildren() {
1226 var children = this.options_.children;
1229 // `this` is `parent`
1230 var parentOptions = this.options_;
1232 var handleAdd = function handleAdd(child) {
1233 var name = child.name;
1234 var opts = child.opts;
1236 // Allow options for children to be set at the parent options
1237 // e.g. videojs(id, { controlBar: false });
1238 // instead of videojs(id, { children: { controlBar: false });
1239 if (parentOptions[name] !== undefined) {
1240 opts = parentOptions[name];
1243 // Allow for disabling default components
1244 // e.g. options['children']['posterImage'] = false
1245 if (opts === false) {
1249 // Allow options to be passed as a simple boolean if no configuration
1251 if (opts === true) {
1255 // We also want to pass the original player options
1256 // to each component as well so they don't need to
1257 // reach back into the player for options later.
1258 opts.playerOptions = _this.options_.playerOptions;
1260 // Create and add the child component.
1261 // Add a direct reference to the child by name on the parent instance.
1262 // If two of the same component are used, different names should be supplied
1264 var newChild = _this.addChild(name, opts);
1267 _this[name] = newChild;
1271 // Allow for an array of children details to passed in the options
1272 var workingChildren = void 0;
1273 var Tech = Component.getComponent('Tech');
1275 if (Array.isArray(children)) {
1276 workingChildren = children;
1278 workingChildren = Object.keys(children);
1282 // children that are in this.options_ but also in workingChildren would
1283 // give us extra children we do not want. So, we want to filter them out.
1284 .concat(Object.keys(this.options_).filter(function (child) {
1285 return !workingChildren.some(function (wchild) {
1286 if (typeof wchild === 'string') {
1287 return child === wchild;
1289 return child === wchild.name;
1291 })).map(function (child) {
1295 if (typeof child === 'string') {
1297 opts = children[name] || _this.options_[name] || {};
1303 return { name: name, opts: opts };
1304 }).filter(function (child) {
1305 // we have to make sure that child.name isn't in the techOrder since
1306 // techs are registerd as Components but can't aren't compatible
1307 // See https://github.com/videojs/video.js/issues/2772
1308 var c = Component.getComponent(child.opts.componentClass || (0, _toTitleCase2['default'])(child.name));
1310 return c && !Tech.isTech(c);
1311 }).forEach(handleAdd);
1316 * Builds the default DOM class name. Should be overriden by sub-components.
1319 * The DOM class name for this object.
1325 Component.prototype.buildCSSClass = function buildCSSClass() {
1326 // Child classes can include a function that does:
1327 // return 'CLASS NAME' + this._super();
1332 * Add an `event listener` to this `Component`s element.
1334 * The benefit of using this over the following:
1335 * - `VjsEvents.on(otherElement, 'eventName', myFunc)`
1336 * - `otherComponent.on('eventName', myFunc)`
1338 * 1. Is that the listeners will get cleaned up when either component gets disposed.
1339 * 1. It will also bind `myComponent` as the context of `myFunc`.
1340 * > NOTE: If you remove the element from the DOM that has used `on` you need to
1341 * clean up references using: `myComponent.trigger(el, 'dispose')`
1342 * This will also allow the browser to garbage collect it. In special
1343 * cases such as with `window` and `document`, which are both permanent,
1344 * this is not necessary.
1346 * @param {string|Component|string[]} [first]
1347 * The event name, and array of event names, or another `Component`.
1349 * @param {EventTarget~EventListener|string|string[]} [second]
1350 * The listener function, an event name, or an Array of events names.
1352 * @param {EventTarget~EventListener} [third]
1353 * The event handler if `first` is a `Component` and `second` is an event name
1354 * or an Array of event names.
1356 * @return {Component}
1357 * Returns itself; method can be chained.
1359 * @listens Component#dispose
1363 Component.prototype.on = function on(first, second, third) {
1366 if (typeof first === 'string' || Array.isArray(first)) {
1367 Events.on(this.el_, first, Fn.bind(this, second));
1369 // Targeting another component or element
1373 var fn = Fn.bind(this, third);
1375 // When this component is disposed, remove the listener from the other component
1376 var removeOnDispose = function removeOnDispose() {
1377 return _this2.off(target, type, fn);
1380 // Use the same function ID so we can remove it later it using the ID
1381 // of the original listener
1382 removeOnDispose.guid = fn.guid;
1383 this.on('dispose', removeOnDispose);
1385 // If the other component is disposed first we need to clean the reference
1386 // to the other component in this component's removeOnDispose listener
1387 // Otherwise we create a memory leak.
1388 var cleanRemover = function cleanRemover() {
1389 return _this2.off('dispose', removeOnDispose);
1392 // Add the same function ID so we can easily remove it later
1393 cleanRemover.guid = fn.guid;
1395 // Check if this is a DOM node
1396 if (first.nodeName) {
1397 // Add the listener to the other element
1398 Events.on(target, type, fn);
1399 Events.on(target, 'dispose', cleanRemover);
1401 // Should be a component
1402 // Not using `instanceof Component` because it makes mock players difficult
1403 } else if (typeof first.on === 'function') {
1404 // Add the listener to the other component
1405 target.on(type, fn);
1406 target.on('dispose', cleanRemover);
1414 * Remove an event listener from this `Component`s element. If the second argument is
1415 * exluded all listeners for the type passed in as the first argument will be removed.
1417 * @param {string|Component|string[]} [first]
1418 * The event name, and array of event names, or another `Component`.
1420 * @param {EventTarget~EventListener|string|string[]} [second]
1421 * The listener function, an event name, or an Array of events names.
1423 * @param {EventTarget~EventListener} [third]
1424 * The event handler if `first` is a `Component` and `second` is an event name
1425 * or an Array of event names.
1427 * @return {Component}
1428 * Returns itself; method can be chained.
1432 Component.prototype.off = function off(first, second, third) {
1433 if (!first || typeof first === 'string' || Array.isArray(first)) {
1434 Events.off(this.el_, first, second);
1438 // Ensure there's at least a guid, even if the function hasn't been used
1439 var fn = Fn.bind(this, third);
1441 // Remove the dispose listener on this component,
1442 // which was given the same guid as the event listener
1443 this.off('dispose', fn);
1445 if (first.nodeName) {
1446 // Remove the listener
1447 Events.off(target, type, fn);
1448 // Remove the listener for cleaning the dispose listener
1449 Events.off(target, 'dispose', fn);
1451 target.off(type, fn);
1452 target.off('dispose', fn);
1460 * Add an event listener that gets triggered only once and then gets removed.
1462 * @param {string|Component|string[]} [first]
1463 * The event name, and array of event names, or another `Component`.
1465 * @param {EventTarget~EventListener|string|string[]} [second]
1466 * The listener function, an event name, or an Array of events names.
1468 * @param {EventTarget~EventListener} [third]
1469 * The event handler if `first` is a `Component` and `second` is an event name
1470 * or an Array of event names.
1472 * @return {Component}
1473 * Returns itself; method can be chained.
1477 Component.prototype.one = function one(first, second, third) {
1479 _arguments = arguments;
1481 if (typeof first === 'string' || Array.isArray(first)) {
1482 Events.one(this.el_, first, Fn.bind(this, second));
1486 var fn = Fn.bind(this, third);
1488 var newFunc = function newFunc() {
1489 _this3.off(target, type, newFunc);
1490 fn.apply(null, _arguments);
1493 // Keep the same function ID so we can remove it later
1494 newFunc.guid = fn.guid;
1496 this.on(target, type, newFunc);
1503 * Trigger an event on an element.
1505 * @param {EventTarget~Event|Object|string} event
1506 * The event name, and Event, or an event-like object with a type attribute
1507 * set to the event name.
1509 * @param {Object} [hash]
1510 * Data hash to pass along with the event
1512 * @return {Component}
1513 * Returns itself; method can be chained.
1517 Component.prototype.trigger = function trigger(event, hash) {
1518 Events.trigger(this.el_, event, hash);
1523 * Bind a listener to the component's ready state. If the ready event has already
1524 * happened it will trigger the function immediately.
1526 * @param {Component~ReadyCallback} fn
1527 * A function to call when ready is triggered.
1529 * @param {boolean} [sync=false]
1530 * Execute the listener synchronously if `Component` is ready.
1532 * @return {Component}
1533 * Returns itself; method can be chained.
1537 Component.prototype.ready = function ready(fn) {
1538 var sync = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1541 if (this.isReady_) {
1545 // Call the function asynchronously by default for consistency
1546 this.setTimeout(fn, 1);
1549 this.readyQueue_ = this.readyQueue_ || [];
1550 this.readyQueue_.push(fn);
1557 * Trigger all the ready listeners for this `Component`.
1559 * @fires Component#ready
1563 Component.prototype.triggerReady = function triggerReady() {
1564 this.isReady_ = true;
1566 // Ensure ready is triggerd asynchronously
1567 this.setTimeout(function () {
1568 var readyQueue = this.readyQueue_;
1570 // Reset Ready Queue
1571 this.readyQueue_ = [];
1573 if (readyQueue && readyQueue.length > 0) {
1574 readyQueue.forEach(function (fn) {
1579 // Allow for using event listeners also
1581 * Triggered when a `Component` is ready.
1583 * @event Component#ready
1584 * @type {EventTarget~Event}
1586 this.trigger('ready');
1591 * Find a single DOM element matching a `selector`. This can be within the `Component`s
1592 * `contentEl()` or another custom context.
1594 * @param {string} selector
1595 * A valid CSS selector, which will be passed to `querySelector`.
1597 * @param {Element|string} [context=this.contentEl()]
1598 * A DOM element within which to query. Can also be a selector string in
1599 * which case the first matching element will get used as context. If
1600 * missing `this.contentEl()` gets used. If `this.contentEl()` returns
1601 * nothing it falls back to `document`.
1603 * @return {Element|null}
1604 * the dom element that was found, or null
1606 * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
1610 Component.prototype.$ = function $(selector, context) {
1611 return Dom.$(selector, context || this.contentEl());
1615 * Finds all DOM element matching a `selector`. This can be within the `Component`s
1616 * `contentEl()` or another custom context.
1618 * @param {string} selector
1619 * A valid CSS selector, which will be passed to `querySelectorAll`.
1621 * @param {Element|string} [context=this.contentEl()]
1622 * A DOM element within which to query. Can also be a selector string in
1623 * which case the first matching element will get used as context. If
1624 * missing `this.contentEl()` gets used. If `this.contentEl()` returns
1625 * nothing it falls back to `document`.
1627 * @return {NodeList}
1628 * a list of dom elements that were found
1630 * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
1634 Component.prototype.$$ = function $$(selector, context) {
1635 return Dom.$$(selector, context || this.contentEl());
1639 * Check if a component's element has a CSS class name.
1641 * @param {string} classToCheck
1642 * CSS class name to check.
1645 * - True if the `Component` has the class.
1646 * - False if the `Component` does not have the class`
1650 Component.prototype.hasClass = function hasClass(classToCheck) {
1651 return Dom.hasElClass(this.el_, classToCheck);
1655 * Add a CSS class name to the `Component`s element.
1657 * @param {string} classToAdd
1658 * CSS class name to add
1660 * @return {Component}
1661 * Returns itself; method can be chained.
1665 Component.prototype.addClass = function addClass(classToAdd) {
1666 Dom.addElClass(this.el_, classToAdd);
1671 * Remove a CSS class name from the `Component`s element.
1673 * @param {string} classToRemove
1674 * CSS class name to remove
1676 * @return {Component}
1677 * Returns itself; method can be chained.
1681 Component.prototype.removeClass = function removeClass(classToRemove) {
1682 Dom.removeElClass(this.el_, classToRemove);
1687 * Add or remove a CSS class name from the component's element.
1688 * - `classToToggle` gets added when {@link Component#hasClass} would return false.
1689 * - `classToToggle` gets removed when {@link Component#hasClass} would return true.
1691 * @param {string} classToToggle
1692 * The class to add or remove based on (@link Component#hasClass}
1694 * @param {boolean|Dom~predicate} [predicate]
1695 * An {@link Dom~predicate} function or a boolean
1697 * @return {Component}
1698 * Returns itself; method can be chained.
1702 Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) {
1703 Dom.toggleElClass(this.el_, classToToggle, predicate);
1708 * Show the `Component`s element if it is hidden by removing the
1709 * 'vjs-hidden' class name from it.
1711 * @return {Component}
1712 * Returns itself; method can be chained.
1716 Component.prototype.show = function show() {
1717 this.removeClass('vjs-hidden');
1722 * Hide the `Component`s element if it is currently showing by adding the
1723 * 'vjs-hidden` class name to it.
1725 * @return {Component}
1726 * Returns itself; method can be chained.
1730 Component.prototype.hide = function hide() {
1731 this.addClass('vjs-hidden');
1736 * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing'
1737 * class name to it. Used during fadeIn/fadeOut.
1739 * @return {Component}
1740 * Returns itself; method can be chained.
1746 Component.prototype.lockShowing = function lockShowing() {
1747 this.addClass('vjs-lock-showing');
1752 * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing'
1753 * class name from it. Used during fadeIn/fadeOut.
1755 * @return {Component}
1756 * Returns itself; method can be chained.
1762 Component.prototype.unlockShowing = function unlockShowing() {
1763 this.removeClass('vjs-lock-showing');
1768 * Get the value of an attribute on the `Component`s element.
1770 * @param {string} attribute
1771 * Name of the attribute to get the value from.
1773 * @return {string|null}
1774 * - The value of the attribute that was asked for.
1775 * - Can be an empty string on some browsers if the attribute does not exist
1777 * - Most browsers will return null if the attibute does not exist or has
1780 * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute}
1784 Component.prototype.getAttribute = function getAttribute(attribute) {
1785 return Dom.getAttribute(this.el_, attribute);
1789 * Set the value of an attribute on the `Component`'s element
1791 * @param {string} attribute
1792 * Name of the attribute to set.
1794 * @param {string} value
1795 * Value to set the attribute to.
1797 * @return {Component}
1798 * Returns itself; method can be chained.
1800 * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute}
1804 Component.prototype.setAttribute = function setAttribute(attribute, value) {
1805 Dom.setAttribute(this.el_, attribute, value);
1810 * Remove an attribute from the `Component`s element.
1812 * @param {string} attribute
1813 * Name of the attribute to remove.
1815 * @return {Component}
1816 * Returns itself; method can be chained.
1818 * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute}
1822 Component.prototype.removeAttribute = function removeAttribute(attribute) {
1823 Dom.removeAttribute(this.el_, attribute);
1828 * Get or set the width of the component based upon the CSS styles.
1829 * See {@link Component#dimension} for more detailed information.
1831 * @param {number|string} [num]
1832 * The width that you want to set postfixed with '%', 'px' or nothing.
1834 * @param {boolean} [skipListeners]
1835 * Skip the resize event trigger
1837 * @return {Component|number|string}
1838 * - The width when getting, zero if there is no width. Can be a string
1839 * postpixed with '%' or 'px'.
1840 * - Returns itself when setting; method can be chained.
1844 Component.prototype.width = function width(num, skipListeners) {
1845 return this.dimension('width', num, skipListeners);
1849 * Get or set the height of the component based upon the CSS styles.
1850 * See {@link Component#dimension} for more detailed information.
1852 * @param {number|string} [num]
1853 * The height that you want to set postfixed with '%', 'px' or nothing.
1855 * @param {boolean} [skipListeners]
1856 * Skip the resize event trigger
1858 * @return {Component|number|string}
1859 * - The width when getting, zero if there is no width. Can be a string
1860 * postpixed with '%' or 'px'.
1861 * - Returns itself when setting; method can be chained.
1865 Component.prototype.height = function height(num, skipListeners) {
1866 return this.dimension('height', num, skipListeners);
1870 * Set both the width and height of the `Component` element at the same time.
1872 * @param {number|string} width
1873 * Width to set the `Component`s element to.
1875 * @param {number|string} height
1876 * Height to set the `Component`s element to.
1878 * @return {Component}
1879 * Returns itself; method can be chained.
1883 Component.prototype.dimensions = function dimensions(width, height) {
1884 // Skip resize listeners on width for optimization
1885 return this.width(width, true).height(height);
1889 * Get or set width or height of the `Component` element. This is the shared code
1890 * for the {@link Component#width} and {@link Component#height}.
1893 * - If the width or height in an number this will return the number postfixed with 'px'.
1894 * - If the width/height is a percent this will return the percent postfixed with '%'
1895 * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function
1896 * defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`.
1897 * See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/}
1898 * for more information
1899 * - If you want the computed style of the component, use {@link Component#currentWidth}
1900 * and {@link {Component#currentHeight}
1902 * @fires Component#resize
1904 * @param {string} widthOrHeight
1905 8 'width' or 'height'
1907 * @param {number|string} [num]
1910 * @param {boolean} [skipListeners]
1911 * Skip resize event trigger
1913 * @return {Component}
1914 * - the dimension when getting or 0 if unset
1915 * - Returns itself when setting; method can be chained.
1919 Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) {
1920 if (num !== undefined) {
1921 // Set to zero if null or literally NaN (NaN !== NaN)
1922 if (num === null || num !== num) {
1926 // Check if using css width/height (% or px) and adjust
1927 if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) {
1928 this.el_.style[widthOrHeight] = num;
1929 } else if (num === 'auto') {
1930 this.el_.style[widthOrHeight] = '';
1932 this.el_.style[widthOrHeight] = num + 'px';
1935 // skipListeners allows us to avoid triggering the resize event when setting both width and height
1936 if (!skipListeners) {
1938 * Triggered when a component is resized.
1940 * @event Component#resize
1941 * @type {EventTarget~Event}
1943 this.trigger('resize');
1950 // Not setting a value, so getting it
1951 // Make sure element exists
1956 // Get dimension value from style
1957 var val = this.el_.style[widthOrHeight];
1958 var pxIndex = val.indexOf('px');
1960 if (pxIndex !== -1) {
1961 // Return the pixel value with no 'px'
1962 return parseInt(val.slice(0, pxIndex), 10);
1965 // No px so using % or no style was set, so falling back to offsetWidth/height
1966 // If component has display:none, offset will return 0
1967 // TODO: handle display:none and no dimension style using px
1968 return parseInt(this.el_['offset' + (0, _toTitleCase2['default'])(widthOrHeight)], 10);
1972 * Get the width or the height of the `Component` elements computed style. Uses
1973 * `window.getComputedStyle`.
1975 * @param {string} widthOrHeight
1976 * A string containing 'width' or 'height'. Whichever one you want to get.
1979 * The dimension that gets asked for or 0 if nothing was set
1980 * for that dimension.
1984 Component.prototype.currentDimension = function currentDimension(widthOrHeight) {
1985 var computedWidthOrHeight = 0;
1987 if (widthOrHeight !== 'width' && widthOrHeight !== 'height') {
1988 throw new Error('currentDimension only accepts width or height value');
1991 if (typeof _window2['default'].getComputedStyle === 'function') {
1992 var computedStyle = _window2['default'].getComputedStyle(this.el_);
1994 computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight];
1997 // remove 'px' from variable and parse as integer
1998 computedWidthOrHeight = parseFloat(computedWidthOrHeight);
2000 // if the computed value is still 0, it's possible that the browser is lying
2001 // and we want to check the offset values.
2002 // This code also runs on IE8 and wherever getComputedStyle doesn't exist.
2003 if (computedWidthOrHeight === 0) {
2004 var rule = 'offset' + (0, _toTitleCase2['default'])(widthOrHeight);
2006 computedWidthOrHeight = this.el_[rule];
2009 return computedWidthOrHeight;
2013 * An object that contains width and height values of the `Component`s
2014 * computed style. Uses `window.getComputedStyle`.
2016 * @typedef {Object} Component~DimensionObject
2018 * @property {number} width
2019 * The width of the `Component`s computed style.
2021 * @property {number} height
2022 * The height of the `Component`s computed style.
2026 * Get an object that contains width and height values of the `Component`s
2029 * @return {Component~DimensionObject}
2030 * The dimensions of the components element
2034 Component.prototype.currentDimensions = function currentDimensions() {
2036 width: this.currentDimension('width'),
2037 height: this.currentDimension('height')
2042 * Get the width of the `Component`s computed style. Uses `window.getComputedStyle`.
2044 * @return {number} width
2045 * The width of the `Component`s computed style.
2049 Component.prototype.currentWidth = function currentWidth() {
2050 return this.currentDimension('width');
2054 * Get the height of the `Component`s computed style. Uses `window.getComputedStyle`.
2056 * @return {number} height
2057 * The height of the `Component`s computed style.
2061 Component.prototype.currentHeight = function currentHeight() {
2062 return this.currentDimension('height');
2066 * Set the focus to this component
2070 Component.prototype.focus = function focus() {
2075 * Remove the focus from this component
2079 Component.prototype.blur = function blur() {
2084 * Emit a 'tap' events when touch event support gets detected. This gets used to
2085 * support toggling the controls through a tap on the video. They get enabled
2086 * because every sub-component would have extra overhead otherwise.
2089 * @fires Component#tap
2090 * @listens Component#touchstart
2091 * @listens Component#touchmove
2092 * @listens Component#touchleave
2093 * @listens Component#touchcancel
2094 * @listens Component#touchend
2098 Component.prototype.emitTapEvents = function emitTapEvents() {
2099 // Track the start time so we can determine how long the touch lasted
2101 var firstTouch = null;
2103 // Maximum movement allowed during a touch event to still be considered a tap
2104 // Other popular libs use anywhere from 2 (hammer.js) to 15,
2105 // so 10 seems like a nice, round number.
2106 var tapMovementThreshold = 10;
2108 // The maximum length a touch can be while still being considered a tap
2109 var touchTimeThreshold = 200;
2111 var couldBeTap = void 0;
2113 this.on('touchstart', function (event) {
2114 // If more than one finger, don't consider treating this as a click
2115 if (event.touches.length === 1) {
2116 // Copy pageX/pageY from the object
2118 pageX: event.touches[0].pageX,
2119 pageY: event.touches[0].pageY
2121 // Record start time so we can detect a tap vs. "touch and hold"
2122 touchStart = new Date().getTime();
2123 // Reset couldBeTap tracking
2128 this.on('touchmove', function (event) {
2129 // If more than one finger, don't consider treating this as a click
2130 if (event.touches.length > 1) {
2132 } else if (firstTouch) {
2133 // Some devices will throw touchmoves for all but the slightest of taps.
2134 // So, if we moved only a small distance, this could still be a tap
2135 var xdiff = event.touches[0].pageX - firstTouch.pageX;
2136 var ydiff = event.touches[0].pageY - firstTouch.pageY;
2137 var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
2139 if (touchDistance > tapMovementThreshold) {
2145 var noTap = function noTap() {
2149 // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s
2150 this.on('touchleave', noTap);
2151 this.on('touchcancel', noTap);
2153 // When the touch ends, measure how long it took and trigger the appropriate
2155 this.on('touchend', function (event) {
2157 // Proceed only if the touchmove/leave/cancel event didn't happen
2158 if (couldBeTap === true) {
2159 // Measure how long the touch lasted
2160 var touchTime = new Date().getTime() - touchStart;
2162 // Make sure the touch was less than the threshold to be considered a tap
2163 if (touchTime < touchTimeThreshold) {
2164 // Don't let browser turn this into a click
2165 event.preventDefault();
2167 * Triggered when a `Component` is tapped.
2169 * @event Component#tap
2170 * @type {EventTarget~Event}
2172 this.trigger('tap');
2173 // It may be good to copy the touchend event object and change the
2174 // type to tap, if the other event properties aren't exact after
2175 // Events.fixEvent runs (e.g. event.target)
2182 * This function reports user activity whenever touch events happen. This can get
2183 * turned off by any sub-components that wants touch events to act another way.
2185 * Report user touch activity when touch events occur. User activity gets used to
2186 * determine when controls should show/hide. It is simple when it comes to mouse
2187 * events, because any mouse event should show the controls. So we capture mouse
2188 * events that bubble up to the player and report activity when that happens.
2189 * With touch events it isn't as easy as `touchstart` and `touchend` toggle player
2190 * controls. So touch events can't help us at the player level either.
2192 * User activity gets checked asynchronously. So what could happen is a tap event
2193 * on the video turns the controls off. Then the `touchend` event bubbles up to
2194 * the player. Which, if it reported user activity, would turn the controls right
2195 * back on. We also don't want to completely block touch events from bubbling up.
2196 * Furthermore a `touchmove` event and anything other than a tap, should not turn
2199 * @listens Component#touchstart
2200 * @listens Component#touchmove
2201 * @listens Component#touchend
2202 * @listens Component#touchcancel
2206 Component.prototype.enableTouchActivity = function enableTouchActivity() {
2207 // Don't continue if the root player doesn't support reporting user activity
2208 if (!this.player() || !this.player().reportUserActivity) {
2212 // listener for reporting that the user is active
2213 var report = Fn.bind(this.player(), this.player().reportUserActivity);
2215 var touchHolding = void 0;
2217 this.on('touchstart', function () {
2219 // For as long as the they are touching the device or have their mouse down,
2220 // we consider them active even if they're not moving their finger or mouse.
2221 // So we want to continue to update that they are active
2222 this.clearInterval(touchHolding);
2223 // report at the same interval as activityCheck
2224 touchHolding = this.setInterval(report, 250);
2227 var touchEnd = function touchEnd(event) {
2229 // stop the interval that maintains activity if the touch is holding
2230 this.clearInterval(touchHolding);
2233 this.on('touchmove', report);
2234 this.on('touchend', touchEnd);
2235 this.on('touchcancel', touchEnd);
2239 * A callback that has no parameters and is bound into `Component`s context.
2241 * @callback Component~GenericCallback
2246 * Creates a function that runs after an `x` millisecond timeout. This function is a
2247 * wrapper around `window.setTimeout`. There are a few reasons to use this one
2249 * 1. It gets cleared via {@link Component#clearTimeout} when
2250 * {@link Component#dispose} gets called.
2251 * 2. The function callback will gets turned into a {@link Component~GenericCallback}
2253 * > Note: You can use `window.clearTimeout` on the id returned by this function. This
2254 * will cause its dispose listener not to get cleaned up! Please use
2255 * {@link Component#clearTimeout} or {@link Component#dispose}.
2257 * @param {Component~GenericCallback} fn
2258 * The function that will be run after `timeout`.
2260 * @param {number} timeout
2261 * Timeout in milliseconds to delay before executing the specified function.
2264 * Returns a timeout ID that gets used to identify the timeout. It can also
2265 * get used in {@link Component#clearTimeout} to clear the timeout that
2268 * @listens Component#dispose
2269 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout}
2273 Component.prototype.setTimeout = function setTimeout(fn, timeout) {
2274 fn = Fn.bind(this, fn);
2276 var timeoutId = _window2['default'].setTimeout(fn, timeout);
2277 var disposeFn = function disposeFn() {
2278 this.clearTimeout(timeoutId);
2281 disposeFn.guid = 'vjs-timeout-' + timeoutId;
2283 this.on('dispose', disposeFn);
2289 * Clears a timeout that gets created via `window.setTimeout` or
2290 * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout}
2291 * use this function instead of `window.clearTimout`. If you don't your dispose
2292 * listener will not get cleaned up until {@link Component#dispose}!
2294 * @param {number} timeoutId
2295 * The id of the timeout to clear. The return value of
2296 * {@link Component#setTimeout} or `window.setTimeout`.
2299 * Returns the timeout id that was cleared.
2301 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout}
2305 Component.prototype.clearTimeout = function clearTimeout(timeoutId) {
2306 _window2['default'].clearTimeout(timeoutId);
2308 var disposeFn = function disposeFn() {};
2310 disposeFn.guid = 'vjs-timeout-' + timeoutId;
2312 this.off('dispose', disposeFn);
2318 * Creates a function that gets run every `x` milliseconds. This function is a wrapper
2319 * around `window.setInterval`. There are a few reasons to use this one instead though.
2320 * 1. It gets cleared via {@link Component#clearInterval} when
2321 * {@link Component#dispose} gets called.
2322 * 2. The function callback will be a {@link Component~GenericCallback}
2324 * @param {Component~GenericCallback} fn
2325 * The function to run every `x` seconds.
2327 * @param {number} interval
2328 * Execute the specified function every `x` milliseconds.
2331 * Returns an id that can be used to identify the interval. It can also be be used in
2332 * {@link Component#clearInterval} to clear the interval.
2334 * @listens Component#dispose
2335 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval}
2339 Component.prototype.setInterval = function setInterval(fn, interval) {
2340 fn = Fn.bind(this, fn);
2342 var intervalId = _window2['default'].setInterval(fn, interval);
2344 var disposeFn = function disposeFn() {
2345 this.clearInterval(intervalId);
2348 disposeFn.guid = 'vjs-interval-' + intervalId;
2350 this.on('dispose', disposeFn);
2356 * Clears an interval that gets created via `window.setInterval` or
2357 * {@link Component#setInterval}. If you set an inteval via {@link Component#setInterval}
2358 * use this function instead of `window.clearInterval`. If you don't your dispose
2359 * listener will not get cleaned up until {@link Component#dispose}!
2361 * @param {number} intervalId
2362 * The id of the interval to clear. The return value of
2363 * {@link Component#setInterval} or `window.setInterval`.
2366 * Returns the interval id that was cleared.
2368 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval}
2372 Component.prototype.clearInterval = function clearInterval(intervalId) {
2373 _window2['default'].clearInterval(intervalId);
2375 var disposeFn = function disposeFn() {};
2377 disposeFn.guid = 'vjs-interval-' + intervalId;
2379 this.off('dispose', disposeFn);
2385 * Register a `Component` with `videojs` given the name and the component.
2387 * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s
2388 * should be registered using {@link Tech.registerTech} or
2389 * {@link videojs:videojs.registerTech}.
2391 * > NOTE: This function can also be seen on videojs as
2392 * {@link videojs:videojs.registerComponent}.
2394 * @param {string} name
2395 * The name of the `Component` to register.
2397 * @param {Component} comp
2398 * The `Component` class to register.
2400 * @return {Component}
2401 * The `Component` that was registered.
2405 Component.registerComponent = function registerComponent(name, comp) {
2410 name = (0, _toTitleCase2['default'])(name);
2412 if (!Component.components_) {
2413 Component.components_ = {};
2416 if (name === 'Player' && Component.components_[name]) {
2417 var Player = Component.components_[name];
2419 // If we have players that were disposed, then their name will still be
2420 // in Players.players. So, we must loop through and verify that the value
2421 // for each item is not null. This allows registration of the Player component
2422 // after all players have been disposed or before any were created.
2423 if (Player.players && Object.keys(Player.players).length > 0 && Object.keys(Player.players).map(function (playerName) {
2424 return Player.players[playerName];
2425 }).every(Boolean)) {
2426 throw new Error('Can not register Player component after player has been created');
2430 Component.components_[name] = comp;
2436 * Get a `Component` based on the name it was registered with.
2438 * @param {string} name
2439 * The Name of the component to get.
2441 * @return {Component}
2442 * The `Component` that got registered under the given name.
2444 * @deprecated In `videojs` 6 this will not return `Component`s that were not
2445 * registered using {@link Component.registerComponent}. Currently we
2446 * check the global `videojs` object for a `Component` name and
2447 * return that if it exists.
2451 Component.getComponent = function getComponent(name) {
2456 name = (0, _toTitleCase2['default'])(name);
2458 if (Component.components_ && Component.components_[name]) {
2459 return Component.components_[name];
2462 if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) {
2463 _log2['default'].warn('The ' + name + ' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)');
2465 return _window2['default'].videojs[name];
2470 * Sets up the constructor using the supplied init method or uses the init of the
2473 * @param {Object} [props={}]
2474 * An object of properties.
2477 * the extended object.
2479 * @deprecated since version 5
2483 Component.extend = function extend(props) {
2484 props = props || {};
2486 _log2['default'].warn('Component.extend({}) has been deprecated, ' + ' use videojs.extend(Component, {}) instead');
2488 // Set up the constructor using the supplied init method
2489 // or using the init of the parent object
2490 // Make sure to check the unobfuscated version for external libs
2491 var init = props.init || props.init || this.prototype.init || this.prototype.init || function () {};
2492 // In Resig's simple class inheritance (previously used) the constructor
2493 // is a function that calls `this.init.apply(arguments)`
2494 // However that would prevent us from using `ParentObject.call(this);`
2495 // in a Child constructor because the `this` in `this.init`
2496 // would still refer to the Child and cause an infinite loop.
2497 // We would instead have to do
2498 // `ParentObject.prototype.init.apply(this, arguments);`
2499 // Bleh. We're not creating a _super() function, so it's good to keep
2500 // the parent constructor reference simple.
2501 var subObj = function subObj() {
2502 init.apply(this, arguments);
2505 // Inherit from this object's prototype
2506 subObj.prototype = Object.create(this.prototype);
2507 // Reset the constructor property for subObj otherwise
2508 // instances of subObj would have the constructor of the parent Object
2509 subObj.prototype.constructor = subObj;
2511 // Make the class extendable
2512 subObj.extend = Component.extend;
2514 // Extend subObj's prototype with functions and other properties from props
2515 for (var name in props) {
2516 if (props.hasOwnProperty(name)) {
2517 subObj.prototype[name] = props[name];
2527 Component.registerComponent('Component', Component);
2528 exports['default'] = Component;
2530 },{"81":81,"82":82,"83":83,"85":85,"86":86,"87":87,"91":91,"95":95}],6:[function(_dereq_,module,exports){
2533 exports.__esModule = true;
2535 var _trackButton = _dereq_(36);
2537 var _trackButton2 = _interopRequireDefault(_trackButton);
2539 var _component = _dereq_(5);
2541 var _component2 = _interopRequireDefault(_component);
2543 var _audioTrackMenuItem = _dereq_(7);
2545 var _audioTrackMenuItem2 = _interopRequireDefault(_audioTrackMenuItem);
2547 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2549 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2551 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
2553 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
2554 * @file audio-track-button.js
2559 * The base class for buttons that toggle specific {@link AudioTrack} types.
2561 * @extends TrackButton
2563 var AudioTrackButton = function (_TrackButton) {
2564 _inherits(AudioTrackButton, _TrackButton);
2567 * Creates an instance of this class.
2569 * @param {Player} player
2570 * The `Player` that this class should be attached to.
2572 * @param {Object} [options={}]
2573 * The key/value store of player options.
2575 function AudioTrackButton(player) {
2576 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2578 _classCallCheck(this, AudioTrackButton);
2580 options.tracks = player.audioTracks && player.audioTracks();
2582 var _this = _possibleConstructorReturn(this, _TrackButton.call(this, player, options));
2584 _this.el_.setAttribute('aria-label', 'Audio Menu');
2589 * Builds the default DOM `className`.
2592 * The DOM `className` for this object.
2596 AudioTrackButton.prototype.buildCSSClass = function buildCSSClass() {
2597 return 'vjs-audio-button ' + _TrackButton.prototype.buildCSSClass.call(this);
2601 * Create a menu item for each audio track
2603 * @param {AudioTrackMenuItem[]} [items=[]]
2604 * An array of existing menu items to use.
2606 * @return {AudioTrackMenuItem[]}
2607 * An array of menu items
2611 AudioTrackButton.prototype.createItems = function createItems() {
2612 var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
2614 // if there's only one audio track, there no point in showing it
2615 this.hideThreshold_ = 1;
2617 var tracks = this.player_.audioTracks && this.player_.audioTracks();
2623 for (var i = 0; i < tracks.length; i++) {
2624 var track = tracks[i];
2626 items.push(new _audioTrackMenuItem2['default'](this.player_, {
2628 // MenuItem is selectable
2636 return AudioTrackButton;
2637 }(_trackButton2['default']);
2640 * The text that should display over the `AudioTrackButton`s controls. Added for localization.
2647 AudioTrackButton.prototype.controlText_ = 'Audio Track';
2648 _component2['default'].registerComponent('AudioTrackButton', AudioTrackButton);
2649 exports['default'] = AudioTrackButton;
2651 },{"36":36,"5":5,"7":7}],7:[function(_dereq_,module,exports){
2654 exports.__esModule = true;
2656 var _menuItem = _dereq_(48);
2658 var _menuItem2 = _interopRequireDefault(_menuItem);
2660 var _component = _dereq_(5);
2662 var _component2 = _interopRequireDefault(_component);
2664 var _fn = _dereq_(83);
2666 var Fn = _interopRequireWildcard(_fn);
2668 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
2670 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2672 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2674 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
2676 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
2677 * @file audio-track-menu-item.js
2682 * An {@link AudioTrack} {@link MenuItem}
2686 var AudioTrackMenuItem = function (_MenuItem) {
2687 _inherits(AudioTrackMenuItem, _MenuItem);
2690 * Creates an instance of this class.
2692 * @param {Player} player
2693 * The `Player` that this class should be attached to.
2695 * @param {Object} [options]
2696 * The key/value store of player options.
2698 function AudioTrackMenuItem(player, options) {
2699 _classCallCheck(this, AudioTrackMenuItem);
2701 var track = options.track;
2702 var tracks = player.audioTracks();
2704 // Modify options for parent MenuItem class's init.
2705 options.label = track.label || track.language || 'Unknown';
2706 options.selected = track.enabled;
2708 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
2710 _this.track = track;
2713 var changeHandler = Fn.bind(_this, _this.handleTracksChange);
2715 tracks.addEventListener('change', changeHandler);
2716 _this.on('dispose', function () {
2717 tracks.removeEventListener('change', changeHandler);
2724 * This gets called when an `AudioTrackMenuItem is "clicked". See {@link ClickableComponent}
2725 * for more detailed information on what a click can be.
2727 * @param {EventTarget~Event} [event]
2728 * The `keydown`, `tap`, or `click` event that caused this function to be
2736 AudioTrackMenuItem.prototype.handleClick = function handleClick(event) {
2737 var tracks = this.player_.audioTracks();
2739 _MenuItem.prototype.handleClick.call(this, event);
2745 for (var i = 0; i < tracks.length; i++) {
2746 var track = tracks[i];
2748 track.enabled = track === this.track;
2753 * Handle any {@link AudioTrack} change.
2755 * @param {EventTarget~Event} [event]
2756 * The {@link AudioTrackList#change} event that caused this to run.
2758 * @listens AudioTrackList#change
2762 AudioTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
2763 this.selected(this.track.enabled);
2766 return AudioTrackMenuItem;
2767 }(_menuItem2['default']);
2769 _component2['default'].registerComponent('AudioTrackMenuItem', AudioTrackMenuItem);
2770 exports['default'] = AudioTrackMenuItem;
2772 },{"48":48,"5":5,"83":83}],8:[function(_dereq_,module,exports){
2775 exports.__esModule = true;
2777 var _component = _dereq_(5);
2779 var _component2 = _interopRequireDefault(_component);
2817 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2819 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2821 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
2823 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
2824 * @file control-bar.js
2828 // Required children
2832 * Container of main controls.
2834 * @extends Component
2836 var ControlBar = function (_Component) {
2837 _inherits(ControlBar, _Component);
2839 function ControlBar() {
2840 _classCallCheck(this, ControlBar);
2842 return _possibleConstructorReturn(this, _Component.apply(this, arguments));
2846 * Create the `Component`'s DOM element
2849 * The element that was created.
2851 ControlBar.prototype.createEl = function createEl() {
2852 return _Component.prototype.createEl.call(this, 'div', {
2853 className: 'vjs-control-bar',
2856 // The control bar is a group, so it can contain menuitems
2862 }(_component2['default']);
2865 * Default options for `ControlBar`
2872 ControlBar.prototype.options_ = {
2873 children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subtitlesButton', 'captionsButton', 'audioTrackButton', 'fullscreenToggle']
2876 _component2['default'].registerComponent('ControlBar', ControlBar);
2877 exports['default'] = ControlBar;
2879 },{"10":10,"11":11,"12":12,"13":13,"18":18,"21":21,"24":24,"25":25,"27":27,"29":29,"32":32,"33":33,"34":34,"35":35,"38":38,"40":40,"5":5,"6":6,"9":9}],9:[function(_dereq_,module,exports){
2882 exports.__esModule = true;
2884 var _button = _dereq_(2);
2886 var _button2 = _interopRequireDefault(_button);
2888 var _component = _dereq_(5);
2890 var _component2 = _interopRequireDefault(_component);
2892 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2894 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2896 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
2898 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
2899 * @file fullscreen-toggle.js
2904 * Toggle fullscreen video
2908 var FullscreenToggle = function (_Button) {
2909 _inherits(FullscreenToggle, _Button);
2912 * Creates an instance of this class.
2914 * @param {Player} player
2915 * The `Player` that this class should be attached to.
2917 * @param {Object} [options]
2918 * The key/value store of player options.
2920 function FullscreenToggle(player, options) {
2921 _classCallCheck(this, FullscreenToggle);
2923 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
2925 _this.on(player, 'fullscreenchange', _this.handleFullscreenChange);
2930 * Builds the default DOM `className`.
2933 * The DOM `className` for this object.
2937 FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() {
2938 return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this);
2942 * Handles fullscreenchange on the player and change control text accordingly.
2944 * @param {EventTarget~Event} [event]
2945 * The {@link Player#fullscreenchange} event that caused this function to be
2948 * @listens Player#fullscreenchange
2952 FullscreenToggle.prototype.handleFullscreenChange = function handleFullscreenChange(event) {
2953 if (this.player_.isFullscreen()) {
2954 this.controlText('Non-Fullscreen');
2956 this.controlText('Fullscreen');
2961 * This gets called when an `FullscreenToggle` is "clicked". See
2962 * {@link ClickableComponent} for more detailed information on what a click can be.
2964 * @param {EventTarget~Event} [event]
2965 * The `keydown`, `tap`, or `click` event that caused this function to be
2973 FullscreenToggle.prototype.handleClick = function handleClick(event) {
2974 if (!this.player_.isFullscreen()) {
2975 this.player_.requestFullscreen();
2977 this.player_.exitFullscreen();
2981 return FullscreenToggle;
2982 }(_button2['default']);
2985 * The text that should display over the `FullscreenToggle`s controls. Added for localization.
2992 FullscreenToggle.prototype.controlText_ = 'Fullscreen';
2994 _component2['default'].registerComponent('FullscreenToggle', FullscreenToggle);
2995 exports['default'] = FullscreenToggle;
2997 },{"2":2,"5":5}],10:[function(_dereq_,module,exports){
3000 exports.__esModule = true;
3002 var _component = _dereq_(5);
3004 var _component2 = _interopRequireDefault(_component);
3006 var _dom = _dereq_(81);
3008 var Dom = _interopRequireWildcard(_dom);
3010 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
3012 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3014 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3016 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3018 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
3019 * @file live-display.js
3023 // TODO - Future make it click to snap to live
3026 * Displays the live indicator when duration is Infinity.
3028 * @extends Component
3030 var LiveDisplay = function (_Component) {
3031 _inherits(LiveDisplay, _Component);
3034 * Creates an instance of this class.
3036 * @param {Player} player
3037 * The `Player` that this class should be attached to.
3039 * @param {Object} [options]
3040 * The key/value store of player options.
3042 function LiveDisplay(player, options) {
3043 _classCallCheck(this, LiveDisplay);
3045 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
3047 _this.updateShowing();
3048 _this.on(_this.player(), 'durationchange', _this.updateShowing);
3053 * Create the `Component`'s DOM element
3056 * The element that was created.
3060 LiveDisplay.prototype.createEl = function createEl() {
3061 var el = _Component.prototype.createEl.call(this, 'div', {
3062 className: 'vjs-live-control vjs-control'
3065 this.contentEl_ = Dom.createEl('div', {
3066 className: 'vjs-live-display',
3067 innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE')
3072 el.appendChild(this.contentEl_);
3077 * Check the duration to see if the LiveDisplay should be showing or not. Then show/hide
3080 * @param {EventTarget~Event} [event]
3081 * The {@link Player#durationchange} event that caused this function to run.
3083 * @listens Player#durationchange
3087 LiveDisplay.prototype.updateShowing = function updateShowing(event) {
3088 if (this.player().duration() === Infinity) {
3096 }(_component2['default']);
3098 _component2['default'].registerComponent('LiveDisplay', LiveDisplay);
3099 exports['default'] = LiveDisplay;
3101 },{"5":5,"81":81}],11:[function(_dereq_,module,exports){
3104 exports.__esModule = true;
3106 var _button = _dereq_(2);
3108 var _button2 = _interopRequireDefault(_button);
3110 var _component = _dereq_(5);
3112 var _component2 = _interopRequireDefault(_component);
3114 var _dom = _dereq_(81);
3116 var Dom = _interopRequireWildcard(_dom);
3118 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
3120 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3122 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3124 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3126 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
3127 * @file mute-toggle.js
3132 * A button component for muting the audio.
3136 var MuteToggle = function (_Button) {
3137 _inherits(MuteToggle, _Button);
3140 * Creates an instance of this class.
3142 * @param {Player} player
3143 * The `Player` that this class should be attached to.
3145 * @param {Object} [options]
3146 * The key/value store of player options.
3148 function MuteToggle(player, options) {
3149 _classCallCheck(this, MuteToggle);
3151 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
3153 _this.on(player, 'volumechange', _this.update);
3155 // hide mute toggle if the current tech doesn't support volume control
3156 if (player.tech_ && player.tech_.featuresVolumeControl === false) {
3157 _this.addClass('vjs-hidden');
3160 _this.on(player, 'loadstart', function () {
3161 // We need to update the button to account for a default muted state.
3164 if (player.tech_.featuresVolumeControl === false) {
3165 this.addClass('vjs-hidden');
3167 this.removeClass('vjs-hidden');
3174 * Builds the default DOM `className`.
3177 * The DOM `className` for this object.
3181 MuteToggle.prototype.buildCSSClass = function buildCSSClass() {
3182 return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this);
3186 * This gets called when an `MuteToggle` is "clicked". See
3187 * {@link ClickableComponent} for more detailed information on what a click can be.
3189 * @param {EventTarget~Event} [event]
3190 * The `keydown`, `tap`, or `click` event that caused this function to be
3198 MuteToggle.prototype.handleClick = function handleClick(event) {
3199 this.player_.muted(this.player_.muted() ? false : true);
3203 * Update the state of volume.
3205 * @param {EventTarget~Event} [event]
3206 * The {@link Player#loadstart} event if this function was called through an
3209 * @listens Player#loadstart
3213 MuteToggle.prototype.update = function update(event) {
3214 var vol = this.player_.volume();
3217 if (vol === 0 || this.player_.muted()) {
3219 } else if (vol < 0.33) {
3221 } else if (vol < 0.67) {
3225 // Don't rewrite the button text if the actual text doesn't change.
3226 // This causes unnecessary and confusing information for screen reader users.
3227 // This check is needed because this function gets called every time the volume level is changed.
3228 var toMute = this.player_.muted() ? 'Unmute' : 'Mute';
3230 if (this.controlText() !== toMute) {
3231 this.controlText(toMute);
3234 // TODO improve muted icon classes
3235 for (var i = 0; i < 4; i++) {
3236 Dom.removeElClass(this.el_, 'vjs-vol-' + i);
3238 Dom.addElClass(this.el_, 'vjs-vol-' + level);
3242 }(_button2['default']);
3245 * The text that should display over the `MuteToggle`s controls. Added for localization.
3252 MuteToggle.prototype.controlText_ = 'Mute';
3254 _component2['default'].registerComponent('MuteToggle', MuteToggle);
3255 exports['default'] = MuteToggle;
3257 },{"2":2,"5":5,"81":81}],12:[function(_dereq_,module,exports){
3260 exports.__esModule = true;
3262 var _button = _dereq_(2);
3264 var _button2 = _interopRequireDefault(_button);
3266 var _component = _dereq_(5);
3268 var _component2 = _interopRequireDefault(_component);
3270 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3272 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3274 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3276 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
3277 * @file play-toggle.js
3282 * Button to toggle between play and pause.
3286 var PlayToggle = function (_Button) {
3287 _inherits(PlayToggle, _Button);
3290 * Creates an instance of this class.
3292 * @param {Player} player
3293 * The `Player` that this class should be attached to.
3295 * @param {Object} [options]
3296 * The key/value store of player options.
3298 function PlayToggle(player, options) {
3299 _classCallCheck(this, PlayToggle);
3301 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
3303 _this.on(player, 'play', _this.handlePlay);
3304 _this.on(player, 'pause', _this.handlePause);
3309 * Builds the default DOM `className`.
3312 * The DOM `className` for this object.
3316 PlayToggle.prototype.buildCSSClass = function buildCSSClass() {
3317 return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this);
3321 * This gets called when an `PlayToggle` is "clicked". See
3322 * {@link ClickableComponent} for more detailed information on what a click can be.
3324 * @param {EventTarget~Event} [event]
3325 * The `keydown`, `tap`, or `click` event that caused this function to be
3333 PlayToggle.prototype.handleClick = function handleClick(event) {
3334 if (this.player_.paused()) {
3335 this.player_.play();
3337 this.player_.pause();
3342 * Add the vjs-playing class to the element so it can change appearance.
3344 * @param {EventTarget~Event} [event]
3345 * The event that caused this function to run.
3347 * @listens Player#play
3351 PlayToggle.prototype.handlePlay = function handlePlay(event) {
3352 this.removeClass('vjs-paused');
3353 this.addClass('vjs-playing');
3354 // change the button text to "Pause"
3355 this.controlText('Pause');
3359 * Add the vjs-paused class to the element so it can change appearance.
3361 * @param {EventTarget~Event} [event]
3362 * The event that caused this function to run.
3364 * @listens Player#pause
3368 PlayToggle.prototype.handlePause = function handlePause(event) {
3369 this.removeClass('vjs-playing');
3370 this.addClass('vjs-paused');
3371 // change the button text to "Play"
3372 this.controlText('Play');
3376 }(_button2['default']);
3379 * The text that should display over the `PlayToggle`s controls. Added for localization.
3386 PlayToggle.prototype.controlText_ = 'Play';
3388 _component2['default'].registerComponent('PlayToggle', PlayToggle);
3389 exports['default'] = PlayToggle;
3391 },{"2":2,"5":5}],13:[function(_dereq_,module,exports){
3394 exports.__esModule = true;
3396 var _menuButton = _dereq_(47);
3398 var _menuButton2 = _interopRequireDefault(_menuButton);
3400 var _menu = _dereq_(49);
3402 var _menu2 = _interopRequireDefault(_menu);
3404 var _playbackRateMenuItem = _dereq_(14);
3406 var _playbackRateMenuItem2 = _interopRequireDefault(_playbackRateMenuItem);
3408 var _component = _dereq_(5);
3410 var _component2 = _interopRequireDefault(_component);
3412 var _dom = _dereq_(81);
3414 var Dom = _interopRequireWildcard(_dom);
3416 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
3418 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3420 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3422 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3424 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
3425 * @file playback-rate-menu-button.js
3430 * The component for controlling the playback rate.
3432 * @extends MenuButton
3434 var PlaybackRateMenuButton = function (_MenuButton) {
3435 _inherits(PlaybackRateMenuButton, _MenuButton);
3438 * Creates an instance of this class.
3440 * @param {Player} player
3441 * The `Player` that this class should be attached to.
3443 * @param {Object} [options]
3444 * The key/value store of player options.
3446 function PlaybackRateMenuButton(player, options) {
3447 _classCallCheck(this, PlaybackRateMenuButton);
3449 var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options));
3451 _this.updateVisibility();
3452 _this.updateLabel();
3454 _this.on(player, 'loadstart', _this.updateVisibility);
3455 _this.on(player, 'ratechange', _this.updateLabel);
3460 * Create the `Component`'s DOM element
3463 * The element that was created.
3467 PlaybackRateMenuButton.prototype.createEl = function createEl() {
3468 var el = _MenuButton.prototype.createEl.call(this);
3470 this.labelEl_ = Dom.createEl('div', {
3471 className: 'vjs-playback-rate-value',
3475 el.appendChild(this.labelEl_);
3481 * Builds the default DOM `className`.
3484 * The DOM `className` for this object.
3488 PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() {
3489 return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this);
3493 * Create the playback rate menu
3496 * Menu object populated with {@link PlaybackRateMenuItem}s
3500 PlaybackRateMenuButton.prototype.createMenu = function createMenu() {
3501 var menu = new _menu2['default'](this.player());
3502 var rates = this.playbackRates();
3505 for (var i = rates.length - 1; i >= 0; i--) {
3506 menu.addChild(new _playbackRateMenuItem2['default'](this.player(), { rate: rates[i] + 'x' }));
3514 * Updates ARIA accessibility attributes
3518 PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() {
3519 // Current playback rate
3520 this.el().setAttribute('aria-valuenow', this.player().playbackRate());
3524 * This gets called when an `PlaybackRateMenuButton` is "clicked". See
3525 * {@link ClickableComponent} for more detailed information on what a click can be.
3527 * @param {EventTarget~Event} [event]
3528 * The `keydown`, `tap`, or `click` event that caused this function to be
3536 PlaybackRateMenuButton.prototype.handleClick = function handleClick(event) {
3537 // select next rate option
3538 var currentRate = this.player().playbackRate();
3539 var rates = this.playbackRates();
3541 // this will select first one if the last one currently selected
3542 var newRate = rates[0];
3544 for (var i = 0; i < rates.length; i++) {
3545 if (rates[i] > currentRate) {
3550 this.player().playbackRate(newRate);
3554 * Get possible playback rates
3557 * All possible playback rates
3561 PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() {
3562 return this.options_.playbackRates || this.options_.playerOptions && this.options_.playerOptions.playbackRates;
3566 * Get whether playback rates is supported by the tech
3567 * and an array of playback rates exists
3570 * Whether changing playback rate is supported
3574 PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() {
3575 return this.player().tech_ && this.player().tech_.featuresPlaybackRate && this.playbackRates() && this.playbackRates().length > 0;
3579 * Hide playback rate controls when they're no playback rate options to select
3581 * @param {EventTarget~Event} [event]
3582 * The event that caused this function to run.
3584 * @listens Player#loadstart
3588 PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility(event) {
3589 if (this.playbackRateSupported()) {
3590 this.removeClass('vjs-hidden');
3592 this.addClass('vjs-hidden');
3597 * Update button label when rate changed
3599 * @param {EventTarget~Event} [event]
3600 * The event that caused this function to run.
3602 * @listens Player#ratechange
3606 PlaybackRateMenuButton.prototype.updateLabel = function updateLabel(event) {
3607 if (this.playbackRateSupported()) {
3608 this.labelEl_.innerHTML = this.player().playbackRate() + 'x';
3612 return PlaybackRateMenuButton;
3613 }(_menuButton2['default']);
3616 * The text that should display over the `FullscreenToggle`s controls. Added for localization.
3623 PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate';
3625 _component2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton);
3626 exports['default'] = PlaybackRateMenuButton;
3628 },{"14":14,"47":47,"49":49,"5":5,"81":81}],14:[function(_dereq_,module,exports){
3631 exports.__esModule = true;
3633 var _menuItem = _dereq_(48);
3635 var _menuItem2 = _interopRequireDefault(_menuItem);
3637 var _component = _dereq_(5);
3639 var _component2 = _interopRequireDefault(_component);
3641 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3643 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3645 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3647 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
3648 * @file playback-rate-menu-item.js
3653 * The specific menu item type for selecting a playback rate.
3657 var PlaybackRateMenuItem = function (_MenuItem) {
3658 _inherits(PlaybackRateMenuItem, _MenuItem);
3661 * Creates an instance of this class.
3663 * @param {Player} player
3664 * The `Player` that this class should be attached to.
3666 * @param {Object} [options]
3667 * The key/value store of player options.
3669 function PlaybackRateMenuItem(player, options) {
3670 _classCallCheck(this, PlaybackRateMenuItem);
3672 var label = options.rate;
3673 var rate = parseFloat(label, 10);
3675 // Modify options for parent MenuItem class's init.
3676 options.label = label;
3677 options.selected = rate === 1;
3678 options.selectable = true;
3680 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
3682 _this.label = label;
3685 _this.on(player, 'ratechange', _this.update);
3690 * This gets called when an `PlaybackRateMenuItem` is "clicked". See
3691 * {@link ClickableComponent} for more detailed information on what a click can be.
3693 * @param {EventTarget~Event} [event]
3694 * The `keydown`, `tap`, or `click` event that caused this function to be
3702 PlaybackRateMenuItem.prototype.handleClick = function handleClick(event) {
3703 _MenuItem.prototype.handleClick.call(this);
3704 this.player().playbackRate(this.rate);
3708 * Update the PlaybackRateMenuItem when the playbackrate changes.
3710 * @param {EventTarget~Event} [event]
3711 * The `ratechange` event that caused this function to run.
3713 * @listens Player#ratechange
3717 PlaybackRateMenuItem.prototype.update = function update(event) {
3718 this.selected(this.player().playbackRate() === this.rate);
3721 return PlaybackRateMenuItem;
3722 }(_menuItem2['default']);
3725 * The text that should display over the `PlaybackRateMenuItem`s controls. Added for localization.
3732 PlaybackRateMenuItem.prototype.contentElType = 'button';
3734 _component2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem);
3735 exports['default'] = PlaybackRateMenuItem;
3737 },{"48":48,"5":5}],15:[function(_dereq_,module,exports){
3740 exports.__esModule = true;
3742 var _component = _dereq_(5);
3744 var _component2 = _interopRequireDefault(_component);
3746 var _dom = _dereq_(81);
3748 var Dom = _interopRequireWildcard(_dom);
3750 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
3752 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3754 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3756 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3758 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
3759 * @file load-progress-bar.js
3764 * Shows loading progress
3766 * @extends Component
3768 var LoadProgressBar = function (_Component) {
3769 _inherits(LoadProgressBar, _Component);
3772 * Creates an instance of this class.
3774 * @param {Player} player
3775 * The `Player` that this class should be attached to.
3777 * @param {Object} [options]
3778 * The key/value store of player options.
3780 function LoadProgressBar(player, options) {
3781 _classCallCheck(this, LoadProgressBar);
3783 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
3785 _this.partEls_ = [];
3786 _this.on(player, 'progress', _this.update);
3791 * Create the `Component`'s DOM element
3794 * The element that was created.
3798 LoadProgressBar.prototype.createEl = function createEl() {
3799 return _Component.prototype.createEl.call(this, 'div', {
3800 className: 'vjs-load-progress',
3801 innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>'
3806 * Update progress bar
3808 * @param {EventTarget~Event} [event]
3809 * The `progress` event that caused this function to run.
3811 * @listens Player#progress
3815 LoadProgressBar.prototype.update = function update(event) {
3816 var buffered = this.player_.buffered();
3817 var duration = this.player_.duration();
3818 var bufferedEnd = this.player_.bufferedEnd();
3819 var children = this.partEls_;
3821 // get the percent width of a time compared to the total end
3822 var percentify = function percentify(time, end) {
3824 var percent = time / end || 0;
3826 return (percent >= 1 ? 1 : percent) * 100 + '%';
3829 // update the width of the progress bar
3830 this.el_.style.width = percentify(bufferedEnd, duration);
3832 // add child elements to represent the individual buffered time ranges
3833 for (var i = 0; i < buffered.length; i++) {
3834 var start = buffered.start(i);
3835 var end = buffered.end(i);
3836 var part = children[i];
3839 part = this.el_.appendChild(Dom.createEl());
3843 // set the percent based on the width of the progress bar (bufferedEnd)
3844 part.style.left = percentify(start, bufferedEnd);
3845 part.style.width = percentify(end - start, bufferedEnd);
3848 // remove unused buffered range elements
3849 for (var _i = children.length; _i > buffered.length; _i--) {
3850 this.el_.removeChild(children[_i - 1]);
3852 children.length = buffered.length;
3855 return LoadProgressBar;
3856 }(_component2['default']);
3858 _component2['default'].registerComponent('LoadProgressBar', LoadProgressBar);
3859 exports['default'] = LoadProgressBar;
3861 },{"5":5,"81":81}],16:[function(_dereq_,module,exports){
3864 exports.__esModule = true;
3866 var _component = _dereq_(5);
3868 var _component2 = _interopRequireDefault(_component);
3870 var _dom = _dereq_(81);
3872 var Dom = _interopRequireWildcard(_dom);
3874 var _fn = _dereq_(83);
3876 var Fn = _interopRequireWildcard(_fn);
3878 var _formatTime = _dereq_(84);
3880 var _formatTime2 = _interopRequireDefault(_formatTime);
3882 var _computedStyle = _dereq_(80);
3884 var _computedStyle2 = _interopRequireDefault(_computedStyle);
3886 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
3888 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3890 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3892 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3894 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
3895 * @file mouse-time-display.js
3900 * The Mouse Time Display component shows the time you will seek to
3901 * when hovering over the progress bar
3903 * @extends Component
3905 var MouseTimeDisplay = function (_Component) {
3906 _inherits(MouseTimeDisplay, _Component);
3909 * Creates an instance of this class.
3911 * @param {Player} player
3912 * The `Player` that this class should be attached to.
3914 * @param {Object} [options]
3915 * The key/value store of player options.
3917 function MouseTimeDisplay(player, options) {
3918 _classCallCheck(this, MouseTimeDisplay);
3920 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
3922 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
3923 _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
3926 if (_this.keepTooltipsInside) {
3927 _this.tooltip = Dom.createEl('div', { className: 'vjs-time-tooltip' });
3928 _this.el().appendChild(_this.tooltip);
3929 _this.addClass('vjs-keep-tooltips-inside');
3934 player.on('ready', function () {
3935 _this.on(player.controlBar.progressControl.el(), 'mousemove', Fn.throttle(Fn.bind(_this, _this.handleMouseMove), 25));
3941 * Create the `Component`'s DOM element
3944 * The element that was created.
3948 MouseTimeDisplay.prototype.createEl = function createEl() {
3949 return _Component.prototype.createEl.call(this, 'div', {
3950 className: 'vjs-mouse-display'
3955 * Handle the mouse move event on the `MouseTimeDisplay`.
3957 * @param {EventTarget~Event} event
3958 * The `mousemove` event that caused this to event to run.
3964 MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) {
3965 var duration = this.player_.duration();
3966 var newTime = this.calculateDistance(event) * duration;
3967 var position = event.pageX - Dom.findElPosition(this.el().parentNode).left;
3969 this.update(newTime, position);
3973 * Update the time and posistion of the `MouseTimeDisplay`.
3975 * @param {number} newTime
3976 * Time to change the `MouseTimeDisplay` to.
3978 * @param {nubmer} position
3979 * Postion from the left of the in pixels.
3983 MouseTimeDisplay.prototype.update = function update(newTime, position) {
3984 var time = (0, _formatTime2['default'])(newTime, this.player_.duration());
3986 this.el().style.left = position + 'px';
3987 this.el().setAttribute('data-current-time', time);
3989 if (this.keepTooltipsInside) {
3990 var clampedPosition = this.clampPosition_(position);
3991 var difference = position - clampedPosition + 1;
3992 var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width'));
3993 var tooltipWidthHalf = tooltipWidth / 2;
3995 this.tooltip.innerHTML = time;
3996 this.tooltip.style.right = '-' + (tooltipWidthHalf - difference) + 'px';
4001 * Get the mouse pointers x coordinate in pixels.
4003 * @param {EventTarget~Event} [event]
4004 * The `mousemove` event that was passed to this function by
4005 * {@link MouseTimeDisplay#handleMouseMove}
4008 * THe x position in pixels of the mouse pointer.
4012 MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) {
4013 return Dom.getPointerPosition(this.el().parentNode, event).x;
4017 * This takes in a horizontal position for the bar and returns a clamped position.
4018 * Clamped position means that it will keep the position greater than half the width
4019 * of the tooltip and smaller than the player width minus half the width o the tooltip.
4020 * It will only clamp the position if `keepTooltipsInside` option is set.
4022 * @param {number} position
4023 * The position the bar wants to be
4026 * The (potentially) new clamped position.
4032 MouseTimeDisplay.prototype.clampPosition_ = function clampPosition_(position) {
4033 if (!this.keepTooltipsInside) {
4037 var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width'));
4038 var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width'));
4039 var tooltipWidthHalf = tooltipWidth / 2;
4040 var actualPosition = position;
4042 if (position < tooltipWidthHalf) {
4043 actualPosition = Math.ceil(tooltipWidthHalf);
4044 } else if (position > playerWidth - tooltipWidthHalf) {
4045 actualPosition = Math.floor(playerWidth - tooltipWidthHalf);
4048 return actualPosition;
4051 return MouseTimeDisplay;
4052 }(_component2['default']);
4054 _component2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay);
4055 exports['default'] = MouseTimeDisplay;
4057 },{"5":5,"80":80,"81":81,"83":83,"84":84}],17:[function(_dereq_,module,exports){
4060 exports.__esModule = true;
4062 var _component = _dereq_(5);
4064 var _component2 = _interopRequireDefault(_component);
4066 var _fn = _dereq_(83);
4068 var Fn = _interopRequireWildcard(_fn);
4070 var _formatTime = _dereq_(84);
4072 var _formatTime2 = _interopRequireDefault(_formatTime);
4074 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
4076 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4078 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4080 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4082 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4083 * @file play-progress-bar.js
4088 * Shows play progress
4090 * @extends Component
4092 var PlayProgressBar = function (_Component) {
4093 _inherits(PlayProgressBar, _Component);
4096 * Creates an instance of this class.
4098 * @param {Player} player
4099 * The `Player` that this class should be attached to.
4101 * @param {Object} [options]
4102 * The key/value store of player options.
4104 function PlayProgressBar(player, options) {
4105 _classCallCheck(this, PlayProgressBar);
4107 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
4109 _this.updateDataAttr();
4110 _this.on(player, 'timeupdate', _this.updateDataAttr);
4111 player.ready(Fn.bind(_this, _this.updateDataAttr));
4113 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
4114 _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
4117 if (_this.keepTooltipsInside) {
4118 _this.addClass('vjs-keep-tooltips-inside');
4124 * Create the `Component`'s DOM element
4127 * The element that was created.
4131 PlayProgressBar.prototype.createEl = function createEl() {
4132 return _Component.prototype.createEl.call(this, 'div', {
4133 className: 'vjs-play-progress vjs-slider-bar',
4134 innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
4139 * Update the data-current-time attribute on the `PlayProgressBar`.
4141 * @param {EventTarget~Event} [event]
4142 * The `timeupdate` event that caused this to run.
4144 * @listens Player#timeupdate
4148 PlayProgressBar.prototype.updateDataAttr = function updateDataAttr(event) {
4149 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
4151 this.el_.setAttribute('data-current-time', (0, _formatTime2['default'])(time, this.player_.duration()));
4154 return PlayProgressBar;
4155 }(_component2['default']);
4157 _component2['default'].registerComponent('PlayProgressBar', PlayProgressBar);
4158 exports['default'] = PlayProgressBar;
4160 },{"5":5,"83":83,"84":84}],18:[function(_dereq_,module,exports){
4163 exports.__esModule = true;
4165 var _component = _dereq_(5);
4167 var _component2 = _interopRequireDefault(_component);
4173 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4175 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4177 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4179 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4180 * @file progress-control.js
4185 * The Progress Control component contains the seek bar, load progress,
4186 * and play progress.
4188 * @extends Component
4190 var ProgressControl = function (_Component) {
4191 _inherits(ProgressControl, _Component);
4193 function ProgressControl() {
4194 _classCallCheck(this, ProgressControl);
4196 return _possibleConstructorReturn(this, _Component.apply(this, arguments));
4200 * Create the `Component`'s DOM element
4203 * The element that was created.
4205 ProgressControl.prototype.createEl = function createEl() {
4206 return _Component.prototype.createEl.call(this, 'div', {
4207 className: 'vjs-progress-control vjs-control'
4211 return ProgressControl;
4212 }(_component2['default']);
4215 * Default options for `ProgressControl`
4222 ProgressControl.prototype.options_ = {
4223 children: ['seekBar']
4226 _component2['default'].registerComponent('ProgressControl', ProgressControl);
4227 exports['default'] = ProgressControl;
4229 },{"16":16,"19":19,"5":5}],19:[function(_dereq_,module,exports){
4232 exports.__esModule = true;
4234 var _slider = _dereq_(57);
4236 var _slider2 = _interopRequireDefault(_slider);
4238 var _component = _dereq_(5);
4240 var _component2 = _interopRequireDefault(_component);
4242 var _fn = _dereq_(83);
4244 var Fn = _interopRequireWildcard(_fn);
4246 var _formatTime = _dereq_(84);
4248 var _formatTime2 = _interopRequireDefault(_formatTime);
4250 var _computedStyle = _dereq_(80);
4252 var _computedStyle2 = _interopRequireDefault(_computedStyle);
4260 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
4262 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4264 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4266 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4268 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4274 * Seek Bar and holder for the progress bars
4278 var SeekBar = function (_Slider) {
4279 _inherits(SeekBar, _Slider);
4282 * Creates an instance of this class.
4284 * @param {Player} player
4285 * The `Player` that this class should be attached to.
4287 * @param {Object} [options]
4288 * The key/value store of player options.
4290 function SeekBar(player, options) {
4291 _classCallCheck(this, SeekBar);
4293 var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options));
4295 _this.on(player, 'timeupdate', _this.updateProgress);
4296 _this.on(player, 'ended', _this.updateProgress);
4297 player.ready(Fn.bind(_this, _this.updateProgress));
4299 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
4300 _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
4303 if (_this.keepTooltipsInside) {
4304 _this.tooltipProgressBar = _this.addChild('TooltipProgressBar');
4310 * Create the `Component`'s DOM element
4313 * The element that was created.
4317 SeekBar.prototype.createEl = function createEl() {
4318 return _Slider.prototype.createEl.call(this, 'div', {
4319 className: 'vjs-progress-holder'
4321 'aria-label': 'progress bar'
4326 * Update the seek bars tooltip and width.
4328 * @param {EventTarget~Event} [event]
4329 * The `timeupdate` or `ended` event that caused this to run.
4331 * @listens Player#timeupdate
4332 * @listens Player#ended
4336 SeekBar.prototype.updateProgress = function updateProgress(event) {
4337 this.updateAriaAttributes(this.el_);
4339 if (this.keepTooltipsInside) {
4340 this.updateAriaAttributes(this.tooltipProgressBar.el_);
4341 this.tooltipProgressBar.el_.style.width = this.bar.el_.style.width;
4343 var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width'));
4344 var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltipProgressBar.tooltip, 'width'));
4345 var tooltipStyle = this.tooltipProgressBar.el().style;
4347 tooltipStyle.maxWidth = Math.floor(playerWidth - tooltipWidth / 2) + 'px';
4348 tooltipStyle.minWidth = Math.ceil(tooltipWidth / 2) + 'px';
4349 tooltipStyle.right = '-' + tooltipWidth / 2 + 'px';
4354 * Update ARIA accessibility attributes
4356 * @param {Element} el
4357 * The element to update with aria accessibility attributes.
4361 SeekBar.prototype.updateAriaAttributes = function updateAriaAttributes(el) {
4362 // Allows for smooth scrubbing, when player can't keep up.
4363 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
4365 // machine readable value of progress bar (percentage complete)
4366 el.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2));
4367 // human readable value of progress bar (time complete)
4368 el.setAttribute('aria-valuetext', (0, _formatTime2['default'])(time, this.player_.duration()));
4372 * Get percentage of video played
4375 * The percentage played
4379 SeekBar.prototype.getPercent = function getPercent() {
4380 var percent = this.player_.currentTime() / this.player_.duration();
4382 return percent >= 1 ? 1 : percent;
4386 * Handle mouse down on seek bar
4388 * @param {EventTarget~Event} event
4389 * The `mousedown` event that caused this to run.
4391 * @listens mousedown
4395 SeekBar.prototype.handleMouseDown = function handleMouseDown(event) {
4396 this.player_.scrubbing(true);
4398 this.videoWasPlaying = !this.player_.paused();
4399 this.player_.pause();
4401 _Slider.prototype.handleMouseDown.call(this, event);
4405 * Handle mouse move on seek bar
4407 * @param {EventTarget~Event} event
4408 * The `mousemove` event that caused this to run.
4410 * @listens mousemove
4414 SeekBar.prototype.handleMouseMove = function handleMouseMove(event) {
4415 var newTime = this.calculateDistance(event) * this.player_.duration();
4417 // Don't let video end while scrubbing.
4418 if (newTime === this.player_.duration()) {
4419 newTime = newTime - 0.1;
4422 // Set new time (tell player to seek to new time)
4423 this.player_.currentTime(newTime);
4427 * Handle mouse up on seek bar
4429 * @param {EventTarget~Event} event
4430 * The `mouseup` event that caused this to run.
4436 SeekBar.prototype.handleMouseUp = function handleMouseUp(event) {
4437 _Slider.prototype.handleMouseUp.call(this, event);
4439 this.player_.scrubbing(false);
4440 if (this.videoWasPlaying) {
4441 this.player_.play();
4446 * Move more quickly fast forward for keyboard-only users
4450 SeekBar.prototype.stepForward = function stepForward() {
4451 // more quickly fast forward for keyboard-only users
4452 this.player_.currentTime(this.player_.currentTime() + 5);
4456 * Move more quickly rewind for keyboard-only users
4460 SeekBar.prototype.stepBack = function stepBack() {
4461 // more quickly rewind for keyboard-only users
4462 this.player_.currentTime(this.player_.currentTime() - 5);
4466 }(_slider2['default']);
4469 * Default options for the `SeekBar`
4476 SeekBar.prototype.options_ = {
4477 children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'],
4478 barName: 'playProgressBar'
4482 * Call the update event for this Slider when this event happens on the player.
4486 SeekBar.prototype.playerEvent = 'timeupdate';
4488 _component2['default'].registerComponent('SeekBar', SeekBar);
4489 exports['default'] = SeekBar;
4491 },{"15":15,"17":17,"20":20,"5":5,"57":57,"80":80,"83":83,"84":84}],20:[function(_dereq_,module,exports){
4494 exports.__esModule = true;
4496 var _component = _dereq_(5);
4498 var _component2 = _interopRequireDefault(_component);
4500 var _fn = _dereq_(83);
4502 var Fn = _interopRequireWildcard(_fn);
4504 var _formatTime = _dereq_(84);
4506 var _formatTime2 = _interopRequireDefault(_formatTime);
4508 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
4510 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4512 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4514 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4516 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4517 * @file play-progress-bar.js
4522 * Shows play progress
4524 * @extends Component
4526 var TooltipProgressBar = function (_Component) {
4527 _inherits(TooltipProgressBar, _Component);
4530 * Creates an instance of this class.
4532 * @param {Player} player
4533 * The `Player` that this class should be attached to.
4535 * @param {Object} [options]
4536 * The key/value store of player options.
4538 function TooltipProgressBar(player, options) {
4539 _classCallCheck(this, TooltipProgressBar);
4541 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
4543 _this.updateDataAttr();
4544 _this.on(player, 'timeupdate', _this.updateDataAttr);
4545 player.ready(Fn.bind(_this, _this.updateDataAttr));
4550 * Create the `Component`'s DOM element
4553 * The element that was created.
4557 TooltipProgressBar.prototype.createEl = function createEl() {
4558 var el = _Component.prototype.createEl.call(this, 'div', {
4559 className: 'vjs-tooltip-progress-bar vjs-slider-bar',
4560 innerHTML: '<div class="vjs-time-tooltip"></div>\n <span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
4563 this.tooltip = el.querySelector('.vjs-time-tooltip');
4569 * Updatet the data-current-time attribute for TooltipProgressBar
4571 * @param {EventTarget~Event} [event]
4572 * The `timeupdate` event that caused this function to run.
4574 * @listens Player#timeupdate
4578 TooltipProgressBar.prototype.updateDataAttr = function updateDataAttr(event) {
4579 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
4580 var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration());
4582 this.el_.setAttribute('data-current-time', formattedTime);
4583 this.tooltip.innerHTML = formattedTime;
4586 return TooltipProgressBar;
4587 }(_component2['default']);
4589 _component2['default'].registerComponent('TooltipProgressBar', TooltipProgressBar);
4590 exports['default'] = TooltipProgressBar;
4592 },{"5":5,"83":83,"84":84}],21:[function(_dereq_,module,exports){
4595 exports.__esModule = true;
4597 var _spacer = _dereq_(22);
4599 var _spacer2 = _interopRequireDefault(_spacer);
4601 var _component = _dereq_(5);
4603 var _component2 = _interopRequireDefault(_component);
4605 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4607 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4609 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4611 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4612 * @file custom-control-spacer.js
4617 * Spacer specifically meant to be used as an insertion point for new plugins, etc.
4621 var CustomControlSpacer = function (_Spacer) {
4622 _inherits(CustomControlSpacer, _Spacer);
4624 function CustomControlSpacer() {
4625 _classCallCheck(this, CustomControlSpacer);
4627 return _possibleConstructorReturn(this, _Spacer.apply(this, arguments));
4631 * Builds the default DOM `className`.
4634 * The DOM `className` for this object.
4636 CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() {
4637 return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this);
4641 * Create the `Component`'s DOM element
4644 * The element that was created.
4648 CustomControlSpacer.prototype.createEl = function createEl() {
4649 var el = _Spacer.prototype.createEl.call(this, {
4650 className: this.buildCSSClass()
4653 // No-flex/table-cell mode requires there be some content
4654 // in the cell to fill the remaining space of the table.
4655 el.innerHTML = ' ';
4659 return CustomControlSpacer;
4660 }(_spacer2['default']);
4662 _component2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer);
4663 exports['default'] = CustomControlSpacer;
4665 },{"22":22,"5":5}],22:[function(_dereq_,module,exports){
4668 exports.__esModule = true;
4670 var _component = _dereq_(5);
4672 var _component2 = _interopRequireDefault(_component);
4674 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4676 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4678 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4680 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4686 * Just an empty spacer element that can be used as an append point for plugins, etc.
4687 * Also can be used to create space between elements when necessary.
4689 * @extends Component
4691 var Spacer = function (_Component) {
4692 _inherits(Spacer, _Component);
4695 _classCallCheck(this, Spacer);
4697 return _possibleConstructorReturn(this, _Component.apply(this, arguments));
4701 * Builds the default DOM `className`.
4704 * The DOM `className` for this object.
4706 Spacer.prototype.buildCSSClass = function buildCSSClass() {
4707 return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this);
4711 * Create the `Component`'s DOM element
4714 * The element that was created.
4718 Spacer.prototype.createEl = function createEl() {
4719 return _Component.prototype.createEl.call(this, 'div', {
4720 className: this.buildCSSClass()
4725 }(_component2['default']);
4727 _component2['default'].registerComponent('Spacer', Spacer);
4729 exports['default'] = Spacer;
4731 },{"5":5}],23:[function(_dereq_,module,exports){
4734 exports.__esModule = true;
4736 var _textTrackMenuItem = _dereq_(31);
4738 var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
4740 var _component = _dereq_(5);
4742 var _component2 = _interopRequireDefault(_component);
4744 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4746 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4748 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4750 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4751 * @file caption-settings-menu-item.js
4756 * The menu item for caption track settings menu
4758 * @extends TextTrackMenuItem
4760 var CaptionSettingsMenuItem = function (_TextTrackMenuItem) {
4761 _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem);
4764 * Creates an instance of this class.
4766 * @param {Player} player
4767 * The `Player` that this class should be attached to.
4769 * @param {Object} [options]
4770 * The key/value store of player options.
4772 function CaptionSettingsMenuItem(player, options) {
4773 _classCallCheck(this, CaptionSettingsMenuItem);
4778 label: options.kind + ' settings',
4784 // CaptionSettingsMenuItem has no concept of 'selected'
4785 options.selectable = false;
4787 var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
4789 _this.addClass('vjs-texttrack-settings');
4790 _this.controlText(', opens ' + options.kind + ' settings dialog');
4795 * This gets called when an `CaptionSettingsMenuItem` is "clicked". See
4796 * {@link ClickableComponent} for more detailed information on what a click can be.
4798 * @param {EventTarget~Event} [event]
4799 * The `keydown`, `tap`, or `click` event that caused this function to be
4807 CaptionSettingsMenuItem.prototype.handleClick = function handleClick(event) {
4808 this.player().getChild('textTrackSettings').show();
4809 this.player().getChild('textTrackSettings').el_.focus();
4812 return CaptionSettingsMenuItem;
4813 }(_textTrackMenuItem2['default']);
4815 _component2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem);
4816 exports['default'] = CaptionSettingsMenuItem;
4818 },{"31":31,"5":5}],24:[function(_dereq_,module,exports){
4821 exports.__esModule = true;
4823 var _textTrackButton = _dereq_(30);
4825 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
4827 var _component = _dereq_(5);
4829 var _component2 = _interopRequireDefault(_component);
4831 var _captionSettingsMenuItem = _dereq_(23);
4833 var _captionSettingsMenuItem2 = _interopRequireDefault(_captionSettingsMenuItem);
4835 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4837 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4839 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4841 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4842 * @file captions-button.js
4847 * The button component for toggling and selecting captions
4849 * @extends TextTrackButton
4851 var CaptionsButton = function (_TextTrackButton) {
4852 _inherits(CaptionsButton, _TextTrackButton);
4855 * Creates an instance of this class.
4857 * @param {Player} player
4858 * The `Player` that this class should be attached to.
4860 * @param {Object} [options]
4861 * The key/value store of player options.
4863 * @param {Component~ReadyCallback} [ready]
4864 * The function to call when this component is ready.
4866 function CaptionsButton(player, options, ready) {
4867 _classCallCheck(this, CaptionsButton);
4869 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
4871 _this.el_.setAttribute('aria-label', 'Captions Menu');
4876 * Builds the default DOM `className`.
4879 * The DOM `className` for this object.
4883 CaptionsButton.prototype.buildCSSClass = function buildCSSClass() {
4884 return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
4888 * Create caption menu items
4890 * @return {CaptionSettingsMenuItem[]}
4891 * The array of current menu items.
4895 CaptionsButton.prototype.createItems = function createItems() {
4898 if (!(this.player().tech_ && this.player().tech_.featuresNativeTextTracks)) {
4899 items.push(new _captionSettingsMenuItem2['default'](this.player_, { kind: this.kind_ }));
4901 this.hideThreshold_ += 1;
4904 return _TextTrackButton.prototype.createItems.call(this, items);
4907 return CaptionsButton;
4908 }(_textTrackButton2['default']);
4911 * `kind` of TextTrack to look for to associate it with this menu.
4918 CaptionsButton.prototype.kind_ = 'captions';
4921 * The text that should display over the `CaptionsButton`s controls. Added for localization.
4926 CaptionsButton.prototype.controlText_ = 'Captions';
4928 _component2['default'].registerComponent('CaptionsButton', CaptionsButton);
4929 exports['default'] = CaptionsButton;
4931 },{"23":23,"30":30,"5":5}],25:[function(_dereq_,module,exports){
4934 exports.__esModule = true;
4936 var _textTrackButton = _dereq_(30);
4938 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
4940 var _component = _dereq_(5);
4942 var _component2 = _interopRequireDefault(_component);
4944 var _chaptersTrackMenuItem = _dereq_(26);
4946 var _chaptersTrackMenuItem2 = _interopRequireDefault(_chaptersTrackMenuItem);
4948 var _toTitleCase = _dereq_(91);
4950 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
4952 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4954 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4956 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
4958 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
4959 * @file chapters-button.js
4964 * The button component for toggling and selecting chapters
4965 * Chapters act much differently than other text tracks
4966 * Cues are navigation vs. other tracks of alternative languages
4968 * @extends TextTrackButton
4970 var ChaptersButton = function (_TextTrackButton) {
4971 _inherits(ChaptersButton, _TextTrackButton);
4974 * Creates an instance of this class.
4976 * @param {Player} player
4977 * The `Player` that this class should be attached to.
4979 * @param {Object} [options]
4980 * The key/value store of player options.
4982 * @param {Component~ReadyCallback} [ready]
4983 * The function to call when this function is ready.
4985 function ChaptersButton(player, options, ready) {
4986 _classCallCheck(this, ChaptersButton);
4988 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
4990 _this.el_.setAttribute('aria-label', 'Chapters Menu');
4995 * Builds the default DOM `className`.
4998 * The DOM `className` for this object.
5002 ChaptersButton.prototype.buildCSSClass = function buildCSSClass() {
5003 return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
5007 * Update the menu based on the current state of its items.
5009 * @param {EventTarget~Event} [event]
5010 * An event that triggered this function to run.
5012 * @listens TextTrackList#addtrack
5013 * @listens TextTrackList#removetrack
5014 * @listens TextTrackList#change
5018 ChaptersButton.prototype.update = function update(event) {
5019 if (!this.track_ || event && (event.type === 'addtrack' || event.type === 'removetrack')) {
5020 this.setTrack(this.findChaptersTrack());
5022 _TextTrackButton.prototype.update.call(this);
5026 * Set the currently selected track for the chapters button.
5028 * @param {TextTrack} track
5029 * The new track to select. Nothing will change if this is the currently selected
5034 ChaptersButton.prototype.setTrack = function setTrack(track) {
5035 if (this.track_ === track) {
5039 if (!this.updateHandler_) {
5040 this.updateHandler_ = this.update.bind(this);
5043 // here this.track_ refers to the old track instance
5045 var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
5047 if (remoteTextTrackEl) {
5048 remoteTextTrackEl.removeEventListener('load', this.updateHandler_);
5054 this.track_ = track;
5056 // here this.track_ refers to the new track instance
5058 this.track_.mode = 'hidden';
5060 var _remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
5062 if (_remoteTextTrackEl) {
5063 _remoteTextTrackEl.addEventListener('load', this.updateHandler_);
5069 * Find the track object that is currently in use by this ChaptersButton
5071 * @return {TextTrack|undefined}
5072 * The current track or undefined if none was found.
5076 ChaptersButton.prototype.findChaptersTrack = function findChaptersTrack() {
5077 var tracks = this.player_.textTracks() || [];
5079 for (var i = tracks.length - 1; i >= 0; i--) {
5080 // We will always choose the last track as our chaptersTrack
5081 var track = tracks[i];
5083 if (track.kind === this.kind_) {
5090 * Get the caption for the ChaptersButton based on the track label. This will also
5091 * use the current tracks localized kind as a fallback if a label does not exist.
5094 * The tracks current label or the localized track kind.
5098 ChaptersButton.prototype.getMenuCaption = function getMenuCaption() {
5099 if (this.track_ && this.track_.label) {
5100 return this.track_.label;
5102 return this.localize((0, _toTitleCase2['default'])(this.kind_));
5106 * Create menu from chapter track
5109 * New menu for the chapter buttons
5113 ChaptersButton.prototype.createMenu = function createMenu() {
5114 this.options_.title = this.getMenuCaption();
5115 return _TextTrackButton.prototype.createMenu.call(this);
5119 * Create a menu item for each text track
5121 * @return {TextTrackMenuItem[]}
5122 * Array of menu items
5126 ChaptersButton.prototype.createItems = function createItems() {
5133 var cues = this.track_.cues;
5139 for (var i = 0, l = cues.length; i < l; i++) {
5141 var mi = new _chaptersTrackMenuItem2['default'](this.player_, { track: this.track_, cue: cue });
5149 return ChaptersButton;
5150 }(_textTrackButton2['default']);
5153 * `kind` of TextTrack to look for to associate it with this menu.
5160 ChaptersButton.prototype.kind_ = 'chapters';
5163 * The text that should display over the `ChaptersButton`s controls. Added for localization.
5168 ChaptersButton.prototype.controlText_ = 'Chapters';
5170 _component2['default'].registerComponent('ChaptersButton', ChaptersButton);
5171 exports['default'] = ChaptersButton;
5173 },{"26":26,"30":30,"5":5,"91":91}],26:[function(_dereq_,module,exports){
5176 exports.__esModule = true;
5178 var _menuItem = _dereq_(48);
5180 var _menuItem2 = _interopRequireDefault(_menuItem);
5182 var _component = _dereq_(5);
5184 var _component2 = _interopRequireDefault(_component);
5186 var _fn = _dereq_(83);
5188 var Fn = _interopRequireWildcard(_fn);
5190 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
5192 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5194 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5196 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5198 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
5199 * @file chapters-track-menu-item.js
5204 * The chapter track menu item
5208 var ChaptersTrackMenuItem = function (_MenuItem) {
5209 _inherits(ChaptersTrackMenuItem, _MenuItem);
5212 * Creates an instance of this class.
5214 * @param {Player} player
5215 * The `Player` that this class should be attached to.
5217 * @param {Object} [options]
5218 * The key/value store of player options.
5220 function ChaptersTrackMenuItem(player, options) {
5221 _classCallCheck(this, ChaptersTrackMenuItem);
5223 var track = options.track;
5224 var cue = options.cue;
5225 var currentTime = player.currentTime();
5227 // Modify options for parent MenuItem class's init.
5228 options.selectable = true;
5229 options.label = cue.text;
5230 options.selected = cue.startTime <= currentTime && currentTime < cue.endTime;
5232 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
5234 _this.track = track;
5236 track.addEventListener('cuechange', Fn.bind(_this, _this.update));
5241 * This gets called when an `ChaptersTrackMenuItem` is "clicked". See
5242 * {@link ClickableComponent} for more detailed information on what a click can be.
5244 * @param {EventTarget~Event} [event]
5245 * The `keydown`, `tap`, or `click` event that caused this function to be
5253 ChaptersTrackMenuItem.prototype.handleClick = function handleClick(event) {
5254 _MenuItem.prototype.handleClick.call(this);
5255 this.player_.currentTime(this.cue.startTime);
5256 this.update(this.cue.startTime);
5260 * Update chapter menu item
5262 * @param {EventTarget~Event} [event]
5263 * The `cuechange` event that caused this function to run.
5265 * @listens TextTrack#cuechange
5269 ChaptersTrackMenuItem.prototype.update = function update(event) {
5271 var currentTime = this.player_.currentTime();
5273 // vjs.log(currentTime, cue.startTime);
5274 this.selected(cue.startTime <= currentTime && currentTime < cue.endTime);
5277 return ChaptersTrackMenuItem;
5278 }(_menuItem2['default']);
5280 _component2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem);
5281 exports['default'] = ChaptersTrackMenuItem;
5283 },{"48":48,"5":5,"83":83}],27:[function(_dereq_,module,exports){
5286 exports.__esModule = true;
5288 var _textTrackButton = _dereq_(30);
5290 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
5292 var _component = _dereq_(5);
5294 var _component2 = _interopRequireDefault(_component);
5296 var _fn = _dereq_(83);
5298 var Fn = _interopRequireWildcard(_fn);
5300 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
5302 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5304 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5306 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5308 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
5309 * @file descriptions-button.js
5314 * The button component for toggling and selecting descriptions
5316 * @extends TextTrackButton
5318 var DescriptionsButton = function (_TextTrackButton) {
5319 _inherits(DescriptionsButton, _TextTrackButton);
5322 * Creates an instance of this class.
5324 * @param {Player} player
5325 * The `Player` that this class should be attached to.
5327 * @param {Object} [options]
5328 * The key/value store of player options.
5330 * @param {Component~ReadyCallback} [ready]
5331 * The function to call when this component is ready.
5333 function DescriptionsButton(player, options, ready) {
5334 _classCallCheck(this, DescriptionsButton);
5336 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
5338 _this.el_.setAttribute('aria-label', 'Descriptions Menu');
5340 var tracks = player.textTracks();
5343 var changeHandler = Fn.bind(_this, _this.handleTracksChange);
5345 tracks.addEventListener('change', changeHandler);
5346 _this.on('dispose', function () {
5347 tracks.removeEventListener('change', changeHandler);
5354 * Handle text track change
5356 * @param {EventTarget~Event} event
5357 * The event that caused this function to run
5359 * @listens TextTrackList#change
5363 DescriptionsButton.prototype.handleTracksChange = function handleTracksChange(event) {
5364 var tracks = this.player().textTracks();
5365 var disabled = false;
5367 // Check whether a track of a different kind is showing
5368 for (var i = 0, l = tracks.length; i < l; i++) {
5369 var track = tracks[i];
5371 if (track.kind !== this.kind_ && track.mode === 'showing') {
5377 // If another track is showing, disable this menu button
5386 * Builds the default DOM `className`.
5389 * The DOM `className` for this object.
5393 DescriptionsButton.prototype.buildCSSClass = function buildCSSClass() {
5394 return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
5397 return DescriptionsButton;
5398 }(_textTrackButton2['default']);
5401 * `kind` of TextTrack to look for to associate it with this menu.
5408 DescriptionsButton.prototype.kind_ = 'descriptions';
5411 * The text that should display over the `DescriptionsButton`s controls. Added for localization.
5416 DescriptionsButton.prototype.controlText_ = 'Descriptions';
5418 _component2['default'].registerComponent('DescriptionsButton', DescriptionsButton);
5419 exports['default'] = DescriptionsButton;
5421 },{"30":30,"5":5,"83":83}],28:[function(_dereq_,module,exports){
5424 exports.__esModule = true;
5426 var _textTrackMenuItem = _dereq_(31);
5428 var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
5430 var _component = _dereq_(5);
5432 var _component2 = _interopRequireDefault(_component);
5434 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5436 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5438 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5440 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
5441 * @file off-text-track-menu-item.js
5446 * A special menu item for turning of a specific type of text track
5448 * @extends TextTrackMenuItem
5450 var OffTextTrackMenuItem = function (_TextTrackMenuItem) {
5451 _inherits(OffTextTrackMenuItem, _TextTrackMenuItem);
5454 * Creates an instance of this class.
5456 * @param {Player} player
5457 * The `Player` that this class should be attached to.
5459 * @param {Object} [options]
5460 * The key/value store of player options.
5462 function OffTextTrackMenuItem(player, options) {
5463 _classCallCheck(this, OffTextTrackMenuItem);
5465 // Create pseudo track info
5466 // Requires options['kind']
5470 label: options.kind + ' off',
5475 // MenuItem is selectable
5476 options.selectable = true;
5478 var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
5480 _this.selected(true);
5485 * Handle text track change
5487 * @param {EventTarget~Event} event
5488 * The event that caused this function to run
5492 OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
5493 var tracks = this.player().textTracks();
5494 var selected = true;
5496 for (var i = 0, l = tracks.length; i < l; i++) {
5497 var track = tracks[i];
5499 if (track.kind === this.track.kind && track.mode === 'showing') {
5505 this.selected(selected);
5508 return OffTextTrackMenuItem;
5509 }(_textTrackMenuItem2['default']);
5511 _component2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem);
5512 exports['default'] = OffTextTrackMenuItem;
5514 },{"31":31,"5":5}],29:[function(_dereq_,module,exports){
5517 exports.__esModule = true;
5519 var _textTrackButton = _dereq_(30);
5521 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
5523 var _component = _dereq_(5);
5525 var _component2 = _interopRequireDefault(_component);
5527 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5529 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5531 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5533 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
5534 * @file subtitles-button.js
5539 * The button component for toggling and selecting subtitles
5541 * @extends TextTrackButton
5543 var SubtitlesButton = function (_TextTrackButton) {
5544 _inherits(SubtitlesButton, _TextTrackButton);
5547 * Creates an instance of this class.
5549 * @param {Player} player
5550 * The `Player` that this class should be attached to.
5552 * @param {Object} [options]
5553 * The key/value store of player options.
5555 * @param {Component~ReadyCallback} [ready]
5556 * The function to call when this component is ready.
5558 function SubtitlesButton(player, options, ready) {
5559 _classCallCheck(this, SubtitlesButton);
5561 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
5563 _this.el_.setAttribute('aria-label', 'Subtitles Menu');
5568 * Builds the default DOM `className`.
5571 * The DOM `className` for this object.
5575 SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() {
5576 return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
5579 return SubtitlesButton;
5580 }(_textTrackButton2['default']);
5583 * `kind` of TextTrack to look for to associate it with this menu.
5590 SubtitlesButton.prototype.kind_ = 'subtitles';
5593 * The text that should display over the `SubtitlesButton`s controls. Added for localization.
5598 SubtitlesButton.prototype.controlText_ = 'Subtitles';
5600 _component2['default'].registerComponent('SubtitlesButton', SubtitlesButton);
5601 exports['default'] = SubtitlesButton;
5603 },{"30":30,"5":5}],30:[function(_dereq_,module,exports){
5606 exports.__esModule = true;
5608 var _trackButton = _dereq_(36);
5610 var _trackButton2 = _interopRequireDefault(_trackButton);
5612 var _component = _dereq_(5);
5614 var _component2 = _interopRequireDefault(_component);
5616 var _textTrackMenuItem = _dereq_(31);
5618 var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
5620 var _offTextTrackMenuItem = _dereq_(28);
5622 var _offTextTrackMenuItem2 = _interopRequireDefault(_offTextTrackMenuItem);
5624 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5626 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5628 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5630 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
5631 * @file text-track-button.js
5636 * The base class for buttons that toggle specific text track types (e.g. subtitles)
5638 * @extends MenuButton
5640 var TextTrackButton = function (_TrackButton) {
5641 _inherits(TextTrackButton, _TrackButton);
5644 * Creates an instance of this class.
5646 * @param {Player} player
5647 * The `Player` that this class should be attached to.
5649 * @param {Object} [options={}]
5650 * The key/value store of player options.
5652 function TextTrackButton(player) {
5653 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
5655 _classCallCheck(this, TextTrackButton);
5657 options.tracks = player.textTracks();
5659 return _possibleConstructorReturn(this, _TrackButton.call(this, player, options));
5663 * Create a menu item for each text track
5665 * @param {TextTrackMenuItem[]} [items=[]]
5666 * Existing array of items to use during creation
5668 * @return {TextTrackMenuItem[]}
5669 * Array of menu items that were created
5673 TextTrackButton.prototype.createItems = function createItems() {
5674 var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
5676 // Add an OFF menu item to turn all tracks off
5677 items.push(new _offTextTrackMenuItem2['default'](this.player_, { kind: this.kind_ }));
5678 this.hideThreshold_ += 1;
5680 var tracks = this.player_.textTracks();
5686 for (var i = 0; i < tracks.length; i++) {
5687 var track = tracks[i];
5689 // only add tracks that are of the appropriate kind and have a label
5690 if (track.kind === this.kind_) {
5691 items.push(new _textTrackMenuItem2['default'](this.player_, {
5693 // MenuItem is selectable
5702 return TextTrackButton;
5703 }(_trackButton2['default']);
5705 _component2['default'].registerComponent('TextTrackButton', TextTrackButton);
5706 exports['default'] = TextTrackButton;
5708 },{"28":28,"31":31,"36":36,"5":5}],31:[function(_dereq_,module,exports){
5711 exports.__esModule = true;
5713 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
5715 var _menuItem = _dereq_(48);
5717 var _menuItem2 = _interopRequireDefault(_menuItem);
5719 var _component = _dereq_(5);
5721 var _component2 = _interopRequireDefault(_component);
5723 var _fn = _dereq_(83);
5725 var Fn = _interopRequireWildcard(_fn);
5727 var _window = _dereq_(95);
5729 var _window2 = _interopRequireDefault(_window);
5731 var _document = _dereq_(94);
5733 var _document2 = _interopRequireDefault(_document);
5735 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
5737 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5739 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5741 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5743 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
5744 * @file text-track-menu-item.js
5749 * The specific menu item type for selecting a language within a text track kind
5753 var TextTrackMenuItem = function (_MenuItem) {
5754 _inherits(TextTrackMenuItem, _MenuItem);
5757 * Creates an instance of this class.
5759 * @param {Player} player
5760 * The `Player` that this class should be attached to.
5762 * @param {Object} [options]
5763 * The key/value store of player options.
5765 function TextTrackMenuItem(player, options) {
5766 _classCallCheck(this, TextTrackMenuItem);
5768 var track = options.track;
5769 var tracks = player.textTracks();
5771 // Modify options for parent MenuItem class's init.
5772 options.label = track.label || track.language || 'Unknown';
5773 options.selected = track['default'] || track.mode === 'showing';
5775 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
5777 _this.track = track;
5780 var changeHandler = Fn.bind(_this, _this.handleTracksChange);
5782 player.on(['loadstart', 'texttrackchange'], changeHandler);
5783 tracks.addEventListener('change', changeHandler);
5784 _this.on('dispose', function () {
5785 tracks.removeEventListener('change', changeHandler);
5789 // iOS7 doesn't dispatch change events to TextTrackLists when an
5790 // associated track's mode changes. Without something like
5791 // Object.observe() (also not present on iOS7), it's not
5792 // possible to detect changes to the mode attribute and polyfill
5793 // the change event. As a poor substitute, we manually dispatch
5794 // change events whenever the controls modify the mode.
5795 if (tracks && tracks.onchange === undefined) {
5798 _this.on(['tap', 'click'], function () {
5799 if (_typeof(_window2['default'].Event) !== 'object') {
5800 // Android 2.3 throws an Illegal Constructor error for window.Event
5802 event = new _window2['default'].Event('change');
5804 // continue regardless of error
5809 event = _document2['default'].createEvent('Event');
5810 event.initEvent('change', true, true);
5813 tracks.dispatchEvent(event);
5820 * This gets called when an `TextTrackMenuItem` is "clicked". See
5821 * {@link ClickableComponent} for more detailed information on what a click can be.
5823 * @param {EventTarget~Event} event
5824 * The `keydown`, `tap`, or `click` event that caused this function to be
5832 TextTrackMenuItem.prototype.handleClick = function handleClick(event) {
5833 var kind = this.track.kind;
5834 var tracks = this.player_.textTracks();
5836 _MenuItem.prototype.handleClick.call(this, event);
5842 for (var i = 0; i < tracks.length; i++) {
5843 var track = tracks[i];
5845 if (track.kind !== kind) {
5849 if (track === this.track) {
5850 track.mode = 'showing';
5852 track.mode = 'disabled';
5858 * Handle text track list change
5860 * @param {EventTarget~Event} event
5861 * The `change` event that caused this function to be called.
5863 * @listens TextTrackList#change
5867 TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
5868 this.selected(this.track.mode === 'showing');
5871 return TextTrackMenuItem;
5872 }(_menuItem2['default']);
5874 _component2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem);
5875 exports['default'] = TextTrackMenuItem;
5877 },{"48":48,"5":5,"83":83,"94":94,"95":95}],32:[function(_dereq_,module,exports){
5880 exports.__esModule = true;
5882 var _component = _dereq_(5);
5884 var _component2 = _interopRequireDefault(_component);
5886 var _dom = _dereq_(81);
5888 var Dom = _interopRequireWildcard(_dom);
5890 var _formatTime = _dereq_(84);
5892 var _formatTime2 = _interopRequireDefault(_formatTime);
5894 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
5896 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5898 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5900 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5902 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
5903 * @file current-time-display.js
5908 * Displays the current time
5910 * @extends Component
5912 var CurrentTimeDisplay = function (_Component) {
5913 _inherits(CurrentTimeDisplay, _Component);
5916 * Creates an instance of this class.
5918 * @param {Player} player
5919 * The `Player` that this class should be attached to.
5921 * @param {Object} [options]
5922 * The key/value store of player options.
5924 function CurrentTimeDisplay(player, options) {
5925 _classCallCheck(this, CurrentTimeDisplay);
5927 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
5929 _this.on(player, 'timeupdate', _this.updateContent);
5934 * Create the `Component`'s DOM element
5937 * The element that was created.
5941 CurrentTimeDisplay.prototype.createEl = function createEl() {
5942 var el = _Component.prototype.createEl.call(this, 'div', {
5943 className: 'vjs-current-time vjs-time-control vjs-control'
5946 this.contentEl_ = Dom.createEl('div', {
5947 className: 'vjs-current-time-display',
5948 // label the current time for screen reader users
5949 innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00'
5951 // tell screen readers not to automatically read the time as it changes
5955 el.appendChild(this.contentEl_);
5960 * Update current time display
5962 * @param {EventTarget~Event} [event]
5963 * The `timeupdate` event that caused this function to run.
5965 * @listens Player#timeupdate
5969 CurrentTimeDisplay.prototype.updateContent = function updateContent(event) {
5970 // Allows for smooth scrubbing, when player can't keep up.
5971 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
5972 var localizedText = this.localize('Current Time');
5973 var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration());
5975 if (formattedTime !== this.formattedTime_) {
5976 this.formattedTime_ = formattedTime;
5977 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
5981 return CurrentTimeDisplay;
5982 }(_component2['default']);
5984 _component2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
5985 exports['default'] = CurrentTimeDisplay;
5987 },{"5":5,"81":81,"84":84}],33:[function(_dereq_,module,exports){
5990 exports.__esModule = true;
5992 var _component = _dereq_(5);
5994 var _component2 = _interopRequireDefault(_component);
5996 var _dom = _dereq_(81);
5998 var Dom = _interopRequireWildcard(_dom);
6000 var _formatTime = _dereq_(84);
6002 var _formatTime2 = _interopRequireDefault(_formatTime);
6004 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
6006 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6008 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6010 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6012 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6013 * @file duration-display.js
6018 * Displays the duration
6020 * @extends Component
6022 var DurationDisplay = function (_Component) {
6023 _inherits(DurationDisplay, _Component);
6026 * Creates an instance of this class.
6028 * @param {Player} player
6029 * The `Player` that this class should be attached to.
6031 * @param {Object} [options]
6032 * The key/value store of player options.
6034 function DurationDisplay(player, options) {
6035 _classCallCheck(this, DurationDisplay);
6037 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
6039 _this.on(player, 'durationchange', _this.updateContent);
6041 // Also listen for timeupdate and loadedmetadata because removing those
6042 // listeners could have broken dependent applications/libraries. These
6043 // can likely be removed for 6.0.
6044 _this.on(player, 'timeupdate', _this.updateContent);
6045 _this.on(player, 'loadedmetadata', _this.updateContent);
6050 * Create the `Component`'s DOM element
6053 * The element that was created.
6057 DurationDisplay.prototype.createEl = function createEl() {
6058 var el = _Component.prototype.createEl.call(this, 'div', {
6059 className: 'vjs-duration vjs-time-control vjs-control'
6062 this.contentEl_ = Dom.createEl('div', {
6063 className: 'vjs-duration-display',
6064 // label the duration time for screen reader users
6065 innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00'
6067 // tell screen readers not to automatically read the time as it changes
6071 el.appendChild(this.contentEl_);
6076 * Update duration time display.
6078 * @param {EventTarget~Event} [event]
6079 * The `durationchange`, `timeupdate`, or `loadedmetadata` event that caused
6080 * this function to be called.
6082 * @listens Player#durationchange
6083 * @listens Player#timeupdate
6084 * @listens Player#loadedmetadata
6088 DurationDisplay.prototype.updateContent = function updateContent(event) {
6089 var duration = this.player_.duration();
6091 if (duration && this.duration_ !== duration) {
6092 this.duration_ = duration;
6093 var localizedText = this.localize('Duration Time');
6094 var formattedTime = (0, _formatTime2['default'])(duration);
6096 // label the duration time for screen reader users
6097 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
6101 return DurationDisplay;
6102 }(_component2['default']);
6104 _component2['default'].registerComponent('DurationDisplay', DurationDisplay);
6105 exports['default'] = DurationDisplay;
6107 },{"5":5,"81":81,"84":84}],34:[function(_dereq_,module,exports){
6110 exports.__esModule = true;
6112 var _component = _dereq_(5);
6114 var _component2 = _interopRequireDefault(_component);
6116 var _dom = _dereq_(81);
6118 var Dom = _interopRequireWildcard(_dom);
6120 var _formatTime = _dereq_(84);
6122 var _formatTime2 = _interopRequireDefault(_formatTime);
6124 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
6126 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6128 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6130 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6132 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6133 * @file remaining-time-display.js
6138 * Displays the time left in the video
6140 * @extends Component
6142 var RemainingTimeDisplay = function (_Component) {
6143 _inherits(RemainingTimeDisplay, _Component);
6146 * Creates an instance of this class.
6148 * @param {Player} player
6149 * The `Player` that this class should be attached to.
6151 * @param {Object} [options]
6152 * The key/value store of player options.
6154 function RemainingTimeDisplay(player, options) {
6155 _classCallCheck(this, RemainingTimeDisplay);
6157 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
6159 _this.on(player, 'timeupdate', _this.updateContent);
6160 _this.on(player, 'durationchange', _this.updateContent);
6165 * Create the `Component`'s DOM element
6168 * The element that was created.
6172 RemainingTimeDisplay.prototype.createEl = function createEl() {
6173 var el = _Component.prototype.createEl.call(this, 'div', {
6174 className: 'vjs-remaining-time vjs-time-control vjs-control'
6177 this.contentEl_ = Dom.createEl('div', {
6178 className: 'vjs-remaining-time-display',
6179 // label the remaining time for screen reader users
6180 innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00'
6182 // tell screen readers not to automatically read the time as it changes
6186 el.appendChild(this.contentEl_);
6191 * Update remaining time display.
6193 * @param {EventTarget~Event} [event]
6194 * The `timeupdate` or `durationchange` event that caused this to run.
6196 * @listens Player#timeupdate
6197 * @listens Player#durationchange
6201 RemainingTimeDisplay.prototype.updateContent = function updateContent(event) {
6202 if (this.player_.duration()) {
6203 var localizedText = this.localize('Remaining Time');
6204 var formattedTime = (0, _formatTime2['default'])(this.player_.remainingTime());
6206 if (formattedTime !== this.formattedTime_) {
6207 this.formattedTime_ = formattedTime;
6208 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime;
6212 // Allows for smooth scrubbing, when player can't keep up.
6213 // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
6214 // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration());
6217 return RemainingTimeDisplay;
6218 }(_component2['default']);
6220 _component2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
6221 exports['default'] = RemainingTimeDisplay;
6223 },{"5":5,"81":81,"84":84}],35:[function(_dereq_,module,exports){
6226 exports.__esModule = true;
6228 var _component = _dereq_(5);
6230 var _component2 = _interopRequireDefault(_component);
6232 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6234 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6236 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6238 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6239 * @file time-divider.js
6244 * The separator between the current time and duration.
6245 * Can be hidden if it's not needed in the design.
6247 * @extends Component
6249 var TimeDivider = function (_Component) {
6250 _inherits(TimeDivider, _Component);
6252 function TimeDivider() {
6253 _classCallCheck(this, TimeDivider);
6255 return _possibleConstructorReturn(this, _Component.apply(this, arguments));
6259 * Create the component's DOM element
6262 * The element that was created.
6264 TimeDivider.prototype.createEl = function createEl() {
6265 return _Component.prototype.createEl.call(this, 'div', {
6266 className: 'vjs-time-control vjs-time-divider',
6267 innerHTML: '<div><span>/</span></div>'
6272 }(_component2['default']);
6274 _component2['default'].registerComponent('TimeDivider', TimeDivider);
6275 exports['default'] = TimeDivider;
6277 },{"5":5}],36:[function(_dereq_,module,exports){
6280 exports.__esModule = true;
6282 var _menuButton = _dereq_(47);
6284 var _menuButton2 = _interopRequireDefault(_menuButton);
6286 var _component = _dereq_(5);
6288 var _component2 = _interopRequireDefault(_component);
6290 var _fn = _dereq_(83);
6292 var Fn = _interopRequireWildcard(_fn);
6294 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
6296 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6298 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6300 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6302 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6303 * @file track-button.js
6308 * The base class for buttons that toggle specific track types (e.g. subtitles).
6310 * @extends MenuButton
6312 var TrackButton = function (_MenuButton) {
6313 _inherits(TrackButton, _MenuButton);
6316 * Creates an instance of this class.
6318 * @param {Player} player
6319 * The `Player` that this class should be attached to.
6321 * @param {Object} [options]
6322 * The key/value store of player options.
6324 function TrackButton(player, options) {
6325 _classCallCheck(this, TrackButton);
6327 var tracks = options.tracks;
6329 var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options));
6331 if (_this.items.length <= 1) {
6336 return _possibleConstructorReturn(_this);
6339 var updateHandler = Fn.bind(_this, _this.update);
6341 tracks.addEventListener('removetrack', updateHandler);
6342 tracks.addEventListener('addtrack', updateHandler);
6344 _this.player_.on('dispose', function () {
6345 tracks.removeEventListener('removetrack', updateHandler);
6346 tracks.removeEventListener('addtrack', updateHandler);
6352 }(_menuButton2['default']);
6354 _component2['default'].registerComponent('TrackButton', TrackButton);
6355 exports['default'] = TrackButton;
6357 },{"47":47,"5":5,"83":83}],37:[function(_dereq_,module,exports){
6360 exports.__esModule = true;
6362 var _slider = _dereq_(57);
6364 var _slider2 = _interopRequireDefault(_slider);
6366 var _component = _dereq_(5);
6368 var _component2 = _interopRequireDefault(_component);
6370 var _fn = _dereq_(83);
6372 var Fn = _interopRequireWildcard(_fn);
6376 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
6378 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6380 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6382 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6384 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6385 * @file volume-bar.js
6389 // Required children
6393 * The bar that contains the volume level and can be clicked on to adjust the level
6397 var VolumeBar = function (_Slider) {
6398 _inherits(VolumeBar, _Slider);
6401 * Creates an instance of this class.
6403 * @param {Player} player
6404 * The `Player` that this class should be attached to.
6406 * @param {Object} [options]
6407 * The key/value store of player options.
6409 function VolumeBar(player, options) {
6410 _classCallCheck(this, VolumeBar);
6412 var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options));
6414 _this.on(player, 'volumechange', _this.updateARIAAttributes);
6415 player.ready(Fn.bind(_this, _this.updateARIAAttributes));
6420 * Create the `Component`'s DOM element
6423 * The element that was created.
6427 VolumeBar.prototype.createEl = function createEl() {
6428 return _Slider.prototype.createEl.call(this, 'div', {
6429 className: 'vjs-volume-bar vjs-slider-bar'
6431 'aria-label': 'volume level'
6436 * Handle movement events on the {@link VolumeMenuButton}.
6438 * @param {EventTarget~Event} event
6439 * The event that caused this function to run.
6441 * @listens mousemove
6445 VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) {
6447 this.player_.volume(this.calculateDistance(event));
6451 * If the player is muted unmute it.
6455 VolumeBar.prototype.checkMuted = function checkMuted() {
6456 if (this.player_.muted()) {
6457 this.player_.muted(false);
6462 * Get percent of volume level
6465 * Volume level percent as a decimal number.
6469 VolumeBar.prototype.getPercent = function getPercent() {
6470 if (this.player_.muted()) {
6473 return this.player_.volume();
6477 * Increase volume level for keyboard users
6481 VolumeBar.prototype.stepForward = function stepForward() {
6483 this.player_.volume(this.player_.volume() + 0.1);
6487 * Decrease volume level for keyboard users
6491 VolumeBar.prototype.stepBack = function stepBack() {
6493 this.player_.volume(this.player_.volume() - 0.1);
6497 * Update ARIA accessibility attributes
6499 * @param {EventTarget~Event} [event]
6500 * The `volumechange` event that caused this function to run.
6502 * @listens Player#volumechange
6506 VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes(event) {
6507 // Current value of volume bar as a percentage
6508 var volume = (this.player_.volume() * 100).toFixed(2);
6510 this.el_.setAttribute('aria-valuenow', volume);
6511 this.el_.setAttribute('aria-valuetext', volume + '%');
6515 }(_slider2['default']);
6518 * Default options for the `VolumeBar`
6525 VolumeBar.prototype.options_ = {
6526 children: ['volumeLevel'],
6527 barName: 'volumeLevel'
6531 * Call the update event for this Slider when this event happens on the player.
6535 VolumeBar.prototype.playerEvent = 'volumechange';
6537 _component2['default'].registerComponent('VolumeBar', VolumeBar);
6538 exports['default'] = VolumeBar;
6540 },{"39":39,"5":5,"57":57,"83":83}],38:[function(_dereq_,module,exports){
6543 exports.__esModule = true;
6545 var _component = _dereq_(5);
6547 var _component2 = _interopRequireDefault(_component);
6551 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6553 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6555 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6557 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6558 * @file volume-control.js
6562 // Required children
6566 * The component for controlling the volume level
6568 * @extends Component
6570 var VolumeControl = function (_Component) {
6571 _inherits(VolumeControl, _Component);
6574 * Creates an instance of this class.
6576 * @param {Player} player
6577 * The `Player` that this class should be attached to.
6579 * @param {Object} [options={}]
6580 * The key/value store of player options.
6582 function VolumeControl(player, options) {
6583 _classCallCheck(this, VolumeControl);
6585 // hide volume controls when they're not supported by the current tech
6586 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
6588 if (player.tech_ && player.tech_.featuresVolumeControl === false) {
6589 _this.addClass('vjs-hidden');
6591 _this.on(player, 'loadstart', function () {
6592 if (player.tech_.featuresVolumeControl === false) {
6593 this.addClass('vjs-hidden');
6595 this.removeClass('vjs-hidden');
6602 * Create the `Component`'s DOM element
6605 * The element that was created.
6609 VolumeControl.prototype.createEl = function createEl() {
6610 return _Component.prototype.createEl.call(this, 'div', {
6611 className: 'vjs-volume-control vjs-control'
6615 return VolumeControl;
6616 }(_component2['default']);
6619 * Default options for the `VolumeControl`
6626 VolumeControl.prototype.options_ = {
6627 children: ['volumeBar']
6630 _component2['default'].registerComponent('VolumeControl', VolumeControl);
6631 exports['default'] = VolumeControl;
6633 },{"37":37,"5":5}],39:[function(_dereq_,module,exports){
6636 exports.__esModule = true;
6638 var _component = _dereq_(5);
6640 var _component2 = _interopRequireDefault(_component);
6642 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6644 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6646 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6648 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6649 * @file volume-level.js
6654 * Shows volume level
6656 * @extends Component
6658 var VolumeLevel = function (_Component) {
6659 _inherits(VolumeLevel, _Component);
6661 function VolumeLevel() {
6662 _classCallCheck(this, VolumeLevel);
6664 return _possibleConstructorReturn(this, _Component.apply(this, arguments));
6668 * Create the `Component`'s DOM element
6671 * The element that was created.
6673 VolumeLevel.prototype.createEl = function createEl() {
6674 return _Component.prototype.createEl.call(this, 'div', {
6675 className: 'vjs-volume-level',
6676 innerHTML: '<span class="vjs-control-text"></span>'
6681 }(_component2['default']);
6683 _component2['default'].registerComponent('VolumeLevel', VolumeLevel);
6684 exports['default'] = VolumeLevel;
6686 },{"5":5}],40:[function(_dereq_,module,exports){
6689 exports.__esModule = true;
6691 var _fn = _dereq_(83);
6693 var Fn = _interopRequireWildcard(_fn);
6695 var _component = _dereq_(5);
6697 var _component2 = _interopRequireDefault(_component);
6699 var _popup = _dereq_(54);
6701 var _popup2 = _interopRequireDefault(_popup);
6703 var _popupButton = _dereq_(53);
6705 var _popupButton2 = _interopRequireDefault(_popupButton);
6707 var _muteToggle = _dereq_(11);
6709 var _muteToggle2 = _interopRequireDefault(_muteToggle);
6711 var _volumeBar = _dereq_(37);
6713 var _volumeBar2 = _interopRequireDefault(_volumeBar);
6715 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6717 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
6719 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6721 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6723 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6724 * @file volume-menu-button.js
6729 * Button for volume popup
6731 * @extends PopupButton
6733 var VolumeMenuButton = function (_PopupButton) {
6734 _inherits(VolumeMenuButton, _PopupButton);
6737 * Creates an instance of this class.
6739 * @param {Player} player
6740 * The `Player` that this class should be attached to.
6742 * @param {Object} [options={}]
6743 * The key/value store of player options.
6745 function VolumeMenuButton(player) {
6746 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
6748 _classCallCheck(this, VolumeMenuButton);
6750 // Default to inline
6751 if (options.inline === undefined) {
6752 options.inline = true;
6755 // If the vertical option isn't passed at all, default to true.
6756 if (options.vertical === undefined) {
6757 // If an inline volumeMenuButton is used, we should default to using
6758 // a horizontal slider for obvious reasons.
6759 if (options.inline) {
6760 options.vertical = false;
6762 options.vertical = true;
6766 // The vertical option needs to be set on the volumeBar as well,
6767 // since that will need to be passed along to the VolumeBar constructor
6768 options.volumeBar = options.volumeBar || {};
6769 options.volumeBar.vertical = !!options.vertical;
6771 // Same listeners as MuteToggle
6772 var _this = _possibleConstructorReturn(this, _PopupButton.call(this, player, options));
6774 _this.on(player, 'volumechange', _this.volumeUpdate);
6775 _this.on(player, 'loadstart', _this.volumeUpdate);
6777 // hide mute toggle if the current tech doesn't support volume control
6778 function updateVisibility() {
6779 if (player.tech_ && player.tech_.featuresVolumeControl === false) {
6780 this.addClass('vjs-hidden');
6782 this.removeClass('vjs-hidden');
6786 updateVisibility.call(_this);
6787 _this.on(player, 'loadstart', updateVisibility);
6789 _this.on(_this.volumeBar, ['slideractive', 'focus'], function () {
6790 this.addClass('vjs-slider-active');
6793 _this.on(_this.volumeBar, ['sliderinactive', 'blur'], function () {
6794 this.removeClass('vjs-slider-active');
6797 _this.on(_this.volumeBar, ['focus'], function () {
6798 this.addClass('vjs-lock-showing');
6801 _this.on(_this.volumeBar, ['blur'], function () {
6802 this.removeClass('vjs-lock-showing');
6808 * Builds the default DOM `className`.
6811 * The DOM `className` for this object.
6815 VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() {
6816 var orientationClass = '';
6818 if (this.options_.vertical) {
6819 orientationClass = 'vjs-volume-menu-button-vertical';
6821 orientationClass = 'vjs-volume-menu-button-horizontal';
6824 return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass;
6828 * Create the VolumeMenuButton popup
6831 * The popup that was created
6835 VolumeMenuButton.prototype.createPopup = function createPopup() {
6836 var popup = new _popup2['default'](this.player_, {
6837 contentElType: 'div'
6840 var vb = new _volumeBar2['default'](this.player_, this.options_.volumeBar);
6844 this.menuContent = popup;
6845 this.volumeBar = vb;
6847 this.attachVolumeBarEvents();
6853 * This gets called when an `VolumeMenuButton` is "clicked". See
6854 * {@link ClickableComponent} for more detailed information on what a click can be.
6856 * @param {EventTarget~Event} [event]
6857 * The `keydown`, `tap`, or `click` event that caused this function to be
6865 VolumeMenuButton.prototype.handleClick = function handleClick(event) {
6866 _muteToggle2['default'].prototype.handleClick.call(this);
6867 _PopupButton.prototype.handleClick.call(this);
6871 * Add events listeners to the created `VolumeBar`.
6875 VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() {
6876 this.menuContent.on(['mousedown', 'touchdown'], Fn.bind(this, this.handleMouseDown));
6880 * Handle the `mousedown` and `touchdown` events on the `VolumeBar`
6882 * @param {EventTarget~Event} [event]
6883 * The `mousedown` or `touchdown` event that caused this to run.
6885 * @listens mousedown
6886 * @listens touchdown
6890 VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) {
6891 this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
6892 this.on(this.el_.ownerDocument, ['mouseup', 'touchend'], this.handleMouseUp);
6896 * Handle the `mouseup` and `touchend` events on the `VolumeBar`
6898 * @param {EventTarget~Event} [event]
6899 * The `mouseup` or `touchend` event that caused this to run.
6906 VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) {
6907 this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
6910 return VolumeMenuButton;
6911 }(_popupButton2['default']);
6914 * @borrows MuteToggle#update as VolumeMenuButton#volumeUpdate
6918 VolumeMenuButton.prototype.volumeUpdate = _muteToggle2['default'].prototype.update;
6921 * The text that should display over the `VolumeMenuButton`s controls. Added for localization.
6926 VolumeMenuButton.prototype.controlText_ = 'Mute';
6928 _component2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton);
6929 exports['default'] = VolumeMenuButton;
6931 },{"11":11,"37":37,"5":5,"53":53,"54":54,"83":83}],41:[function(_dereq_,module,exports){
6934 exports.__esModule = true;
6936 var _component = _dereq_(5);
6938 var _component2 = _interopRequireDefault(_component);
6940 var _modalDialog = _dereq_(50);
6942 var _modalDialog2 = _interopRequireDefault(_modalDialog);
6944 var _mergeOptions = _dereq_(87);
6946 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
6948 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6950 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6952 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6954 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
6955 * @file error-display.js
6960 * A display that indicates an error has occurred. This means that the video
6963 * @extends ModalDialog
6965 var ErrorDisplay = function (_ModalDialog) {
6966 _inherits(ErrorDisplay, _ModalDialog);
6969 * Creates an instance of this class.
6971 * @param {Player} player
6972 * The `Player` that this class should be attached to.
6974 * @param {Object} [options]
6975 * The key/value store of player options.
6977 function ErrorDisplay(player, options) {
6978 _classCallCheck(this, ErrorDisplay);
6980 var _this = _possibleConstructorReturn(this, _ModalDialog.call(this, player, options));
6982 _this.on(player, 'error', _this.open);
6987 * Builds the default DOM `className`.
6990 * The DOM `className` for this object.
6992 * @deprecated Since version 5.
6996 ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() {
6997 return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this);
7001 * Gets the localized error message based on the `Player`s error.
7004 * The `Player`s error message localized or an empty string.
7008 ErrorDisplay.prototype.content = function content() {
7009 var error = this.player().error();
7011 return error ? this.localize(error.message) : '';
7014 return ErrorDisplay;
7015 }(_modalDialog2['default']);
7018 * The default options for an `ErrorDisplay`.
7024 ErrorDisplay.prototype.options_ = (0, _mergeOptions2['default'])(_modalDialog2['default'].prototype.options_, {
7031 _component2['default'].registerComponent('ErrorDisplay', ErrorDisplay);
7032 exports['default'] = ErrorDisplay;
7034 },{"5":5,"50":50,"87":87}],42:[function(_dereq_,module,exports){
7037 exports.__esModule = true;
7039 var _events = _dereq_(82);
7041 var Events = _interopRequireWildcard(_events);
7043 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
7046 * `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It
7047 * adds shorthand functions that wrap around lengthy functions. For example:
7048 * the `on` function is a wrapper around `addEventListener`.
7050 * @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget}
7051 * @class EventTarget
7053 var EventTarget = function EventTarget() {};
7056 * A Custom DOM event.
7058 * @typedef {Object} EventTarget~Event
7059 * @see [Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
7063 * All event listeners should follow the following format.
7065 * @callback EventTarget~EventListener
7066 * @this {EventTarget}
7068 * @param {EventTarget~Event} event
7069 * the event that triggered this function
7071 * @param {Object} [hash]
7072 * hash of data sent during the event
7076 * An object containing event names as keys and booleans as values.
7078 * > NOTE: If an event name is set to a true value here {@link EventTarget#trigger}
7079 * will have extra functionality. See that function for more information.
7081 * @property EventTarget.prototype.allowedEvents_
7085 * @file src/js/event-target.js
7087 EventTarget.prototype.allowedEvents_ = {};
7090 * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a
7091 * function that will get called when an event with a certain name gets triggered.
7093 * @param {string|string[]} type
7094 * An event name or an array of event names.
7096 * @param {EventTarget~EventListener} fn
7097 * The function to call with `EventTarget`s
7099 EventTarget.prototype.on = function (type, fn) {
7100 // Remove the addEventListener alias before calling Events.on
7101 // so we don't get into an infinite type loop
7102 var ael = this.addEventListener;
7104 this.addEventListener = function () {};
7105 Events.on(this, type, fn);
7106 this.addEventListener = ael;
7110 * An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic
7111 * the standard DOM API.
7114 * @see {@link EventTarget#on}
7116 EventTarget.prototype.addEventListener = EventTarget.prototype.on;
7119 * Removes an `event listener` for a specific event from an instance of `EventTarget`.
7120 * This makes it so that the `event listener` will no longer get called when the
7121 * named event happens.
7123 * @param {string|string[]} type
7124 * An event name or an array of event names.
7126 * @param {EventTarget~EventListener} fn
7127 * The function to remove.
7129 EventTarget.prototype.off = function (type, fn) {
7130 Events.off(this, type, fn);
7134 * An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic
7135 * the standard DOM API.
7138 * @see {@link EventTarget#off}
7140 EventTarget.prototype.removeEventListener = EventTarget.prototype.off;
7143 * This function will add an `event listener` that gets triggered only once. After the
7144 * first trigger it will get removed. This is like adding an `event listener`
7145 * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself.
7147 * @param {string|string[]} type
7148 * An event name or an array of event names.
7150 * @param {EventTarget~EventListener} fn
7151 * The function to be called once for each event name.
7153 EventTarget.prototype.one = function (type, fn) {
7154 // Remove the addEventListener alialing Events.on
7155 // so we don't get into an infinite type loop
7156 var ael = this.addEventListener;
7158 this.addEventListener = function () {};
7159 Events.one(this, type, fn);
7160 this.addEventListener = ael;
7164 * This function causes an event to happen. This will then cause any `event listeners`
7165 * that are waiting for that event, to get called. If there are no `event listeners`
7166 * for an event then nothing will happen.
7168 * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`.
7169 * Trigger will also call the `on` + `uppercaseEventName` function.
7172 * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call
7173 * `onClick` if it exists.
7175 * @param {string|EventTarget~Event|Object} event
7176 * The name of the event, an `Event`, or an object with a key of type set to
7179 EventTarget.prototype.trigger = function (event) {
7180 var type = event.type || event;
7182 if (typeof event === 'string') {
7183 event = { type: type };
7185 event = Events.fixEvent(event);
7187 if (this.allowedEvents_[type] && this['on' + type]) {
7188 this['on' + type](event);
7191 Events.trigger(this, event);
7195 * An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic
7196 * the standard DOM API.
7199 * @see {@link EventTarget#trigger}
7201 EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;
7203 exports['default'] = EventTarget;
7205 },{"82":82}],43:[function(_dereq_,module,exports){
7208 exports.__esModule = true;
7210 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
7212 var _log = _dereq_(86);
7214 var _log2 = _interopRequireDefault(_log);
7216 var _obj = _dereq_(88);
7218 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7226 * A combination of node inherits and babel's inherits (after transpile).
7227 * Both work the same but node adds `super_` to the subClass
7228 * and Bable adds the superClass as __proto__. Both seem useful.
7230 * @param {Object} subClass
7231 * The class to inherit to
7233 * @param {Object} superClass
7234 * The class to inherit from
7238 var _inherits = function _inherits(subClass, superClass) {
7239 if (typeof superClass !== 'function' && superClass !== null) {
7240 throw new TypeError('Super expression must either be null or a function, not ' + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass)));
7243 subClass.prototype = Object.create(superClass && superClass.prototype, {
7254 subClass.super_ = superClass;
7259 * Function for subclassing using the same inheritance that
7260 * videojs uses internally
7262 * @param {Object} superClass
7263 * The class to inherit from
7265 * @param {Object} [subClassMethods={}]
7266 * The class to inherit to
7269 * The new object with subClassMethods that inherited superClass.
7271 var extendFn = function extendFn(superClass) {
7272 var subClassMethods = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7274 var subClass = function subClass() {
7275 superClass.apply(this, arguments);
7280 if ((0, _obj.isObject)(subClassMethods)) {
7281 if (typeof subClassMethods.init === 'function') {
7282 _log2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.');
7283 subClassMethods.constructor = subClassMethods.init;
7285 if (subClassMethods.constructor !== Object.prototype.constructor) {
7286 subClass = subClassMethods.constructor;
7288 methods = subClassMethods;
7289 } else if (typeof subClassMethods === 'function') {
7290 subClass = subClassMethods;
7293 _inherits(subClass, superClass);
7295 // Extend subObj's prototype with functions and other properties from props
7296 for (var name in methods) {
7297 if (methods.hasOwnProperty(name)) {
7298 subClass.prototype[name] = methods[name];
7305 exports['default'] = extendFn;
7307 },{"86":86,"88":88}],44:[function(_dereq_,module,exports){
7310 exports.__esModule = true;
7312 var _document = _dereq_(94);
7314 var _document2 = _interopRequireDefault(_document);
7316 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7319 * Store the browser-specific methods for the fullscreen API.
7322 * @see [Specification]{@link https://fullscreen.spec.whatwg.org}
7323 * @see [Map Approach From Screenfull.js]{@link https://github.com/sindresorhus/screenfull.js}
7325 var FullscreenApi = {};
7327 // browser API methods
7329 * @file fullscreen-api.js
7330 * @module fullscreen-api
7333 var apiMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'],
7335 ['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'],
7336 // Old WebKit (Safari 5.1)
7337 ['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'],
7339 ['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'],
7341 ['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']];
7343 var specApi = apiMap[0];
7344 var browserApi = void 0;
7346 // determine the supported set of functions
7347 for (var i = 0; i < apiMap.length; i++) {
7348 // check for exitFullscreen function
7349 if (apiMap[i][1] in _document2['default']) {
7350 browserApi = apiMap[i];
7355 // map the browser API names to the spec API names
7357 for (var _i = 0; _i < browserApi.length; _i++) {
7358 FullscreenApi[specApi[_i]] = browserApi[_i];
7362 exports['default'] = FullscreenApi;
7364 },{"94":94}],45:[function(_dereq_,module,exports){
7367 exports.__esModule = true;
7369 var _component = _dereq_(5);
7371 var _component2 = _interopRequireDefault(_component);
7373 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7375 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7377 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
7379 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
7380 * @file loading-spinner.js
7385 * A loading spinner for use during waiting/loading events.
7387 * @extends Component
7389 var LoadingSpinner = function (_Component) {
7390 _inherits(LoadingSpinner, _Component);
7392 function LoadingSpinner() {
7393 _classCallCheck(this, LoadingSpinner);
7395 return _possibleConstructorReturn(this, _Component.apply(this, arguments));
7399 * Create the `LoadingSpinner`s DOM element.
7402 * The dom element that gets created.
7404 LoadingSpinner.prototype.createEl = function createEl() {
7405 return _Component.prototype.createEl.call(this, 'div', {
7406 className: 'vjs-loading-spinner',
7411 return LoadingSpinner;
7412 }(_component2['default']);
7414 _component2['default'].registerComponent('LoadingSpinner', LoadingSpinner);
7415 exports['default'] = LoadingSpinner;
7417 },{"5":5}],46:[function(_dereq_,module,exports){
7420 exports.__esModule = true;
7422 var _obj = _dereq_(88);
7425 * A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class.
7427 * @param {number|string|Object|MediaError} value
7428 * This can be of multiple types:
7429 * - number: should be a standard error code
7430 * - string: an error message (the code will be 0)
7431 * - Object: arbitrary properties
7432 * - `MediaError` (native): used to populate a video.js `MediaError` object
7433 * - `MediaError` (video.js): will return itself if it's already a
7434 * video.js `MediaError` object.
7436 * @see [MediaError Spec]{@link https://dev.w3.org/html5/spec-author-view/video.html#mediaerror}
7437 * @see [Encrypted MediaError Spec]{@link https://www.w3.org/TR/2013/WD-encrypted-media-20130510/#error-codes}
7441 function MediaError(value) {
7443 // Allow redundant calls to this constructor to avoid having `instanceof`
7444 // checks peppered around the code.
7445 if (value instanceof MediaError) {
7449 if (typeof value === 'number') {
7451 } else if (typeof value === 'string') {
7452 // default code is zero, so this is a custom error
7453 this.message = value;
7454 } else if ((0, _obj.isObject)(value)) {
7456 // We assign the `code` property manually because native `MediaError` objects
7457 // do not expose it as an own/enumerable property of the object.
7458 if (typeof value.code === 'number') {
7459 this.code = value.code;
7462 (0, _obj.assign)(this, value);
7465 if (!this.message) {
7466 this.message = MediaError.defaultMessages[this.code] || '';
7471 * The error code that refers two one of the defined `MediaError` types
7476 * @file media-error.js
7478 MediaError.prototype.code = 0;
7481 * An optional message that to show with the error. Message is not part of the HTML5
7482 * video spec but allows for more informative custom errors.
7486 MediaError.prototype.message = '';
7489 * An optional status code that can be set by plugins to allow even more detail about
7490 * the error. For example a plugin might provide a specific HTTP status code and an
7491 * error message for that code. Then when the plugin gets that error this class will
7492 * know how to display an error message for it. This allows a custom message to show
7493 * up on the `Player` error overlay.
7497 MediaError.prototype.status = null;
7500 * Errors indexed by the W3C standard. The order **CANNOT CHANGE**! See the
7501 * specification listed under {@link MediaError} for more information.
7505 * @property {string} 0 - MEDIA_ERR_CUSTOM
7506 * @property {string} 1 - MEDIA_ERR_CUSTOM
7507 * @property {string} 2 - MEDIA_ERR_ABORTED
7508 * @property {string} 3 - MEDIA_ERR_NETWORK
7509 * @property {string} 4 - MEDIA_ERR_SRC_NOT_SUPPORTED
7510 * @property {string} 5 - MEDIA_ERR_ENCRYPTED
7512 MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED'];
7515 * The default `MediaError` messages based on the {@link MediaError.errorTypes}.
7520 MediaError.defaultMessages = {
7521 1: 'You aborted the media playback',
7522 2: 'A network error caused the media download to fail part-way.',
7523 3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.',
7524 4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.',
7525 5: 'The media is encrypted and we do not have the keys to decrypt it.'
7528 // Add types as properties on MediaError
7529 // e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
7530 for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) {
7531 MediaError[MediaError.errorTypes[errNum]] = errNum;
7532 // values should be accessible on both the class and instance
7533 MediaError.prototype[MediaError.errorTypes[errNum]] = errNum;
7536 // jsdocs for instance/static members added above
7537 // instance methods use `#` and static methods use `.`
7539 * W3C error code for any custom error.
7541 * @member MediaError#MEDIA_ERR_CUSTOM
7542 * @constant {number}
7546 * W3C error code for any custom error.
7548 * @member MediaError.MEDIA_ERR_CUSTOM
7549 * @constant {number}
7554 * W3C error code for media error aborted.
7556 * @member MediaError#MEDIA_ERR_ABORTED
7557 * @constant {number}
7561 * W3C error code for media error aborted.
7563 * @member MediaError.MEDIA_ERR_ABORTED
7564 * @constant {number}
7569 * W3C error code for any network error.
7571 * @member MediaError#MEDIA_ERR_NETWORK
7572 * @constant {number}
7576 * W3C error code for any network error.
7578 * @member MediaError.MEDIA_ERR_NETWORK
7579 * @constant {number}
7584 * W3C error code for any decoding error.
7586 * @member MediaError#MEDIA_ERR_DECODE
7587 * @constant {number}
7591 * W3C error code for any decoding error.
7593 * @member MediaError.MEDIA_ERR_DECODE
7594 * @constant {number}
7599 * W3C error code for any time that a source is not supported.
7601 * @member MediaError#MEDIA_ERR_SRC_NOT_SUPPORTED
7602 * @constant {number}
7606 * W3C error code for any time that a source is not supported.
7608 * @member MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED
7609 * @constant {number}
7614 * W3C error code for any time that a source is encrypted.
7616 * @member MediaError#MEDIA_ERR_ENCRYPTED
7617 * @constant {number}
7621 * W3C error code for any time that a source is encrypted.
7623 * @member MediaError.MEDIA_ERR_ENCRYPTED
7624 * @constant {number}
7628 exports['default'] = MediaError;
7630 },{"88":88}],47:[function(_dereq_,module,exports){
7633 exports.__esModule = true;
7635 var _clickableComponent = _dereq_(3);
7637 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
7639 var _component = _dereq_(5);
7641 var _component2 = _interopRequireDefault(_component);
7643 var _menu = _dereq_(49);
7645 var _menu2 = _interopRequireDefault(_menu);
7647 var _dom = _dereq_(81);
7649 var Dom = _interopRequireWildcard(_dom);
7651 var _fn = _dereq_(83);
7653 var Fn = _interopRequireWildcard(_fn);
7655 var _toTitleCase = _dereq_(91);
7657 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
7659 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
7661 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7663 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7665 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
7667 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
7668 * @file menu-button.js
7673 * A `MenuButton` class for any popup {@link Menu}.
7675 * @extends ClickableComponent
7677 var MenuButton = function (_ClickableComponent) {
7678 _inherits(MenuButton, _ClickableComponent);
7681 * Creates an instance of this class.
7683 * @param {Player} player
7684 * The `Player` that this class should be attached to.
7686 * @param {Object} [options={}]
7687 * The key/value store of player options.
7689 function MenuButton(player) {
7690 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7692 _classCallCheck(this, MenuButton);
7694 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
7698 _this.enabled_ = true;
7700 _this.el_.setAttribute('aria-haspopup', 'true');
7701 _this.el_.setAttribute('role', 'menuitem');
7702 _this.on('keydown', _this.handleSubmenuKeyPress);
7707 * Update the menu based on the current state of its items.
7711 MenuButton.prototype.update = function update() {
7712 var menu = this.createMenu();
7715 this.removeChild(this.menu);
7719 this.addChild(menu);
7722 * Track the state of the menu button
7727 this.buttonPressed_ = false;
7728 this.el_.setAttribute('aria-expanded', 'false');
7730 if (this.items && this.items.length <= this.hideThreshold_) {
7738 * Create the menu and add all items to it.
7741 * The constructed menu
7745 MenuButton.prototype.createMenu = function createMenu() {
7746 var menu = new _menu2['default'](this.player_);
7749 * Hide the menu if the number of items is less than or equal to this threshold. This defaults
7750 * to 0 and whenever we add items which can be hidden to the menu we'll increment it. We list
7751 * it here because every time we run `createMenu` we need to reset the value.
7756 this.hideThreshold_ = 0;
7758 // Add a title list item to the top
7759 if (this.options_.title) {
7760 var title = Dom.createEl('li', {
7761 className: 'vjs-menu-title',
7762 innerHTML: (0, _toTitleCase2['default'])(this.options_.title),
7766 this.hideThreshold_ += 1;
7768 menu.children_.unshift(title);
7769 Dom.insertElFirst(title, menu.contentEl());
7772 this.items = this.createItems();
7775 // Add menu items to the menu
7776 for (var i = 0; i < this.items.length; i++) {
7777 menu.addItem(this.items[i]);
7785 * Create the list of menu items. Specific to each subclass.
7791 MenuButton.prototype.createItems = function createItems() {};
7794 * Create the `MenuButtons`s DOM element.
7797 * The element that gets created.
7801 MenuButton.prototype.createEl = function createEl() {
7802 return _ClickableComponent.prototype.createEl.call(this, 'div', {
7803 className: this.buildCSSClass()
7808 * Builds the default DOM `className`.
7811 * The DOM `className` for this object.
7815 MenuButton.prototype.buildCSSClass = function buildCSSClass() {
7816 var menuButtonClass = 'vjs-menu-button';
7818 // If the inline option is passed, we want to use different styles altogether.
7819 if (this.options_.inline === true) {
7820 menuButtonClass += '-inline';
7822 menuButtonClass += '-popup';
7825 return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
7829 * Handle a click on a `MenuButton`.
7830 * See {@link ClickableComponent#handleClick} for instances where this is called.
7832 * @param {EventTarget~Event} event
7833 * The `keydown`, `tap`, or `click` event that caused this function to be
7841 MenuButton.prototype.handleClick = function handleClick(event) {
7842 // When you click the button it adds focus, which will show the menu.
7843 // So we'll remove focus when the mouse leaves the button. Focus is needed
7844 // for tab navigation.
7846 this.one(this.menu.contentEl(), 'mouseleave', Fn.bind(this, function (e) {
7847 this.unpressButton();
7850 if (this.buttonPressed_) {
7851 this.unpressButton();
7858 * Handle tab, escape, down arrow, and up arrow keys for `MenuButton`. See
7859 * {@link ClickableComponent#handleKeyPress} for instances where this is called.
7861 * @param {EventTarget~Event} event
7862 * The `keydown` event that caused this function to be called.
7868 MenuButton.prototype.handleKeyPress = function handleKeyPress(event) {
7870 // Escape (27) key or Tab (9) key unpress the 'button'
7871 if (event.which === 27 || event.which === 9) {
7872 if (this.buttonPressed_) {
7873 this.unpressButton();
7875 // Don't preventDefault for Tab key - we still want to lose focus
7876 if (event.which !== 9) {
7877 event.preventDefault();
7879 // Up (38) key or Down (40) key press the 'button'
7880 } else if (event.which === 38 || event.which === 40) {
7881 if (!this.buttonPressed_) {
7883 event.preventDefault();
7886 _ClickableComponent.prototype.handleKeyPress.call(this, event);
7891 * Handle a `keydown` event on a sub-menu. The listener for this is added in
7894 * @param {EventTarget~Event} event
7901 MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) {
7903 // Escape (27) key or Tab (9) key unpress the 'button'
7904 if (event.which === 27 || event.which === 9) {
7905 if (this.buttonPressed_) {
7906 this.unpressButton();
7908 // Don't preventDefault for Tab key - we still want to lose focus
7909 if (event.which !== 9) {
7910 event.preventDefault();
7916 * Put the current `MenuButton` into a pressed state.
7920 MenuButton.prototype.pressButton = function pressButton() {
7921 if (this.enabled_) {
7922 this.buttonPressed_ = true;
7923 this.menu.lockShowing();
7924 this.el_.setAttribute('aria-expanded', 'true');
7925 // set the focus into the submenu
7931 * Take the current `MenuButton` out of a pressed state.
7935 MenuButton.prototype.unpressButton = function unpressButton() {
7936 if (this.enabled_) {
7937 this.buttonPressed_ = false;
7938 this.menu.unlockShowing();
7939 this.el_.setAttribute('aria-expanded', 'false');
7940 // Set focus back to this menu button
7946 * Disable the `MenuButton`. Don't allow it to be clicked.
7948 * @return {MenuButton}
7949 * Returns itself; method can be chained.
7953 MenuButton.prototype.disable = function disable() {
7954 // Unpress, but don't force focus on this button
7955 this.buttonPressed_ = false;
7956 this.menu.unlockShowing();
7957 this.el_.setAttribute('aria-expanded', 'false');
7959 this.enabled_ = false;
7961 return _ClickableComponent.prototype.disable.call(this);
7965 * Enable the `MenuButton`. Allow it to be clicked.
7967 * @return {MenuButton}
7968 * Returns itself; method can be chained.
7972 MenuButton.prototype.enable = function enable() {
7973 this.enabled_ = true;
7975 return _ClickableComponent.prototype.enable.call(this);
7979 }(_clickableComponent2['default']);
7981 _component2['default'].registerComponent('MenuButton', MenuButton);
7982 exports['default'] = MenuButton;
7984 },{"3":3,"49":49,"5":5,"81":81,"83":83,"91":91}],48:[function(_dereq_,module,exports){
7987 exports.__esModule = true;
7989 var _clickableComponent = _dereq_(3);
7991 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
7993 var _component = _dereq_(5);
7995 var _component2 = _interopRequireDefault(_component);
7997 var _obj = _dereq_(88);
7999 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8001 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8003 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
8005 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
8006 * @file menu-item.js
8011 * The component for a menu item. `<li>`
8013 * @extends ClickableComponent
8015 var MenuItem = function (_ClickableComponent) {
8016 _inherits(MenuItem, _ClickableComponent);
8019 * Creates an instance of the this class.
8021 * @param {Player} player
8022 * The `Player` that this class should be attached to.
8024 * @param {Object} [options={}]
8025 * The key/value store of player options.
8028 function MenuItem(player, options) {
8029 _classCallCheck(this, MenuItem);
8031 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
8033 _this.selectable = options.selectable;
8035 _this.selected(options.selected);
8037 if (_this.selectable) {
8038 // TODO: May need to be either menuitemcheckbox or menuitemradio,
8039 // and may need logical grouping of menu items.
8040 _this.el_.setAttribute('role', 'menuitemcheckbox');
8042 _this.el_.setAttribute('role', 'menuitem');
8048 * Create the `MenuItem's DOM element
8050 * @param {string} [type=li]
8051 * Element's node type, not actually used, always set to `li`.
8053 * @param {Object} [props={}]
8054 * An object of properties that should be set on the element
8056 * @param {Object} [attrs={}]
8057 * An object of attributes that should be set on the element
8060 * The element that gets created.
8064 MenuItem.prototype.createEl = function createEl(type, props, attrs) {
8065 // The control is textual, not just an icon
8066 this.nonIconControl = true;
8068 return _ClickableComponent.prototype.createEl.call(this, 'li', (0, _obj.assign)({
8069 className: 'vjs-menu-item',
8070 innerHTML: this.localize(this.options_.label),
8076 * Any click on a `MenuItem` puts int into the selected state.
8077 * See {@link ClickableComponent#handleClick} for instances where this is called.
8079 * @param {EventTarget~Event} event
8080 * The `keydown`, `tap`, or `click` event that caused this function to be
8088 MenuItem.prototype.handleClick = function handleClick(event) {
8089 this.selected(true);
8093 * Set the state for this menu item as selected or not.
8095 * @param {boolean} selected
8096 * if the menu item is selected or not
8100 MenuItem.prototype.selected = function selected(_selected) {
8101 if (this.selectable) {
8103 this.addClass('vjs-selected');
8104 this.el_.setAttribute('aria-checked', 'true');
8105 // aria-checked isn't fully supported by browsers/screen readers,
8106 // so indicate selected state to screen reader in the control text.
8107 this.controlText(', selected');
8109 this.removeClass('vjs-selected');
8110 this.el_.setAttribute('aria-checked', 'false');
8111 // Indicate un-selected state to screen reader
8112 // Note that a space clears out the selected state text
8113 this.controlText(' ');
8119 }(_clickableComponent2['default']);
8121 _component2['default'].registerComponent('MenuItem', MenuItem);
8122 exports['default'] = MenuItem;
8124 },{"3":3,"5":5,"88":88}],49:[function(_dereq_,module,exports){
8127 exports.__esModule = true;
8129 var _component = _dereq_(5);
8131 var _component2 = _interopRequireDefault(_component);
8133 var _dom = _dereq_(81);
8135 var Dom = _interopRequireWildcard(_dom);
8137 var _fn = _dereq_(83);
8139 var Fn = _interopRequireWildcard(_fn);
8141 var _events = _dereq_(82);
8143 var Events = _interopRequireWildcard(_events);
8145 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
8147 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8149 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8151 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
8153 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
8159 * The Menu component is used to build popup menus, including subtitle and
8160 * captions selection menus.
8162 * @extends Component
8164 var Menu = function (_Component) {
8165 _inherits(Menu, _Component);
8168 * Create an instance of this class.
8170 * @param {Player} player
8171 * the player that this component should attach to
8173 * @param {Object} [options]
8174 * Object of option names and values
8177 function Menu(player, options) {
8178 _classCallCheck(this, Menu);
8180 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
8182 _this.focusedChild_ = -1;
8184 _this.on('keydown', _this.handleKeyPress);
8189 * Add a {@link MenuItem} to the menu.
8191 * @param {Object|string} component
8192 * The name or instance of the `MenuItem` to add.
8197 Menu.prototype.addItem = function addItem(component) {
8198 this.addChild(component);
8199 component.on('click', Fn.bind(this, function (event) {
8200 this.unlockShowing();
8201 // TODO: Need to set keyboard focus back to the menuButton
8206 * Create the `Menu`s DOM element.
8209 * the element that was created
8213 Menu.prototype.createEl = function createEl() {
8214 var contentElType = this.options_.contentElType || 'ul';
8216 this.contentEl_ = Dom.createEl(contentElType, {
8217 className: 'vjs-menu-content'
8220 this.contentEl_.setAttribute('role', 'menu');
8222 var el = _Component.prototype.createEl.call(this, 'div', {
8223 append: this.contentEl_,
8224 className: 'vjs-menu'
8227 el.setAttribute('role', 'presentation');
8228 el.appendChild(this.contentEl_);
8230 // Prevent clicks from bubbling up. Needed for Menu Buttons,
8231 // where a click on the parent is significant
8232 Events.on(el, 'click', function (event) {
8233 event.preventDefault();
8234 event.stopImmediatePropagation();
8241 * Handle a `keydown` event on this menu. This listener is added in the constructor.
8243 * @param {EventTarget~Event} event
8244 * A `keydown` event that happened on the menu.
8250 Menu.prototype.handleKeyPress = function handleKeyPress(event) {
8251 // Left and Down Arrows
8252 if (event.which === 37 || event.which === 40) {
8253 event.preventDefault();
8256 // Up and Right Arrows
8257 } else if (event.which === 38 || event.which === 39) {
8258 event.preventDefault();
8264 * Move to next (lower) menu item for keyboard users.
8268 Menu.prototype.stepForward = function stepForward() {
8271 if (this.focusedChild_ !== undefined) {
8272 stepChild = this.focusedChild_ + 1;
8274 this.focus(stepChild);
8278 * Move to previous (higher) menu item for keyboard users.
8282 Menu.prototype.stepBack = function stepBack() {
8285 if (this.focusedChild_ !== undefined) {
8286 stepChild = this.focusedChild_ - 1;
8288 this.focus(stepChild);
8292 * Set focus on a {@link MenuItem} in the `Menu`.
8294 * @param {Object|string} [item=0]
8295 * Index of child item set focus on.
8299 Menu.prototype.focus = function focus() {
8300 var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
8302 var children = this.children().slice();
8303 var haveTitle = children.length && children[0].className && /vjs-menu-title/.test(children[0].className);
8309 if (children.length > 0) {
8312 } else if (item >= children.length) {
8313 item = children.length - 1;
8316 this.focusedChild_ = item;
8318 children[item].el_.focus();
8323 }(_component2['default']);
8325 _component2['default'].registerComponent('Menu', Menu);
8326 exports['default'] = Menu;
8328 },{"5":5,"81":81,"82":82,"83":83}],50:[function(_dereq_,module,exports){
8331 exports.__esModule = true;
8333 var _dom = _dereq_(81);
8335 var Dom = _interopRequireWildcard(_dom);
8337 var _fn = _dereq_(83);
8339 var Fn = _interopRequireWildcard(_fn);
8341 var _component = _dereq_(5);
8343 var _component2 = _interopRequireDefault(_component);
8345 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8347 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
8349 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8351 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
8353 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
8354 * @file modal-dialog.js
8358 var MODAL_CLASS_NAME = 'vjs-modal-dialog';
8362 * The `ModalDialog` displays over the video and its controls, which blocks
8363 * interaction with the player until it is closed.
8365 * Modal dialogs include a "Close" button and will close when that button
8366 * is activated - or when ESC is pressed anywhere.
8368 * @extends Component
8371 var ModalDialog = function (_Component) {
8372 _inherits(ModalDialog, _Component);
8375 * Create an instance of this class.
8377 * @param {Player} player
8378 * The `Player` that this class should be attached to.
8380 * @param {Object} [options]
8381 * The key/value store of player options.
8383 * @param {Mixed} [options.content=undefined]
8384 * Provide customized content for this modal.
8386 * @param {string} [options.description]
8387 * A text description for the modal, primarily for accessibility.
8389 * @param {boolean} [options.fillAlways=false]
8390 * Normally, modals are automatically filled only the first time
8391 * they open. This tells the modal to refresh its content
8392 * every time it opens.
8394 * @param {string} [options.label]
8395 * A text label for the modal, primarily for accessibility.
8397 * @param {boolean} [options.temporary=true]
8398 * If `true`, the modal can only be opened once; it will be
8399 * disposed as soon as it's closed.
8401 * @param {boolean} [options.uncloseable=false]
8402 * If `true`, the user will not be able to close the modal
8403 * through the UI in the normal ways. Programmatic closing is
8406 function ModalDialog(player, options) {
8407 _classCallCheck(this, ModalDialog);
8409 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
8411 _this.opened_ = _this.hasBeenOpened_ = _this.hasBeenFilled_ = false;
8413 _this.closeable(!_this.options_.uncloseable);
8414 _this.content(_this.options_.content);
8416 // Make sure the contentEl is defined AFTER any children are initialized
8417 // because we only want the contents of the modal in the contentEl
8418 // (not the UI elements like the close button).
8419 _this.contentEl_ = Dom.createEl('div', {
8420 className: MODAL_CLASS_NAME + '-content'
8425 _this.descEl_ = Dom.createEl('p', {
8426 className: MODAL_CLASS_NAME + '-description vjs-offscreen',
8427 id: _this.el().getAttribute('aria-describedby')
8430 Dom.textContent(_this.descEl_, _this.description());
8431 _this.el_.appendChild(_this.descEl_);
8432 _this.el_.appendChild(_this.contentEl_);
8437 * Create the `ModalDialog`'s DOM element
8440 * The DOM element that gets created.
8444 ModalDialog.prototype.createEl = function createEl() {
8445 return _Component.prototype.createEl.call(this, 'div', {
8446 className: this.buildCSSClass(),
8449 'aria-describedby': this.id() + '_description',
8450 'aria-hidden': 'true',
8451 'aria-label': this.label(),
8457 * Builds the default DOM `className`.
8460 * The DOM `className` for this object.
8464 ModalDialog.prototype.buildCSSClass = function buildCSSClass() {
8465 return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this);
8469 * Handles `keydown` events on the document, looking for ESC, which closes
8472 * @param {EventTarget~Event} e
8473 * The keypress that triggered this event.
8479 ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) {
8480 if (e.which === ESC && this.closeable()) {
8486 * Returns the label string for this modal. Primarily used for accessibility.
8489 * the localized or raw label of this modal.
8493 ModalDialog.prototype.label = function label() {
8494 return this.options_.label || this.localize('Modal Window');
8498 * Returns the description string for this modal. Primarily used for
8502 * The localized or raw description of this modal.
8506 ModalDialog.prototype.description = function description() {
8507 var desc = this.options_.description || this.localize('This is a modal window.');
8509 // Append a universal closeability message if the modal is closeable.
8510 if (this.closeable()) {
8511 desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.');
8520 * @fires ModalDialog#beforemodalopen
8521 * @fires ModalDialog#modalopen
8523 * @return {ModalDialog}
8524 * Returns itself; method can be chained.
8528 ModalDialog.prototype.open = function open() {
8529 if (!this.opened_) {
8530 var player = this.player();
8533 * Fired just before a `ModalDialog` is opened.
8535 * @event ModalDialog#beforemodalopen
8536 * @type {EventTarget~Event}
8538 this.trigger('beforemodalopen');
8539 this.opened_ = true;
8541 // Fill content if the modal has never opened before and
8542 // never been filled.
8543 if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) {
8547 // If the player was playing, pause it and take note of its previously
8549 this.wasPlaying_ = !player.paused();
8551 if (this.options_.pauseOnOpen && this.wasPlaying_) {
8555 if (this.closeable()) {
8556 this.on(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
8559 player.controls(false);
8561 this.el().setAttribute('aria-hidden', 'false');
8564 * Fired just after a `ModalDialog` is opened.
8566 * @event ModalDialog#modalopen
8567 * @type {EventTarget~Event}
8569 this.trigger('modalopen');
8570 this.hasBeenOpened_ = true;
8576 * If the `ModalDialog` is currently open or closed.
8578 * @param {boolean} [value]
8579 * If given, it will open (`true`) or close (`false`) the modal.
8582 * the current open state of the modaldialog
8586 ModalDialog.prototype.opened = function opened(value) {
8587 if (typeof value === 'boolean') {
8588 this[value ? 'open' : 'close']();
8590 return this.opened_;
8594 * Closes the modal, does nothing if the `ModalDialog` is
8597 * @fires ModalDialog#beforemodalclose
8598 * @fires ModalDialog#modalclose
8600 * @return {ModalDialog}
8601 * Returns itself; method can be chained.
8605 ModalDialog.prototype.close = function close() {
8607 var player = this.player();
8610 * Fired just before a `ModalDialog` is closed.
8612 * @event ModalDialog#beforemodalclose
8613 * @type {EventTarget~Event}
8615 this.trigger('beforemodalclose');
8616 this.opened_ = false;
8618 if (this.wasPlaying_ && this.options_.pauseOnOpen) {
8622 if (this.closeable()) {
8623 this.off(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
8626 player.controls(true);
8628 this.el().setAttribute('aria-hidden', 'true');
8631 * Fired just after a `ModalDialog` is closed.
8633 * @event ModalDialog#modalclose
8634 * @type {EventTarget~Event}
8636 this.trigger('modalclose');
8638 if (this.options_.temporary) {
8646 * Check to see if the `ModalDialog` is closeable via the UI.
8648 * @param {boolean} [value]
8649 * If given as a boolean, it will set the `closeable` option.
8652 * Returns the final value of the closable option.
8656 ModalDialog.prototype.closeable = function closeable(value) {
8657 if (typeof value === 'boolean') {
8658 var closeable = this.closeable_ = !!value;
8659 var close = this.getChild('closeButton');
8661 // If this is being made closeable and has no close button, add one.
8662 if (closeable && !close) {
8664 // The close button should be a child of the modal - not its
8665 // content element, so temporarily change the content element.
8666 var temp = this.contentEl_;
8668 this.contentEl_ = this.el_;
8669 close = this.addChild('closeButton', { controlText: 'Close Modal Dialog' });
8670 this.contentEl_ = temp;
8671 this.on(close, 'close', this.close);
8674 // If this is being made uncloseable and has a close button, remove it.
8675 if (!closeable && close) {
8676 this.off(close, 'close', this.close);
8677 this.removeChild(close);
8681 return this.closeable_;
8685 * Fill the modal's content element with the modal's "content" option.
8686 * The content element will be emptied before this change takes place.
8688 * @return {ModalDialog}
8689 * Returns itself; method can be chained.
8693 ModalDialog.prototype.fill = function fill() {
8694 return this.fillWith(this.content());
8698 * Fill the modal's content element with arbitrary content.
8699 * The content element will be emptied before this change takes place.
8701 * @fires ModalDialog#beforemodalfill
8702 * @fires ModalDialog#modalfill
8704 * @param {Mixed} [content]
8705 * The same rules apply to this as apply to the `content` option.
8707 * @return {ModalDialog}
8708 * Returns itself; method can be chained.
8712 ModalDialog.prototype.fillWith = function fillWith(content) {
8713 var contentEl = this.contentEl();
8714 var parentEl = contentEl.parentNode;
8715 var nextSiblingEl = contentEl.nextSibling;
8718 * Fired just before a `ModalDialog` is filled with content.
8720 * @event ModalDialog#beforemodalfill
8721 * @type {EventTarget~Event}
8723 this.trigger('beforemodalfill');
8724 this.hasBeenFilled_ = true;
8726 // Detach the content element from the DOM before performing
8727 // manipulation to avoid modifying the live DOM multiple times.
8728 parentEl.removeChild(contentEl);
8730 Dom.insertContent(contentEl, content);
8732 * Fired just after a `ModalDialog` is filled with content.
8734 * @event ModalDialog#modalfill
8735 * @type {EventTarget~Event}
8737 this.trigger('modalfill');
8739 // Re-inject the re-filled content element.
8740 if (nextSiblingEl) {
8741 parentEl.insertBefore(contentEl, nextSiblingEl);
8743 parentEl.appendChild(contentEl);
8750 * Empties the content element. This happens anytime the modal is filled.
8752 * @fires ModalDialog#beforemodalempty
8753 * @fires ModalDialog#modalempty
8755 * @return {ModalDialog}
8756 * Returns itself; method can be chained.
8760 ModalDialog.prototype.empty = function empty() {
8762 * Fired just before a `ModalDialog` is emptied.
8764 * @event ModalDialog#beforemodalempty
8765 * @type {EventTarget~Event}
8767 this.trigger('beforemodalempty');
8768 Dom.emptyEl(this.contentEl());
8771 * Fired just after a `ModalDialog` is emptied.
8773 * @event ModalDialog#modalempty
8774 * @type {EventTarget~Event}
8776 this.trigger('modalempty');
8781 * Gets or sets the modal content, which gets normalized before being
8782 * rendered into the DOM.
8784 * This does not update the DOM or fill the modal, but it is called during
8787 * @param {Mixed} [value]
8788 * If defined, sets the internal content value to be used on the
8789 * next call(s) to `fill`. This value is normalized before being
8790 * inserted. To "clear" the internal content value, pass `null`.
8793 * The current content of the modal dialog
8797 ModalDialog.prototype.content = function content(value) {
8798 if (typeof value !== 'undefined') {
8799 this.content_ = value;
8801 return this.content_;
8805 }(_component2['default']);
8808 * Default options for `ModalDialog` default options.
8815 ModalDialog.prototype.options_ = {
8820 _component2['default'].registerComponent('ModalDialog', ModalDialog);
8821 exports['default'] = ModalDialog;
8823 },{"5":5,"81":81,"83":83}],51:[function(_dereq_,module,exports){
8826 exports.__esModule = true;
8828 var _component = _dereq_(5);
8830 var _component2 = _interopRequireDefault(_component);
8832 var _document = _dereq_(94);
8834 var _document2 = _interopRequireDefault(_document);
8836 var _window = _dereq_(95);
8838 var _window2 = _interopRequireDefault(_window);
8840 var _events = _dereq_(82);
8842 var Events = _interopRequireWildcard(_events);
8844 var _dom = _dereq_(81);
8846 var Dom = _interopRequireWildcard(_dom);
8848 var _fn = _dereq_(83);
8850 var Fn = _interopRequireWildcard(_fn);
8852 var _guid = _dereq_(85);
8854 var Guid = _interopRequireWildcard(_guid);
8856 var _browser = _dereq_(78);
8858 var browser = _interopRequireWildcard(_browser);
8860 var _log = _dereq_(86);
8862 var _log2 = _interopRequireDefault(_log);
8864 var _toTitleCase = _dereq_(91);
8866 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
8868 var _timeRanges = _dereq_(90);
8870 var _buffer = _dereq_(79);
8872 var _stylesheet = _dereq_(89);
8874 var stylesheet = _interopRequireWildcard(_stylesheet);
8876 var _fullscreenApi = _dereq_(44);
8878 var _fullscreenApi2 = _interopRequireDefault(_fullscreenApi);
8880 var _mediaError = _dereq_(46);
8882 var _mediaError2 = _interopRequireDefault(_mediaError);
8884 var _tuple = _dereq_(97);
8886 var _tuple2 = _interopRequireDefault(_tuple);
8888 var _obj = _dereq_(88);
8890 var _mergeOptions = _dereq_(87);
8892 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
8894 var _textTrackListConverter = _dereq_(69);
8896 var _textTrackListConverter2 = _interopRequireDefault(_textTrackListConverter);
8898 var _modalDialog = _dereq_(50);
8900 var _modalDialog2 = _interopRequireDefault(_modalDialog);
8902 var _tech = _dereq_(62);
8904 var _tech2 = _interopRequireDefault(_tech);
8906 var _audioTrackList = _dereq_(63);
8908 var _audioTrackList2 = _interopRequireDefault(_audioTrackList);
8910 var _videoTrackList = _dereq_(76);
8912 var _videoTrackList2 = _interopRequireDefault(_videoTrackList);
8936 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
8938 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8940 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8942 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
8944 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
8947 // Subclasses Component
8950 // The following imports are used only to ensure that the corresponding modules
8951 // are always included in the video.js package. Importing the modules will
8952 // execute them and they will register themselves with video.js.
8955 // Import Html5 tech, at least for disposing the original video tag.
8958 // The following tech events are simply re-triggered
8959 // on the player when they happen
8960 var TECH_EVENTS_RETRIGGER = [
8962 * Fired while the user agent is downloading media data.
8964 * @event Player#progress
8965 * @type {EventTarget~Event}
8968 * Retrigger the `progress` event that was triggered by the {@link Tech}.
8971 * @method Player#handleTechProgress_
8972 * @fires Player#progress
8973 * @listens Tech#progress
8978 * Fires when the loading of an audio/video is aborted.
8980 * @event Player#abort
8981 * @type {EventTarget~Event}
8984 * Retrigger the `abort` event that was triggered by the {@link Tech}.
8987 * @method Player#handleTechAbort_
8988 * @fires Player#abort
8989 * @listens Tech#abort
8994 * Fires when the browser is intentionally not getting media data.
8996 * @event Player#suspend
8997 * @type {EventTarget~Event}
9000 * Retrigger the `suspend` event that was triggered by the {@link Tech}.
9003 * @method Player#handleTechSuspend_
9004 * @fires Player#suspend
9005 * @listens Tech#suspend
9010 * Fires when the current playlist is empty.
9012 * @event Player#emptied
9013 * @type {EventTarget~Event}
9016 * Retrigger the `emptied` event that was triggered by the {@link Tech}.
9019 * @method Player#handleTechEmptied_
9020 * @fires Player#emptied
9021 * @listens Tech#emptied
9025 * Fires when the browser is trying to get media data, but data is not available.
9027 * @event Player#stalled
9028 * @type {EventTarget~Event}
9031 * Retrigger the `stalled` event that was triggered by the {@link Tech}.
9034 * @method Player#handleTechStalled_
9035 * @fires Player#stalled
9036 * @listens Tech#stalled
9041 * Fires when the browser has loaded meta data for the audio/video.
9043 * @event Player#loadedmetadata
9044 * @type {EventTarget~Event}
9047 * Retrigger the `stalled` event that was triggered by the {@link Tech}.
9050 * @method Player#handleTechLoadedmetadata_
9051 * @fires Player#loadedmetadata
9052 * @listens Tech#loadedmetadata
9057 * Fires when the browser has loaded the current frame of the audio/video.
9059 * @event player#loadeddata
9063 * Retrigger the `loadeddata` event that was triggered by the {@link Tech}.
9066 * @method Player#handleTechLoaddeddata_
9067 * @fires Player#loadeddata
9068 * @listens Tech#loadeddata
9073 * Fires when the current playback position has changed.
9075 * @event player#timeupdate
9079 * Retrigger the `timeupdate` event that was triggered by the {@link Tech}.
9082 * @method Player#handleTechTimeUpdate_
9083 * @fires Player#timeupdate
9084 * @listens Tech#timeupdate
9089 * Fires when the playing speed of the audio/video is changed
9091 * @event player#ratechange
9095 * Retrigger the `ratechange` event that was triggered by the {@link Tech}.
9098 * @method Player#handleTechRatechange_
9099 * @fires Player#ratechange
9100 * @listens Tech#ratechange
9105 * Fires when the volume has been changed
9107 * @event player#volumechange
9111 * Retrigger the `volumechange` event that was triggered by the {@link Tech}.
9114 * @method Player#handleTechVolumechange_
9115 * @fires Player#volumechange
9116 * @listens Tech#volumechange
9121 * Fires when the text track has been changed
9123 * @event player#texttrackchange
9127 * Retrigger the `texttrackchange` event that was triggered by the {@link Tech}.
9130 * @method Player#handleTechTexttrackchange_
9131 * @fires Player#texttrackchange
9132 * @listens Tech#texttrackchange
9137 * An instance of the `Player` class is created when any of the Video.js setup methods
9138 * are used to initialize a video.
9140 * After an instance has been created it can be accessed globally in two ways:
9141 * 1. By calling `videojs('example_video_1');`
9142 * 2. By using it directly via `videojs.players.example_video_1;`
9144 * @extends Component
9147 var Player = function (_Component) {
9148 _inherits(Player, _Component);
9151 * Create an instance of this class.
9153 * @param {Element} tag
9154 * The original video DOM element used for configuring options.
9156 * @param {Object} [options]
9157 * Object of option names and values.
9159 * @param {Component~ReadyCallback} [ready]
9160 * Ready callback function.
9162 function Player(tag, options, ready) {
9163 _classCallCheck(this, Player);
9165 // Make sure tag ID exists
9166 tag.id = tag.id || 'vjs_video_' + Guid.newGUID();
9169 // The options argument overrides options set in the video tag
9170 // which overrides globally set options.
9171 // This latter part coincides with the load order
9172 // (tag must exist before Player)
9173 options = (0, _obj.assign)(Player.getTagSettings(tag), options);
9175 // Delay the initialization of children because we need to set up
9176 // player properties first, and can't use `this` before `super()`
9177 options.initChildren = false;
9179 // Same with creating the element
9180 options.createEl = false;
9182 // we don't want the player to report touch activity on itself
9183 // see enableTouchActivity in Component
9184 options.reportTouchActivity = false;
9186 // If language is not set, get the closest lang attribute
9187 if (!options.language) {
9188 if (typeof tag.closest === 'function') {
9189 var closest = tag.closest('[lang]');
9192 options.language = closest.getAttribute('lang');
9197 while (element && element.nodeType === 1) {
9198 if (Dom.getElAttributes(element).hasOwnProperty('lang')) {
9199 options.language = element.getAttribute('lang');
9202 element = element.parentNode;
9207 // Run base component initializing with new options
9209 // if the global option object was accidentally blown away by
9210 // someone, bail early with an informative error
9211 var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready));
9213 if (!_this.options_ || !_this.options_.techOrder || !_this.options_.techOrder.length) {
9214 throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?');
9217 // Store the original tag used to set options
9220 // Store the tag attributes used to restore html5 element
9221 _this.tagAttributes = tag && Dom.getElAttributes(tag);
9223 // Update current language
9224 _this.language(_this.options_.language);
9226 // Update Supported Languages
9227 if (options.languages) {
9228 // Normalise player option languages to lowercase
9229 var languagesToLower = {};
9231 Object.getOwnPropertyNames(options.languages).forEach(function (name) {
9232 languagesToLower[name.toLowerCase()] = options.languages[name];
9234 _this.languages_ = languagesToLower;
9236 _this.languages_ = Player.prototype.options_.languages;
9239 // Cache for video property values.
9243 _this.poster_ = options.poster || '';
9246 _this.controls_ = !!options.controls;
9248 // Original tag settings stored in options
9249 // now remove immediately so native controls don't flash.
9250 // May be turned back on by HTML5 tech if nativeControlsForTouch is true
9251 tag.controls = false;
9254 * Store the internal state of scrubbing
9257 * @return {Boolean} True if the user is scrubbing
9259 _this.scrubbing_ = false;
9261 _this.el_ = _this.createEl();
9263 // We also want to pass the original player options to each component and plugin
9264 // as well so they don't need to reach back into the player for options later.
9265 // We also need to do another copy of this.options_ so we don't end up with
9266 // an infinite loop.
9267 var playerOptionsCopy = (0, _mergeOptions2['default'])(_this.options_);
9270 if (options.plugins) {
9271 var plugins = options.plugins;
9273 Object.getOwnPropertyNames(plugins).forEach(function (name) {
9274 if (typeof this[name] === 'function') {
9275 this[name](plugins[name]);
9277 _log2['default'].error('Unable to find plugin:', name);
9282 _this.options_.playerOptions = playerOptionsCopy;
9284 _this.initChildren();
9286 // Set isAudio based on whether or not an audio tag was used
9287 _this.isAudio(tag.nodeName.toLowerCase() === 'audio');
9289 // Update controls className. Can't do this when the controls are initially
9290 // set because the element doesn't exist yet.
9291 if (_this.controls()) {
9292 _this.addClass('vjs-controls-enabled');
9294 _this.addClass('vjs-controls-disabled');
9297 // Set ARIA label and region role depending on player type
9298 _this.el_.setAttribute('role', 'region');
9299 if (_this.isAudio()) {
9300 _this.el_.setAttribute('aria-label', 'audio player');
9302 _this.el_.setAttribute('aria-label', 'video player');
9305 if (_this.isAudio()) {
9306 _this.addClass('vjs-audio');
9309 if (_this.flexNotSupported_()) {
9310 _this.addClass('vjs-no-flex');
9313 // TODO: Make this smarter. Toggle user state between touching/mousing
9314 // using events, since devices can have both touch and mouse events.
9315 // if (browser.TOUCH_ENABLED) {
9316 // this.addClass('vjs-touch-enabled');
9319 // iOS Safari has broken hover handling
9320 if (!browser.IS_IOS) {
9321 _this.addClass('vjs-workinghover');
9324 // Make player easily findable by ID
9325 Player.players[_this.id_] = _this;
9327 // When the player is first initialized, trigger activity so components
9328 // like the control bar show themselves if needed
9329 _this.userActive(true);
9330 _this.reportUserActivity();
9331 _this.listenForUserActivity_();
9333 _this.on('fullscreenchange', _this.handleFullscreenChange_);
9334 _this.on('stageclick', _this.handleStageClick_);
9339 * Destroys the video player and does any necessary cleanup.
9341 * This is especially helpful if you are dynamically adding and removing videos
9344 * @fires Player#dispose
9348 Player.prototype.dispose = function dispose() {
9350 * Called when the player is being disposed of.
9352 * @event Player#dispose
9353 * @type {EventTarget~Event}
9355 this.trigger('dispose');
9356 // prevent dispose from being called twice
9357 this.off('dispose');
9359 if (this.styleEl_ && this.styleEl_.parentNode) {
9360 this.styleEl_.parentNode.removeChild(this.styleEl_);
9363 // Kill reference to this player
9364 Player.players[this.id_] = null;
9366 if (this.tag && this.tag.player) {
9367 this.tag.player = null;
9370 if (this.el_ && this.el_.player) {
9371 this.el_.player = null;
9375 this.tech_.dispose();
9378 _Component.prototype.dispose.call(this);
9382 * Create the `Player`'s DOM element.
9385 * The DOM element that gets created.
9389 Player.prototype.createEl = function createEl() {
9392 var playerElIngest = this.playerElIngest_ = tag.parentNode && tag.parentNode.hasAttribute && tag.parentNode.hasAttribute('data-vjs-player');
9394 if (playerElIngest) {
9395 el = this.el_ = tag.parentNode;
9397 el = this.el_ = _Component.prototype.createEl.call(this, 'div');
9400 // set tabindex to -1 so we could focus on the player element
9401 tag.setAttribute('tabindex', '-1');
9403 // Remove width/height attrs from tag so CSS can make it 100% width/height
9404 tag.removeAttribute('width');
9405 tag.removeAttribute('height');
9407 // Copy over all the attributes from the tag, including ID and class
9408 // ID will now reference player box, not the video tag
9409 var attrs = Dom.getElAttributes(tag);
9411 Object.getOwnPropertyNames(attrs).forEach(function (attr) {
9412 // workaround so we don't totally break IE7
9413 // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7
9414 if (attr === 'class') {
9415 el.className += ' ' + attrs[attr];
9417 el.setAttribute(attr, attrs[attr]);
9421 // Update tag id/class for use as HTML5 playback tech
9422 // Might think we should do this after embedding in container so .vjs-tech class
9423 // doesn't flash 100% width/height, but class only applies with .video-js parent
9424 tag.playerId = tag.id;
9425 tag.id += '_html5_api';
9426 tag.className = 'vjs-tech';
9428 // Make player findable on elements
9429 tag.player = el.player = this;
9430 // Default state of video is paused
9431 this.addClass('vjs-paused');
9433 // Add a style element in the player that we'll use to set the width/height
9434 // of the player in a way that's still overrideable by CSS, just like the
9436 if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) {
9437 this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions');
9438 var defaultsStyleEl = Dom.$('.vjs-styles-defaults');
9439 var head = Dom.$('head');
9441 head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild);
9444 // Pass in the width/height/aspectRatio options which will update the style el
9445 this.width(this.options_.width);
9446 this.height(this.options_.height);
9447 this.fluid(this.options_.fluid);
9448 this.aspectRatio(this.options_.aspectRatio);
9450 // Hide any links within the video/audio tag, because IE doesn't hide them completely.
9451 var links = tag.getElementsByTagName('a');
9453 for (var i = 0; i < links.length; i++) {
9454 var linkEl = links.item(i);
9456 Dom.addElClass(linkEl, 'vjs-hidden');
9457 linkEl.setAttribute('hidden', 'hidden');
9460 // insertElFirst seems to cause the networkState to flicker from 3 to 2, so
9461 // keep track of the original for later so we can know if the source originally failed
9462 tag.initNetworkState_ = tag.networkState;
9464 // Wrap video tag in div (el/box) container
9465 if (tag.parentNode && !playerElIngest) {
9466 tag.parentNode.insertBefore(el, tag);
9469 // insert the tag as the first child of the player element
9470 // then manually add it to the children array so that this.addChild
9471 // will work properly for other components
9473 // Breaks iPhone, fixed in HTML5 setup.
9474 Dom.insertElFirst(tag, el);
9475 this.children_.unshift(tag);
9483 * A getter/setter for the `Player`'s width.
9485 * @param {number} [value]
9486 * The value to set the `Player's width to.
9489 * The current width of the `Player`.
9493 Player.prototype.width = function width(value) {
9494 return this.dimension('width', value);
9498 * A getter/setter for the `Player`'s height.
9500 * @param {number} [value]
9501 * The value to set the `Player's heigth to.
9504 * The current heigth of the `Player`.
9508 Player.prototype.height = function height(value) {
9509 return this.dimension('height', value);
9513 * A getter/setter for the `Player`'s width & height.
9515 * @param {string} dimension
9516 * This string can be:
9520 * @param {number} [value]
9521 * Value for dimension specified in the first argument.
9523 * @return {Player|number}
9524 * - Returns itself when setting; method can be chained.
9525 * - The dimension arguments value when getting (width/height).
9529 Player.prototype.dimension = function dimension(_dimension, value) {
9530 var privDimension = _dimension + '_';
9532 if (value === undefined) {
9533 return this[privDimension] || 0;
9537 // If an empty string is given, reset the dimension to be automatic
9538 this[privDimension] = undefined;
9540 var parsedVal = parseFloat(value);
9542 if (isNaN(parsedVal)) {
9543 _log2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension);
9547 this[privDimension] = parsedVal;
9550 this.updateStyleEl_();
9555 * A getter/setter/toggler for the vjs-fluid `className` on the `Player`.
9557 * @param {boolean} [bool]
9558 * - A value of true adds the class.
9559 * - A value of false removes the class.
9560 * - No value will toggle the fluid class.
9562 * @return {boolean|undefined}
9563 * - The value of fluid when getting.
9564 * - `undefined` when setting.
9568 Player.prototype.fluid = function fluid(bool) {
9569 if (bool === undefined) {
9570 return !!this.fluid_;
9573 this.fluid_ = !!bool;
9576 this.addClass('vjs-fluid');
9578 this.removeClass('vjs-fluid');
9581 this.updateStyleEl_();
9585 * Get/Set the aspect ratio
9587 * @param {string} [ratio]
9588 * Aspect ratio for player
9590 * @return {string|undefined}
9591 * returns the current aspect ratio when getting
9595 * A getter/setter for the `Player`'s aspect ratio.
9597 * @param {string} [ratio]
9598 * The value to set the `Player's aspect ratio to.
9600 * @return {string|undefined}
9601 * - The current aspect ratio of the `Player` when getting.
9602 * - undefined when setting
9606 Player.prototype.aspectRatio = function aspectRatio(ratio) {
9607 if (ratio === undefined) {
9608 return this.aspectRatio_;
9611 // Check for width:height format
9612 if (!/^\d+\:\d+$/.test(ratio)) {
9613 throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.');
9615 this.aspectRatio_ = ratio;
9617 // We're assuming if you set an aspect ratio you want fluid mode,
9618 // because in fixed mode you could calculate width and height yourself.
9621 this.updateStyleEl_();
9625 * Update styles of the `Player` element (height, width and aspect ratio).
9628 * @listens Tech#loadedmetadata
9632 Player.prototype.updateStyleEl_ = function updateStyleEl_() {
9633 if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE === true) {
9634 var _width = typeof this.width_ === 'number' ? this.width_ : this.options_.width;
9635 var _height = typeof this.height_ === 'number' ? this.height_ : this.options_.height;
9636 var techEl = this.tech_ && this.tech_.el();
9640 techEl.width = _width;
9643 techEl.height = _height;
9651 var height = void 0;
9652 var aspectRatio = void 0;
9653 var idClass = void 0;
9655 // The aspect ratio is either used directly or to calculate width and height.
9656 if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') {
9657 // Use any aspectRatio that's been specifically set
9658 aspectRatio = this.aspectRatio_;
9659 } else if (this.videoWidth() > 0) {
9660 // Otherwise try to get the aspect ratio from the video metadata
9661 aspectRatio = this.videoWidth() + ':' + this.videoHeight();
9663 // Or use a default. The video element's is 2:1, but 16:9 is more common.
9664 aspectRatio = '16:9';
9667 // Get the ratio as a decimal we can use to calculate dimensions
9668 var ratioParts = aspectRatio.split(':');
9669 var ratioMultiplier = ratioParts[1] / ratioParts[0];
9671 if (this.width_ !== undefined) {
9672 // Use any width that's been specifically set
9673 width = this.width_;
9674 } else if (this.height_ !== undefined) {
9675 // Or calulate the width from the aspect ratio if a height has been set
9676 width = this.height_ / ratioMultiplier;
9678 // Or use the video's metadata, or use the video el's default of 300
9679 width = this.videoWidth() || 300;
9682 if (this.height_ !== undefined) {
9683 // Use any height that's been specifically set
9684 height = this.height_;
9686 // Otherwise calculate the height from the ratio and the width
9687 height = width * ratioMultiplier;
9690 // Ensure the CSS class is valid by starting with an alpha character
9691 if (/^[^a-zA-Z]/.test(this.id())) {
9692 idClass = 'dimensions-' + this.id();
9694 idClass = this.id() + '-dimensions';
9697 // Ensure the right class is still on the player for the style element
9698 this.addClass(idClass);
9700 stylesheet.setTextContent(this.styleEl_, '\n .' + idClass + ' {\n width: ' + width + 'px;\n height: ' + height + 'px;\n }\n\n .' + idClass + '.vjs-fluid {\n padding-top: ' + ratioMultiplier * 100 + '%;\n }\n ');
9704 * Load/Create an instance of playback {@link Tech} including element
9705 * and API methods. Then append the `Tech` element in `Player` as a child.
9707 * @param {string} techName
9708 * name of the playback technology
9710 * @param {string} source
9717 Player.prototype.loadTech_ = function loadTech_(techName, source) {
9720 // Pause and remove current playback technology
9725 // get rid of the HTML5 video tag as soon as we are using another tech
9726 if (techName !== 'Html5' && this.tag) {
9727 _tech2['default'].getTech('Html5').disposeMediaElement(this.tag);
9728 this.tag.player = null;
9732 this.techName_ = techName;
9734 // Turn off API access because we're loading a new tech that might load asynchronously
9735 this.isReady_ = false;
9737 // Grab tech-specific options from player options and add source and parent element to use.
9738 var techOptions = (0, _obj.assign)({
9740 'nativeControlsForTouch': this.options_.nativeControlsForTouch,
9741 'playerId': this.id(),
9742 'techId': this.id() + '_' + techName + '_api',
9743 'videoTracks': this.videoTracks_,
9744 'textTracks': this.textTracks_,
9745 'audioTracks': this.audioTracks_,
9746 'autoplay': this.options_.autoplay,
9747 'preload': this.options_.preload,
9748 'loop': this.options_.loop,
9749 'muted': this.options_.muted,
9750 'poster': this.poster(),
9751 'language': this.language(),
9752 'playerElIngest': this.playerElIngest_ || false,
9753 'vtt.js': this.options_['vtt.js']
9754 }, this.options_[techName.toLowerCase()]);
9757 techOptions.tag = this.tag;
9761 this.currentType_ = source.type;
9763 if (source.src === this.cache_.src && this.cache_.currentTime > 0) {
9764 techOptions.startTime = this.cache_.currentTime;
9767 this.cache_.sources = null;
9768 this.cache_.source = source;
9769 this.cache_.src = source.src;
9772 // Initialize tech instance
9773 var TechComponent = _tech2['default'].getTech(techName);
9775 // Support old behavior of techs being registered as components.
9776 // Remove once that deprecated behavior is removed.
9777 if (!TechComponent) {
9778 TechComponent = _component2['default'].getComponent(techName);
9780 this.tech_ = new TechComponent(techOptions);
9782 // player.triggerReady is always async, so don't need this to be async
9783 this.tech_.ready(Fn.bind(this, this.handleTechReady_), true);
9785 _textTrackListConverter2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_);
9787 // Listen to all HTML5-defined events and trigger them on the player
9788 TECH_EVENTS_RETRIGGER.forEach(function (event) {
9789 _this2.on(_this2.tech_, event, _this2['handleTech' + (0, _toTitleCase2['default'])(event) + '_']);
9791 this.on(this.tech_, 'loadstart', this.handleTechLoadStart_);
9792 this.on(this.tech_, 'waiting', this.handleTechWaiting_);
9793 this.on(this.tech_, 'canplay', this.handleTechCanPlay_);
9794 this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_);
9795 this.on(this.tech_, 'playing', this.handleTechPlaying_);
9796 this.on(this.tech_, 'ended', this.handleTechEnded_);
9797 this.on(this.tech_, 'seeking', this.handleTechSeeking_);
9798 this.on(this.tech_, 'seeked', this.handleTechSeeked_);
9799 this.on(this.tech_, 'play', this.handleTechPlay_);
9800 this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_);
9801 this.on(this.tech_, 'pause', this.handleTechPause_);
9802 this.on(this.tech_, 'durationchange', this.handleTechDurationChange_);
9803 this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_);
9804 this.on(this.tech_, 'error', this.handleTechError_);
9805 this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_);
9806 this.on(this.tech_, 'posterchange', this.handleTechPosterChange_);
9807 this.on(this.tech_, 'textdata', this.handleTechTextData_);
9809 this.usingNativeControls(this.techGet_('controls'));
9811 if (this.controls() && !this.usingNativeControls()) {
9812 this.addTechControlsListeners_();
9815 // Add the tech element in the DOM if it was not already there
9816 // Make sure to not insert the original video element if using Html5
9817 if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) {
9818 Dom.insertElFirst(this.tech_.el(), this.el());
9821 // Get rid of the original video tag reference after the first tech is loaded
9823 this.tag.player = null;
9829 * Unload and dispose of the current playback {@link Tech}.
9835 Player.prototype.unloadTech_ = function unloadTech_() {
9836 // Save the current text tracks so that we can reuse the same text tracks with the next tech
9837 this.videoTracks_ = this.videoTracks();
9838 this.textTracks_ = this.textTracks();
9839 this.audioTracks_ = this.audioTracks();
9840 this.textTracksJson_ = _textTrackListConverter2['default'].textTracksToJson(this.tech_);
9842 this.isReady_ = false;
9844 this.tech_.dispose();
9850 * Return a reference to the current {@link Tech}, but only if given an object with the
9851 * `IWillNotUseThisInPlugins` property having a true value. This is try and prevent misuse
9852 * of techs by plugins.
9854 * @param {Object} safety
9855 * An object that must contain `{IWillNotUseThisInPlugins: true}`
9857 * @param {boolean} safety.IWillNotUseThisInPlugins
9858 * Must be set to true or else this function will throw an error.
9865 Player.prototype.tech = function tech(safety) {
9866 if (safety && safety.IWillNotUseThisInPlugins) {
9869 var errorText = '\n Please make sure that you are not using this inside of a plugin.\n To disable this alert and error, please pass in an object with\n `IWillNotUseThisInPlugins` to the `tech` method. See\n https://github.com/videojs/video.js/issues/2617 for more info.\n ';
9871 _window2['default'].alert(errorText);
9872 throw new Error(errorText);
9876 * Set up click and touch listeners for the playback element
9878 * - On desktops: a click on the video itself will toggle playback
9879 * - On mobile devices: a click on the video toggles controls
9880 * which is done by toggling the user state between active and
9882 * - A tap can signal that a user has become active or has become inactive
9883 * e.g. a quick tap on an iPhone movie should reveal the controls. Another
9884 * quick tap should hide them again (signaling the user is in an inactive
9886 * - In addition to this, we still want the user to be considered inactive after
9887 * a few seconds of inactivity.
9889 * > Note: the only part of iOS interaction we can't mimic with this setup
9890 * is a touch and hold on the video element counting as activity in order to
9891 * keep the controls showing, but that shouldn't be an issue. A touch and hold
9892 * on any controls will still keep the user active
9898 Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() {
9899 // Make sure to remove all the previous listeners in case we are called multiple times.
9900 this.removeTechControlsListeners_();
9902 // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
9903 // trigger mousedown/up.
9904 // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object
9905 // Any touch events are set to block the mousedown event from happening
9906 this.on(this.tech_, 'mousedown', this.handleTechClick_);
9908 // If the controls were hidden we don't want that to change without a tap event
9909 // so we'll check if the controls were already showing before reporting user
9911 this.on(this.tech_, 'touchstart', this.handleTechTouchStart_);
9912 this.on(this.tech_, 'touchmove', this.handleTechTouchMove_);
9913 this.on(this.tech_, 'touchend', this.handleTechTouchEnd_);
9915 // The tap listener needs to come after the touchend listener because the tap
9916 // listener cancels out any reportedUserActivity when setting userActive(false)
9917 this.on(this.tech_, 'tap', this.handleTechTap_);
9921 * Remove the listeners used for click and tap controls. This is needed for
9922 * toggling to controls disabled, where a tap/touch should do nothing.
9928 Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() {
9929 // We don't want to just use `this.off()` because there might be other needed
9930 // listeners added by techs that extend this.
9931 this.off(this.tech_, 'tap', this.handleTechTap_);
9932 this.off(this.tech_, 'touchstart', this.handleTechTouchStart_);
9933 this.off(this.tech_, 'touchmove', this.handleTechTouchMove_);
9934 this.off(this.tech_, 'touchend', this.handleTechTouchEnd_);
9935 this.off(this.tech_, 'mousedown', this.handleTechClick_);
9939 * Player waits for the tech to be ready
9945 Player.prototype.handleTechReady_ = function handleTechReady_() {
9946 this.triggerReady();
9948 // Keep the same volume as before
9949 if (this.cache_.volume) {
9950 this.techCall_('setVolume', this.cache_.volume);
9953 // Look if the tech found a higher resolution poster while loading
9954 this.handleTechPosterChange_();
9956 // Update the duration if available
9957 this.handleTechDurationChange_();
9959 // Chrome and Safari both have issues with autoplay.
9960 // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
9961 // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
9962 // This fixes both issues. Need to wait for API, so it updates displays correctly
9963 if ((this.src() || this.currentSrc()) && this.tag && this.options_.autoplay && this.paused()) {
9965 // Chrome Fix. Fixed in Chrome v16.
9966 delete this.tag.poster;
9968 (0, _log2['default'])('deleting tag.poster throws in some browsers', e);
9975 * Retrigger the `loadstart` event that was triggered by the {@link Tech}. This
9976 * function will also trigger {@link Player#firstplay} if it is the first loadstart
9979 * @fires Player#loadstart
9980 * @fires Player#firstplay
9981 * @listens Tech#loadstart
9986 Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() {
9987 // TODO: Update to use `emptied` event instead. See #1277.
9989 this.removeClass('vjs-ended');
9990 this.removeClass('vjs-seeking');
9992 // reset the error state
9995 // If it's already playing we want to trigger a firstplay event now.
9996 // The firstplay event relies on both the play and loadstart events
9997 // which can happen in any order for a new source
9998 if (!this.paused()) {
10000 * Fired when the user agent begins looking for media data
10002 * @event Player#loadstart
10003 * @type {EventTarget~Event}
10005 this.trigger('loadstart');
10006 this.trigger('firstplay');
10008 // reset the hasStarted state
10009 this.hasStarted(false);
10010 this.trigger('loadstart');
10015 * Add/remove the vjs-has-started class
10017 * @fires Player#firstplay
10019 * @param {boolean} hasStarted
10020 * - true: adds the class
10021 * - false: remove the class
10023 * @return {boolean}
10024 * the boolean value of hasStarted
10028 Player.prototype.hasStarted = function hasStarted(_hasStarted) {
10029 if (_hasStarted !== undefined) {
10030 // only update if this is a new value
10031 if (this.hasStarted_ !== _hasStarted) {
10032 this.hasStarted_ = _hasStarted;
10034 this.addClass('vjs-has-started');
10035 // trigger the firstplay event if this newly has played
10036 this.trigger('firstplay');
10038 this.removeClass('vjs-has-started');
10043 return !!this.hasStarted_;
10047 * Fired whenever the media begins or resumes playback
10049 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play}
10050 * @fires Player#play
10051 * @listens Tech#play
10056 Player.prototype.handleTechPlay_ = function handleTechPlay_() {
10057 this.removeClass('vjs-ended');
10058 this.removeClass('vjs-paused');
10059 this.addClass('vjs-playing');
10061 // hide the poster when the user hits play
10062 this.hasStarted(true);
10064 * Triggered whenever an {@link Tech#play} event happens. Indicates that
10065 * playback has started or resumed.
10067 * @event Player#play
10068 * @type {EventTarget~Event}
10070 this.trigger('play');
10074 * Retrigger the `waiting` event that was triggered by the {@link Tech}.
10076 * @fires Player#waiting
10077 * @listens Tech#waiting
10082 Player.prototype.handleTechWaiting_ = function handleTechWaiting_() {
10085 this.addClass('vjs-waiting');
10087 * A readyState change on the DOM element has caused playback to stop.
10089 * @event Player#waiting
10090 * @type {EventTarget~Event}
10092 this.trigger('waiting');
10093 this.one('timeupdate', function () {
10094 return _this3.removeClass('vjs-waiting');
10099 * Retrigger the `canplay` event that was triggered by the {@link Tech}.
10100 * > Note: This is not consistent between browsers. See #1351
10102 * @fires Player#canplay
10103 * @listens Tech#canplay
10108 Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() {
10109 this.removeClass('vjs-waiting');
10111 * The media has a readyState of HAVE_FUTURE_DATA or greater.
10113 * @event Player#canplay
10114 * @type {EventTarget~Event}
10116 this.trigger('canplay');
10120 * Retrigger the `canplaythrough` event that was triggered by the {@link Tech}.
10122 * @fires Player#canplaythrough
10123 * @listens Tech#canplaythrough
10128 Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() {
10129 this.removeClass('vjs-waiting');
10131 * The media has a readyState of HAVE_ENOUGH_DATA or greater. This means that the
10132 * entire media file can be played without buffering.
10134 * @event Player#canplaythrough
10135 * @type {EventTarget~Event}
10137 this.trigger('canplaythrough');
10141 * Retrigger the `playing` event that was triggered by the {@link Tech}.
10143 * @fires Player#playing
10144 * @listens Tech#playing
10149 Player.prototype.handleTechPlaying_ = function handleTechPlaying_() {
10150 this.removeClass('vjs-waiting');
10152 * The media is no longer blocked from playback, and has started playing.
10154 * @event Player#playing
10155 * @type {EventTarget~Event}
10157 this.trigger('playing');
10161 * Retrigger the `seeking` event that was triggered by the {@link Tech}.
10163 * @fires Player#seeking
10164 * @listens Tech#seeking
10169 Player.prototype.handleTechSeeking_ = function handleTechSeeking_() {
10170 this.addClass('vjs-seeking');
10172 * Fired whenever the player is jumping to a new time
10174 * @event Player#seeking
10175 * @type {EventTarget~Event}
10177 this.trigger('seeking');
10181 * Retrigger the `seeked` event that was triggered by the {@link Tech}.
10183 * @fires Player#seeked
10184 * @listens Tech#seeked
10189 Player.prototype.handleTechSeeked_ = function handleTechSeeked_() {
10190 this.removeClass('vjs-seeking');
10192 * Fired when the player has finished jumping to a new time
10194 * @event Player#seeked
10195 * @type {EventTarget~Event}
10197 this.trigger('seeked');
10201 * Retrigger the `firstplay` event that was triggered by the {@link Tech}.
10203 * @fires Player#firstplay
10204 * @listens Tech#firstplay
10205 * @deprecated As of 6.0 passing the `starttime` option to the player will be deprecated
10210 Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() {
10211 // If the first starttime attribute is specified
10212 // then we will start at the given offset in seconds
10213 if (this.options_.starttime) {
10214 _log2['default'].warn('Passing the `starttime` option to the player will be deprecated in 6.0');
10215 this.currentTime(this.options_.starttime);
10218 this.addClass('vjs-has-started');
10220 * Fired the first time a video is played. Not part of the HLS spec, and this is
10221 * probably not the best implementation yet, so use sparingly. If you don't have a
10222 * reason to prevent playback, use `myPlayer.one('play');` instead.
10224 * @event Player#firstplay
10225 * @type {EventTarget~Event}
10227 this.trigger('firstplay');
10231 * Retrigger the `pause` event that was triggered by the {@link Tech}.
10233 * @fires Player#pause
10234 * @listens Tech#pause
10239 Player.prototype.handleTechPause_ = function handleTechPause_() {
10240 this.removeClass('vjs-playing');
10241 this.addClass('vjs-paused');
10243 * Fired whenever the media has been paused
10245 * @event Player#pause
10246 * @type {EventTarget~Event}
10248 this.trigger('pause');
10252 * Retrigger the `ended` event that was triggered by the {@link Tech}.
10254 * @fires Player#ended
10255 * @listens Tech#ended
10260 Player.prototype.handleTechEnded_ = function handleTechEnded_() {
10261 this.addClass('vjs-ended');
10262 if (this.options_.loop) {
10263 this.currentTime(0);
10265 } else if (!this.paused()) {
10270 * Fired when the end of the media resource is reached (currentTime == duration)
10272 * @event Player#ended
10273 * @type {EventTarget~Event}
10275 this.trigger('ended');
10279 * Fired when the duration of the media resource is first known or changed
10281 * @listens Tech#durationchange
10286 Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() {
10287 this.duration(this.techGet_('duration'));
10291 * Handle a click on the media element to play/pause
10293 * @param {EventTarget~Event} event
10294 * the event that caused this function to trigger
10296 * @listens Tech#mousedown
10301 Player.prototype.handleTechClick_ = function handleTechClick_(event) {
10302 // We're using mousedown to detect clicks thanks to Flash, but mousedown
10303 // will also be triggered with right-clicks, so we need to prevent that
10304 if (event.button !== 0) {
10308 // When controls are disabled a click should not toggle playback because
10309 // the click is considered a control
10310 if (this.controls()) {
10311 if (this.paused()) {
10320 * Handle a tap on the media element. It will toggle the user
10321 * activity state, which hides and shows the controls.
10323 * @listens Tech#tap
10328 Player.prototype.handleTechTap_ = function handleTechTap_() {
10329 this.userActive(!this.userActive());
10333 * Handle touch to start
10335 * @listens Tech#touchstart
10340 Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() {
10341 this.userWasActive = this.userActive();
10345 * Handle touch to move
10347 * @listens Tech#touchmove
10352 Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() {
10353 if (this.userWasActive) {
10354 this.reportUserActivity();
10359 * Handle touch to end
10361 * @param {EventTarget~Event} event
10362 * the touchend event that triggered
10365 * @listens Tech#touchend
10370 Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) {
10371 // Stop the mouse events from also happening
10372 event.preventDefault();
10376 * Fired when the player switches in or out of fullscreen mode
10379 * @listens Player#fullscreenchange
10383 Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() {
10384 if (this.isFullscreen()) {
10385 this.addClass('vjs-fullscreen');
10387 this.removeClass('vjs-fullscreen');
10392 * native click events on the SWF aren't triggered on IE11, Win8.1RT
10393 * use stageclick events triggered from inside the SWF instead
10396 * @listens stageclick
10400 Player.prototype.handleStageClick_ = function handleStageClick_() {
10401 this.reportUserActivity();
10405 * Handle Tech Fullscreen Change
10407 * @param {EventTarget~Event} event
10408 * the fullscreenchange event that triggered this function
10410 * @param {Object} data
10411 * the data that was sent with the event
10414 * @listens Tech#fullscreenchange
10415 * @fires Player#fullscreenchange
10419 Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) {
10421 this.isFullscreen(data.isFullscreen);
10424 * Fired when going in and out of fullscreen.
10426 * @event Player#fullscreenchange
10427 * @type {EventTarget~Event}
10429 this.trigger('fullscreenchange');
10433 * Fires when an error occurred during the loading of an audio/video.
10436 * @listens Tech#error
10440 Player.prototype.handleTechError_ = function handleTechError_() {
10441 var error = this.tech_.error();
10447 * Retrigger the `textdata` event that was triggered by the {@link Tech}.
10449 * @fires Player#textdata
10450 * @listens Tech#textdata
10455 Player.prototype.handleTechTextData_ = function handleTechTextData_() {
10458 if (arguments.length > 1) {
10459 data = arguments[1];
10463 * Fires when we get a textdata event from tech
10465 * @event Player#textdata
10466 * @type {EventTarget~Event}
10468 this.trigger('textdata', data);
10472 * Get object for cached values.
10475 * get the current object cache
10479 Player.prototype.getCache = function getCache() {
10480 return this.cache_;
10484 * Pass values to the playback tech
10486 * @param {string} [method]
10487 * the method to call
10489 * @param {Object} arg
10490 * the argument to pass
10496 Player.prototype.techCall_ = function techCall_(method, arg) {
10497 // If it's not ready yet, call method when it is
10498 if (this.tech_ && !this.tech_.isReady_) {
10499 this.tech_.ready(function () {
10503 // Otherwise call method now
10507 this.tech_[method](arg);
10510 (0, _log2['default'])(e);
10517 * Get calls can't wait for the tech, and sometimes don't need to.
10519 * @param {string} method
10522 * @return {Function|undefined}
10523 * the method or undefined
10529 Player.prototype.techGet_ = function techGet_(method) {
10530 if (this.tech_ && this.tech_.isReady_) {
10532 // Flash likes to die and reload when you hide or reposition it.
10533 // In these cases the object methods go away and we get errors.
10534 // When that happens we'll catch the errors and inform tech that it's not ready any more.
10536 return this.tech_[method]();
10538 // When building additional tech libs, an expected method may not be defined yet
10539 if (this.tech_[method] === undefined) {
10540 (0, _log2['default'])('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e);
10542 // When a method isn't available on the object it throws a TypeError
10543 } else if (e.name === 'TypeError') {
10544 (0, _log2['default'])('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e);
10545 this.tech_.isReady_ = false;
10547 (0, _log2['default'])(e);
10557 * start media playback
10560 * A reference to the player object this function was called on
10564 Player.prototype.play = function play() {
10565 // Only calls the tech's play if we already have a src loaded
10566 if (this.src() || this.currentSrc()) {
10567 this.techCall_('play');
10569 this.tech_.one('loadstart', function () {
10578 * Pause the video playback
10581 * A reference to the player object this function was called on
10585 Player.prototype.pause = function pause() {
10586 this.techCall_('pause');
10591 * Check if the player is paused or has yet to play
10593 * @return {boolean}
10594 * - false: if the media is currently playing
10595 * - true: if media is not currently playing
10599 Player.prototype.paused = function paused() {
10600 // The initial state of paused should be true (in Safari it's actually false)
10601 return this.techGet_('paused') === false ? false : true;
10605 * Returns whether or not the user is "scrubbing". Scrubbing is
10606 * when the user has clicked the progress bar handle and is
10607 * dragging it along the progress bar.
10609 * @param {boolean} [isScrubbing]
10610 * wether the user is or is not scrubbing
10612 * @return {boolean|Player}
10613 * A instance of the player that called this function when setting,
10614 * and the value of scrubbing when getting
10618 Player.prototype.scrubbing = function scrubbing(isScrubbing) {
10619 if (isScrubbing !== undefined) {
10620 this.scrubbing_ = !!isScrubbing;
10623 this.addClass('vjs-scrubbing');
10625 this.removeClass('vjs-scrubbing');
10631 return this.scrubbing_;
10635 * Get or set the current time (in seconds)
10637 * @param {number|string} [seconds]
10638 * The time to seek to in seconds
10640 * @return {Player|number}
10641 * - the current time in seconds when getting
10642 * - a reference to the current player object when setting
10646 Player.prototype.currentTime = function currentTime(seconds) {
10647 if (seconds !== undefined) {
10649 this.techCall_('setCurrentTime', seconds);
10654 // cache last currentTime and return. default to 0 seconds
10656 // Caching the currentTime is meant to prevent a massive amount of reads on the tech's
10657 // currentTime when scrubbing, but may not provide much performance benefit afterall.
10658 // Should be tested. Also something has to read the actual current time or the cache will
10659 // never get updated.
10660 this.cache_.currentTime = this.techGet_('currentTime') || 0;
10661 return this.cache_.currentTime;
10665 * Normally gets the length in time of the video in seconds;
10666 * in all but the rarest use cases an argument will NOT be passed to the method
10668 * > **NOTE**: The video must have started loading before the duration can be
10669 * known, and in the case of Flash, may not be known until the video starts
10672 * @fires Player#durationchange
10674 * @param {number} [seconds]
10675 * The duration of the video to set in seconds
10677 * @return {number|Player}
10678 * - The duration of the video in seconds when getting
10679 * - A reference to the player that called this function
10684 Player.prototype.duration = function duration(seconds) {
10685 if (seconds === undefined) {
10686 return this.cache_.duration || 0;
10689 seconds = parseFloat(seconds) || 0;
10691 // Standardize on Inifity for signaling video is live
10693 seconds = Infinity;
10696 if (seconds !== this.cache_.duration) {
10697 // Cache the last set value for optimized scrubbing (esp. Flash)
10698 this.cache_.duration = seconds;
10700 if (seconds === Infinity) {
10701 this.addClass('vjs-live');
10703 this.removeClass('vjs-live');
10706 * @event Player#durationchange
10707 * @type {EventTarget~Event}
10709 this.trigger('durationchange');
10716 * Calculates how much time is left in the video. Not part
10717 * of the native video API.
10720 * The time remaining in seconds
10724 Player.prototype.remainingTime = function remainingTime() {
10725 return this.duration() - this.currentTime();
10729 // Kind of like an array of portions of the video that have been downloaded.
10732 * Get a TimeRange object with an array of the times of the video
10733 * that have been downloaded. If you just want the percent of the
10734 * video that's been downloaded, use bufferedPercent.
10736 * @see [Buffered Spec]{@link http://dev.w3.org/html5/spec/video.html#dom-media-buffered}
10738 * @return {TimeRange}
10739 * A mock TimeRange object (following HTML spec)
10743 Player.prototype.buffered = function buffered() {
10744 var buffered = this.techGet_('buffered');
10746 if (!buffered || !buffered.length) {
10747 buffered = (0, _timeRanges.createTimeRange)(0, 0);
10754 * Get the percent (as a decimal) of the video that's been downloaded.
10755 * This method is not a part of the native HTML video API.
10758 * A decimal between 0 and 1 representing the percent
10759 * that is bufferred 0 being 0% and 1 being 100%
10763 Player.prototype.bufferedPercent = function bufferedPercent() {
10764 return (0, _buffer.bufferedPercent)(this.buffered(), this.duration());
10768 * Get the ending time of the last buffered time range
10769 * This is used in the progress bar to encapsulate all time ranges.
10772 * The end of the last buffered time range
10776 Player.prototype.bufferedEnd = function bufferedEnd() {
10777 var buffered = this.buffered();
10778 var duration = this.duration();
10779 var end = buffered.end(buffered.length - 1);
10781 if (end > duration) {
10789 * Get or set the current volume of the media
10791 * @param {number} [percentAsDecimal]
10792 * The new volume as a decimal percent:
10793 * - 0 is muted/0%/off
10794 * - 1.0 is 100%/full
10795 * - 0.5 is half volume or 50%
10797 * @return {Player|number}
10798 * a reference to the calling player when setting and the
10799 * current volume as a percent when getting
10803 Player.prototype.volume = function volume(percentAsDecimal) {
10806 if (percentAsDecimal !== undefined) {
10807 // Force value to between 0 and 1
10808 vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal)));
10809 this.cache_.volume = vol;
10810 this.techCall_('setVolume', vol);
10815 // Default to 1 when returning current volume.
10816 vol = parseFloat(this.techGet_('volume'));
10817 return isNaN(vol) ? 1 : vol;
10821 * Get the current muted state, or turn mute on or off
10823 * @param {boolean} [muted]
10825 * - false to unmute
10827 * @return {boolean|Player}
10828 * - true if mute is on and getting
10829 * - false if mute is off and getting
10830 * - A reference to the current player when setting
10834 Player.prototype.muted = function muted(_muted) {
10835 if (_muted !== undefined) {
10836 this.techCall_('setMuted', _muted);
10839 return this.techGet_('muted') || false;
10843 * Check if current tech can support native fullscreen
10844 * (e.g. with built in controls like iOS, so not our flash swf)
10846 * @return {boolean}
10847 * if native fullscreen is supported
10851 Player.prototype.supportsFullScreen = function supportsFullScreen() {
10852 return this.techGet_('supportsFullScreen') || false;
10856 * Check if the player is in fullscreen mode or tell the player that it
10857 * is or is not in fullscreen mode.
10859 * > NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official
10860 * property and instead document.fullscreenElement is used. But isFullscreen is
10861 * still a valuable property for internal player workings.
10863 * @param {boolean} [isFS]
10864 * Set the players current fullscreen state
10866 * @return {boolean|Player}
10867 * - true if fullscreen is on and getting
10868 * - false if fullscreen is off and getting
10869 * - A reference to the current player when setting
10873 Player.prototype.isFullscreen = function isFullscreen(isFS) {
10874 if (isFS !== undefined) {
10875 this.isFullscreen_ = !!isFS;
10878 return !!this.isFullscreen_;
10882 * Increase the size of the video to full screen
10883 * In some browsers, full screen is not supported natively, so it enters
10884 * "full window mode", where the video fills the browser window.
10885 * In browsers and devices that support native full screen, sometimes the
10886 * browser's default controls will be shown, and not the Video.js custom skin.
10887 * This includes most mobile devices (iOS, Android) and older versions of
10890 * @fires Player#fullscreenchange
10892 * A reference to the current player
10896 Player.prototype.requestFullscreen = function requestFullscreen() {
10897 var fsApi = _fullscreenApi2['default'];
10899 this.isFullscreen(true);
10901 if (fsApi.requestFullscreen) {
10902 // the browser supports going fullscreen at the element level so we can
10903 // take the controls fullscreen as well as the video
10905 // Trigger fullscreenchange event after change
10906 // We have to specifically add this each time, and remove
10907 // when canceling fullscreen. Otherwise if there's multiple
10908 // players on a page, they would all be reacting to the same fullscreen
10910 Events.on(_document2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) {
10911 this.isFullscreen(_document2['default'][fsApi.fullscreenElement]);
10913 // If cancelling fullscreen, remove event listener.
10914 if (this.isFullscreen() === false) {
10915 Events.off(_document2['default'], fsApi.fullscreenchange, documentFullscreenChange);
10918 * @event Player#fullscreenchange
10919 * @type {EventTarget~Event}
10921 this.trigger('fullscreenchange');
10924 this.el_[fsApi.requestFullscreen]();
10925 } else if (this.tech_.supportsFullScreen()) {
10926 // we can't take the video.js controls fullscreen but we can go fullscreen
10927 // with native controls
10928 this.techCall_('enterFullScreen');
10930 // fullscreen isn't supported so we'll just stretch the video element to
10931 // fill the viewport
10932 this.enterFullWindow();
10934 * @event Player#fullscreenchange
10935 * @type {EventTarget~Event}
10937 this.trigger('fullscreenchange');
10944 * Return the video to its normal size after having been in full screen mode
10946 * @fires Player#fullscreenchange
10949 * A reference to the current player
10953 Player.prototype.exitFullscreen = function exitFullscreen() {
10954 var fsApi = _fullscreenApi2['default'];
10956 this.isFullscreen(false);
10958 // Check for browser element fullscreen support
10959 if (fsApi.requestFullscreen) {
10960 _document2['default'][fsApi.exitFullscreen]();
10961 } else if (this.tech_.supportsFullScreen()) {
10962 this.techCall_('exitFullScreen');
10964 this.exitFullWindow();
10966 * @event Player#fullscreenchange
10967 * @type {EventTarget~Event}
10969 this.trigger('fullscreenchange');
10976 * When fullscreen isn't supported we can stretch the
10977 * video container to as wide as the browser will let us.
10979 * @fires Player#enterFullWindow
10983 Player.prototype.enterFullWindow = function enterFullWindow() {
10984 this.isFullWindow = true;
10986 // Storing original doc overflow value to return to when fullscreen is off
10987 this.docOrigOverflow = _document2['default'].documentElement.style.overflow;
10989 // Add listener for esc key to exit fullscreen
10990 Events.on(_document2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey));
10992 // Hide any scroll bars
10993 _document2['default'].documentElement.style.overflow = 'hidden';
10995 // Apply fullscreen styles
10996 Dom.addElClass(_document2['default'].body, 'vjs-full-window');
10999 * @event Player#enterFullWindow
11000 * @type {EventTarget~Event}
11002 this.trigger('enterFullWindow');
11006 * Check for call to either exit full window or
11007 * full screen on ESC key
11009 * @param {string} event
11010 * Event to check for key press
11014 Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) {
11015 if (event.keyCode === 27) {
11016 if (this.isFullscreen() === true) {
11017 this.exitFullscreen();
11019 this.exitFullWindow();
11027 * @fires Player#exitFullWindow
11031 Player.prototype.exitFullWindow = function exitFullWindow() {
11032 this.isFullWindow = false;
11033 Events.off(_document2['default'], 'keydown', this.fullWindowOnEscKey);
11035 // Unhide scroll bars.
11036 _document2['default'].documentElement.style.overflow = this.docOrigOverflow;
11038 // Remove fullscreen styles
11039 Dom.removeElClass(_document2['default'].body, 'vjs-full-window');
11041 // Resize the box, controller, and poster to original sizes
11042 // this.positionAll();
11044 * @event Player#exitFullWindow
11045 * @type {EventTarget~Event}
11047 this.trigger('exitFullWindow');
11051 * Check whether the player can play a given mimetype
11053 * @see https://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-navigator-canplaytype
11055 * @param {string} type
11056 * The mimetype to check
11059 * 'probably', 'maybe', or '' (empty string)
11063 Player.prototype.canPlayType = function canPlayType(type) {
11066 // Loop through each playback technology in the options order
11067 for (var i = 0, j = this.options_.techOrder; i < j.length; i++) {
11068 var techName = (0, _toTitleCase2['default'])(j[i]);
11069 var tech = _tech2['default'].getTech(techName);
11071 // Support old behavior of techs being registered as components.
11072 // Remove once that deprecated behavior is removed.
11074 tech = _component2['default'].getComponent(techName);
11077 // Check if the current tech is defined before continuing
11079 _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
11083 // Check if the browser supports this technology
11084 if (tech.isSupported()) {
11085 can = tech.canPlayType(type);
11097 * Select source based on tech-order or source-order
11098 * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise,
11099 * defaults to tech-order selection
11101 * @param {Array} sources
11102 * The sources for a media asset
11104 * @return {Object|boolean}
11105 * Object of source and tech order or false
11109 Player.prototype.selectSource = function selectSource(sources) {
11112 // Get only the techs specified in `techOrder` that exist and are supported by the
11113 // current platform
11114 var techs = this.options_.techOrder.map(_toTitleCase2['default']).map(function (techName) {
11115 // `Component.getComponent(...)` is for support of old behavior of techs
11116 // being registered as components.
11117 // Remove once that deprecated behavior is removed.
11118 return [techName, _tech2['default'].getTech(techName) || _component2['default'].getComponent(techName)];
11119 }).filter(function (_ref) {
11120 var techName = _ref[0],
11123 // Check if the current tech is defined before continuing
11125 // Check if the browser supports this technology
11126 return tech.isSupported();
11129 _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
11133 // Iterate over each `innerArray` element once per `outerArray` element and execute
11134 // `tester` with both. If `tester` returns a non-falsy value, exit early and return
11136 var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) {
11137 var found = void 0;
11139 outerArray.some(function (outerChoice) {
11140 return innerArray.some(function (innerChoice) {
11141 found = tester(outerChoice, innerChoice);
11152 var foundSourceAndTech = void 0;
11153 var flip = function flip(fn) {
11154 return function (a, b) {
11158 var finder = function finder(_ref2, source) {
11159 var techName = _ref2[0],
11162 if (tech.canPlaySource(source, _this4.options_[techName.toLowerCase()])) {
11163 return { source: source, tech: techName };
11167 // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources
11168 // to select from them based on their priority.
11169 if (this.options_.sourceOrder) {
11170 // Source-first ordering
11171 foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder));
11173 // Tech-first ordering
11174 foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder);
11177 return foundSourceAndTech || false;
11181 * The source function updates the video source
11182 * There are three types of variables you can pass as the argument.
11183 * **URL string**: A URL to the the video file. Use this method if you are sure
11184 * the current playback technology (HTML5/Flash) can support the source you
11185 * provide. Currently only MP4 files can be used in both HTML5 and Flash.
11187 * @param {Tech~SourceObject|Tech~SourceObject[]} [source]
11188 * One SourceObject or an array of SourceObjects
11190 * @return {string|Player}
11191 * - The current video source when getting
11192 * - The player when setting
11196 Player.prototype.src = function src(source) {
11197 if (source === undefined) {
11198 return this.techGet_('src');
11201 var currentTech = _tech2['default'].getTech(this.techName_);
11203 // Support old behavior of techs being registered as components.
11204 // Remove once that deprecated behavior is removed.
11205 if (!currentTech) {
11206 currentTech = _component2['default'].getComponent(this.techName_);
11209 // case: Array of source objects to choose from and pick the best to play
11210 if (Array.isArray(source)) {
11211 this.sourceList_(source);
11213 // case: URL String (http://myvideo...)
11214 } else if (typeof source === 'string') {
11215 // create a source object from the string
11216 this.src({ src: source });
11218 // case: Source object { src: '', type: '' ... }
11219 } else if (source instanceof Object) {
11220 // check if the source has a type and the loaded tech cannot play the source
11221 // if there's no type we'll just try the current tech
11222 if (source.type && !currentTech.canPlaySource(source, this.options_[this.techName_.toLowerCase()])) {
11223 // create a source list with the current source and send through
11224 // the tech loop to check for a compatible technology
11225 this.sourceList_([source]);
11227 this.cache_.sources = null;
11228 this.cache_.source = source;
11229 this.cache_.src = source.src;
11231 this.currentType_ = source.type || '';
11233 // wait until the tech is ready to set the source
11234 this.ready(function () {
11236 // The setSource tech method was added with source handlers
11237 // so older techs won't support it
11238 // We need to check the direct prototype for the case where subclasses
11239 // of the tech do not support source handlers
11240 if (currentTech.prototype.hasOwnProperty('setSource')) {
11241 this.techCall_('setSource', source);
11243 this.techCall_('src', source.src);
11246 if (this.options_.preload === 'auto') {
11250 if (this.options_.autoplay) {
11254 // Set the source synchronously if possible (#2326)
11263 * Handle an array of source objects
11265 * @param {Tech~SourceObject[]} sources
11266 * Array of source objects
11272 Player.prototype.sourceList_ = function sourceList_(sources) {
11273 var sourceTech = this.selectSource(sources);
11276 if (sourceTech.tech === this.techName_) {
11277 // if this technology is already loaded, set the source
11278 this.src(sourceTech.source);
11280 // load this technology with the chosen source
11281 this.loadTech_(sourceTech.tech, sourceTech.source);
11284 this.cache_.sources = sources;
11286 // We need to wrap this in a timeout to give folks a chance to add error event handlers
11287 this.setTimeout(function () {
11288 this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) });
11291 // we could not find an appropriate tech, but let's still notify the delegate that this is it
11292 // this needs a better comment about why this is needed
11293 this.triggerReady();
11298 * Begin loading the src data.
11301 * A reference to the player
11305 Player.prototype.load = function load() {
11306 this.techCall_('load');
11311 * Reset the player. Loads the first tech in the techOrder,
11312 * and calls `reset` on the tech`.
11315 * A reference to the player
11319 Player.prototype.reset = function reset() {
11320 this.loadTech_((0, _toTitleCase2['default'])(this.options_.techOrder[0]), null);
11321 this.techCall_('reset');
11326 * Returns all of the current source objects.
11328 * @return {Tech~SourceObject[]}
11329 * The current source objects
11333 Player.prototype.currentSources = function currentSources() {
11334 var source = this.currentSource();
11337 // assume `{}` or `{ src }`
11338 if (Object.keys(source).length !== 0) {
11339 sources.push(source);
11342 return this.cache_.sources || sources;
11346 * Returns the current source object.
11348 * @return {Tech~SourceObject}
11349 * The current source object
11353 Player.prototype.currentSource = function currentSource() {
11355 var src = this.currentSrc();
11361 return this.cache_.source || source;
11365 * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4
11366 * Can be used in conjuction with `currentType` to assist in rebuilding the current source object.
11369 * The current source
11373 Player.prototype.currentSrc = function currentSrc() {
11374 return this.techGet_('currentSrc') || this.cache_.src || '';
11378 * Get the current source type e.g. video/mp4
11379 * This can allow you rebuild the current source object so that you could load the same
11380 * source and tech later
11383 * The source MIME type
11387 Player.prototype.currentType = function currentType() {
11388 return this.currentType_ || '';
11392 * Get or set the preload attribute
11394 * @param {boolean} [value]
11395 * - true means that we should preload
11396 * - false maens that we should not preload
11398 * @return {string|Player}
11399 * - the preload attribute value when getting
11400 * - the player when setting
11404 Player.prototype.preload = function preload(value) {
11405 if (value !== undefined) {
11406 this.techCall_('setPreload', value);
11407 this.options_.preload = value;
11410 return this.techGet_('preload');
11414 * Get or set the autoplay attribute.
11416 * @param {boolean} [value]
11417 * - true means that we should autoplay
11418 * - false maens that we should not autoplay
11420 * @return {string|Player}
11421 * - the current value of autoplay
11422 * - the player when setting
11426 Player.prototype.autoplay = function autoplay(value) {
11427 if (value !== undefined) {
11428 this.techCall_('setAutoplay', value);
11429 this.options_.autoplay = value;
11432 return this.techGet_('autoplay', value);
11436 * Get or set the loop attribute on the video element.
11438 * @param {boolean} [value]
11439 * - true means that we should loop the video
11440 * - false means that we should not loop the video
11442 * @return {string|Player}
11443 * - the current value of loop when getting
11444 * - the player when setting
11448 Player.prototype.loop = function loop(value) {
11449 if (value !== undefined) {
11450 this.techCall_('setLoop', value);
11451 this.options_.loop = value;
11454 return this.techGet_('loop');
11458 * Get or set the poster image source url
11460 * @fires Player#posterchange
11462 * @param {string} [src]
11463 * Poster image source URL
11465 * @return {string|Player}
11466 * - the current value of poster when getting
11467 * - the player when setting
11471 Player.prototype.poster = function poster(src) {
11472 if (src === undefined) {
11473 return this.poster_;
11476 // The correct way to remove a poster is to set as an empty string
11477 // other falsey values will throw errors
11482 // update the internal poster variable
11483 this.poster_ = src;
11485 // update the tech's poster
11486 this.techCall_('setPoster', src);
11488 // alert components that the poster has been set
11490 * This event fires when the poster image is changed on the player.
11492 * @event Player#posterchange
11493 * @type {EventTarget~Event}
11495 this.trigger('posterchange');
11501 * Some techs (e.g. YouTube) can provide a poster source in an
11502 * asynchronous way. We want the poster component to use this
11503 * poster source so that it covers up the tech's controls.
11504 * (YouTube's play button). However we only want to use this
11505 * soruce if the player user hasn't set a poster through
11508 * @fires Player#posterchange
11509 * @listens Tech#posterchange
11514 Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() {
11515 if (!this.poster_ && this.tech_ && this.tech_.poster) {
11516 this.poster_ = this.tech_.poster() || '';
11518 // Let components know the poster has changed
11519 this.trigger('posterchange');
11524 * Get or set whether or not the controls are showing.
11526 * @fires Player#controlsenabled
11528 * @param {boolean} [bool]
11529 * - true to turn controls on
11530 * - false to turn controls off
11532 * @return {boolean|Player}
11533 * - the current value of controls when getting
11534 * - the player when setting
11538 Player.prototype.controls = function controls(bool) {
11539 if (bool !== undefined) {
11542 // Don't trigger a change event unless it actually changed
11543 if (this.controls_ !== bool) {
11544 this.controls_ = bool;
11546 if (this.usingNativeControls()) {
11547 this.techCall_('setControls', bool);
11551 this.removeClass('vjs-controls-disabled');
11552 this.addClass('vjs-controls-enabled');
11554 * @event Player#controlsenabled
11555 * @type {EventTarget~Event}
11557 this.trigger('controlsenabled');
11559 if (!this.usingNativeControls()) {
11560 this.addTechControlsListeners_();
11563 this.removeClass('vjs-controls-enabled');
11564 this.addClass('vjs-controls-disabled');
11566 * @event Player#controlsdisabled
11567 * @type {EventTarget~Event}
11569 this.trigger('controlsdisabled');
11571 if (!this.usingNativeControls()) {
11572 this.removeTechControlsListeners_();
11578 return !!this.controls_;
11582 * Toggle native controls on/off. Native controls are the controls built into
11583 * devices (e.g. default iPhone controls), Flash, or other techs
11584 * (e.g. Vimeo Controls)
11585 * **This should only be set by the current tech, because only the tech knows
11586 * if it can support native controls**
11588 * @fires Player#usingnativecontrols
11589 * @fires Player#usingcustomcontrols
11591 * @param {boolean} [bool]
11592 * - true to turn native controls on
11593 * - false to turn native controls off
11595 * @return {boolean|Player}
11596 * - the current value of native controls when getting
11597 * - the player when setting
11601 Player.prototype.usingNativeControls = function usingNativeControls(bool) {
11602 if (bool !== undefined) {
11605 // Don't trigger a change event unless it actually changed
11606 if (this.usingNativeControls_ !== bool) {
11607 this.usingNativeControls_ = bool;
11609 this.addClass('vjs-using-native-controls');
11612 * player is using the native device controls
11614 * @event Player#usingnativecontrols
11615 * @type {EventTarget~Event}
11617 this.trigger('usingnativecontrols');
11619 this.removeClass('vjs-using-native-controls');
11622 * player is using the custom HTML controls
11624 * @event Player#usingcustomcontrols
11625 * @type {EventTarget~Event}
11627 this.trigger('usingcustomcontrols');
11632 return !!this.usingNativeControls_;
11636 * Set or get the current MediaError
11638 * @fires Player#error
11640 * @param {MediaError|string|number} [err]
11641 * A MediaError or a string/number to be turned
11642 * into a MediaError
11644 * @return {MediaError|null|Player}
11645 * - The current MediaError when getting (or null)
11646 * - The player when setting
11650 Player.prototype.error = function error(err) {
11651 if (err === undefined) {
11652 return this.error_ || null;
11655 // restoring to default
11656 if (err === null) {
11658 this.removeClass('vjs-error');
11659 if (this.errorDisplay) {
11660 this.errorDisplay.close();
11665 this.error_ = new _mediaError2['default'](err);
11667 // add the vjs-error classname to the player
11668 this.addClass('vjs-error');
11670 // log the name of the error type and any message
11671 // ie8 just logs "[object object]" if you just log the error object
11672 _log2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaError2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_);
11675 * @event Player#error
11676 * @type {EventTarget~Event}
11678 this.trigger('error');
11684 * Report user activity
11686 * @param {Object} event
11691 Player.prototype.reportUserActivity = function reportUserActivity(event) {
11692 this.userActivity_ = true;
11696 * Get/set if user is active
11698 * @fires Player#useractive
11699 * @fires Player#userinactive
11701 * @param {boolean} [bool]
11702 * - true if the user is active
11703 * - false if the user is inactive
11704 * @return {boolean|Player}
11705 * - the current value of userActive when getting
11706 * - the player when setting
11710 Player.prototype.userActive = function userActive(bool) {
11711 if (bool !== undefined) {
11713 if (bool !== this.userActive_) {
11714 this.userActive_ = bool;
11716 // If the user was inactive and is now active we want to reset the
11717 // inactivity timer
11718 this.userActivity_ = true;
11719 this.removeClass('vjs-user-inactive');
11720 this.addClass('vjs-user-active');
11722 * @event Player#useractive
11723 * @type {EventTarget~Event}
11725 this.trigger('useractive');
11727 // We're switching the state to inactive manually, so erase any other
11729 this.userActivity_ = false;
11731 // Chrome/Safari/IE have bugs where when you change the cursor it can
11732 // trigger a mousemove event. This causes an issue when you're hiding
11733 // the cursor when the user is inactive, and a mousemove signals user
11734 // activity. Making it impossible to go into inactive mode. Specifically
11735 // this happens in fullscreen when we really need to hide the cursor.
11737 // When this gets resolved in ALL browsers it can be removed
11738 // https://code.google.com/p/chromium/issues/detail?id=103041
11740 this.tech_.one('mousemove', function (e) {
11741 e.stopPropagation();
11742 e.preventDefault();
11746 this.removeClass('vjs-user-active');
11747 this.addClass('vjs-user-inactive');
11749 * @event Player#userinactive
11750 * @type {EventTarget~Event}
11752 this.trigger('userinactive');
11757 return this.userActive_;
11761 * Listen for user activity based on timeout value
11767 Player.prototype.listenForUserActivity_ = function listenForUserActivity_() {
11768 var mouseInProgress = void 0;
11769 var lastMoveX = void 0;
11770 var lastMoveY = void 0;
11771 var handleActivity = Fn.bind(this, this.reportUserActivity);
11773 var handleMouseMove = function handleMouseMove(e) {
11774 // #1068 - Prevent mousemove spamming
11775 // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970
11776 if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) {
11777 lastMoveX = e.screenX;
11778 lastMoveY = e.screenY;
11783 var handleMouseDown = function handleMouseDown() {
11785 // For as long as the they are touching the device or have their mouse down,
11786 // we consider them active even if they're not moving their finger or mouse.
11787 // So we want to continue to update that they are active
11788 this.clearInterval(mouseInProgress);
11789 // Setting userActivity=true now and setting the interval to the same time
11790 // as the activityCheck interval (250) should ensure we never miss the
11791 // next activityCheck
11792 mouseInProgress = this.setInterval(handleActivity, 250);
11795 var handleMouseUp = function handleMouseUp(event) {
11797 // Stop the interval that maintains activity if the mouse/touch is down
11798 this.clearInterval(mouseInProgress);
11801 // Any mouse movement will be considered user activity
11802 this.on('mousedown', handleMouseDown);
11803 this.on('mousemove', handleMouseMove);
11804 this.on('mouseup', handleMouseUp);
11806 // Listen for keyboard navigation
11807 // Shouldn't need to use inProgress interval because of key repeat
11808 this.on('keydown', handleActivity);
11809 this.on('keyup', handleActivity);
11811 // Run an interval every 250 milliseconds instead of stuffing everything into
11812 // the mousemove/touchmove function itself, to prevent performance degradation.
11813 // `this.reportUserActivity` simply sets this.userActivity_ to true, which
11814 // then gets picked up by this loop
11815 // http://ejohn.org/blog/learning-from-twitter/
11816 var inactivityTimeout = void 0;
11818 this.setInterval(function () {
11819 // Check to see if mouse/touch activity has happened
11820 if (this.userActivity_) {
11821 // Reset the activity tracker
11822 this.userActivity_ = false;
11824 // If the user state was inactive, set the state to active
11825 this.userActive(true);
11827 // Clear any existing inactivity timeout to start the timer over
11828 this.clearTimeout(inactivityTimeout);
11830 var timeout = this.options_.inactivityTimeout;
11833 // In <timeout> milliseconds, if no more activity has occurred the
11834 // user will be considered inactive
11835 inactivityTimeout = this.setTimeout(function () {
11836 // Protect against the case where the inactivityTimeout can trigger just
11837 // before the next user activity is picked up by the activity check loop
11838 // causing a flicker
11839 if (!this.userActivity_) {
11840 this.userActive(false);
11849 * Gets or sets the current playback rate. A playback rate of
11850 * 1.0 represents normal speed and 0.5 would indicate half-speed
11851 * playback, for instance.
11853 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate
11855 * @param {number} [rate]
11856 * New playback rate to set.
11858 * @return {number|Player}
11859 * - The current playback rate when getting or 1.0
11860 * - the player when setting
11864 Player.prototype.playbackRate = function playbackRate(rate) {
11865 if (rate !== undefined) {
11866 this.techCall_('setPlaybackRate', rate);
11870 if (this.tech_ && this.tech_.featuresPlaybackRate) {
11871 return this.techGet_('playbackRate');
11877 * Gets or sets the audio flag
11879 * @param {boolean} bool
11880 * - true signals that this is an audio player
11881 * - false signals that this is not an audio player
11883 * @return {Player|boolean}
11884 * - the current value of isAudio when getting
11885 * - the player if setting
11889 Player.prototype.isAudio = function isAudio(bool) {
11890 if (bool !== undefined) {
11891 this.isAudio_ = !!bool;
11895 return !!this.isAudio_;
11899 * Get the {@link VideoTrackList}
11901 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist
11903 * @return {VideoTrackList}
11904 * the current video track list
11908 Player.prototype.videoTracks = function videoTracks() {
11909 // if we have not yet loadTech_, we create videoTracks_
11910 // these will be passed to the tech during loading
11912 this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default']();
11913 return this.videoTracks_;
11916 return this.tech_.videoTracks();
11920 * Get the {@link AudioTrackList}
11922 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist
11924 * @return {AudioTrackList}
11925 * the current audio track list
11929 Player.prototype.audioTracks = function audioTracks() {
11930 // if we have not yet loadTech_, we create videoTracks_
11931 // these will be passed to the tech during loading
11933 this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default']();
11934 return this.audioTracks_;
11937 return this.tech_.audioTracks();
11941 * Get the {@link TextTrackList}
11943 * Text tracks are tracks of timed text events.
11944 * - Captions: text displayed over the video
11945 * for the hearing impaired
11946 * - Subtitles: text displayed over the video for
11947 * those who don't understand language in the video
11948 * - Chapters: text displayed in a menu allowing the user to jump
11949 * to particular points (chapters) in the video
11950 * - Descriptions: (not yet implemented) audio descriptions that are read back to
11951 * the user by a screen reading device
11953 * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks
11955 * @return {TextTrackList|undefined}
11956 * The current TextTrackList or undefined if
11957 * or undefined if we don't have a tech
11961 Player.prototype.textTracks = function textTracks() {
11962 // cannot use techGet_ directly because it checks to see whether the tech is ready.
11963 // Flash is unlikely to be ready in time but textTracks should still work.
11965 return this.tech_.textTracks();
11970 * Get the "remote" {@link TextTrackList}. Remote Text Tracks
11971 * are tracks that were added to the HTML video element and can
11972 * be removed, whereas normal texttracks cannot be removed.
11975 * @return {TextTrackList|undefined}
11976 * The current remote text track list or undefined
11977 * if we don't have a tech
11981 Player.prototype.remoteTextTracks = function remoteTextTracks() {
11983 return this.tech_.remoteTextTracks();
11988 * Get the "remote" {@link HTMLTrackElementList}.
11989 * This gives the user all of the DOM elements that match up
11990 * with the remote {@link TextTrackList}.
11992 * @return {HTMLTrackElementList}
11993 * The current remote text track list elements
11994 * or undefined if we don't have a tech
11998 Player.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
12000 return this.tech_.remoteTextTrackEls();
12005 * A helper method for adding a {@link TextTrack} to our
12006 * {@link TextTrackList}.
12008 * In addition to the W3C settings we allow adding additional info through options.
12010 * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack
12012 * @param {string} [kind]
12013 * the kind of TextTrack you are adding
12015 * @param {string} [label]
12016 * the label to give the TextTrack label
12018 * @param {string} [language]
12019 * the language to set on the TextTrack
12021 * @return {TextTrack|undefined}
12022 * the TextTrack that was added or undefined
12023 * if there is no tech
12027 Player.prototype.addTextTrack = function addTextTrack(kind, label, language) {
12029 return this.tech_.addTextTrack(kind, label, language);
12034 * Create a remote {@link TextTrack} and an {@link HTMLTrackElement}. It will
12035 * automatically removed from the video element whenever the source changes, unless
12036 * manualCleanup is set to false.
12038 * @param {Object} options
12039 * Options to pass to {@link HTMLTrackElement} during creation. See
12040 * {@link HTMLTrackElement} for object properties that you should use.
12042 * @param {boolean} [manualCleanup=true] if set to false, the TextTrack will be
12044 * @return {HTMLTrackElement}
12045 * the HTMLTrackElement that was created and added
12046 * to the HTMLTrackElementList and the remote
12049 * @deprecated The default value of the "manualCleanup" parameter will default
12050 * to "false" in upcoming versions of Video.js
12054 Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) {
12056 return this.tech_.addRemoteTextTrack(options, manualCleanup);
12061 * Remove a remote {@link TextTrack} from the respective
12062 * {@link TextTrackList} and {@link HTMLTrackElementList}.
12064 * @param {Object} track
12065 * Remote {@link TextTrack} to remove
12067 * @return {undefined}
12068 * does not return anything
12072 Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack() {
12073 var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
12074 _ref3$track = _ref3.track,
12075 track = _ref3$track === undefined ? arguments[0] : _ref3$track;
12077 // destructure the input into an object with a track argument, defaulting to arguments[0]
12078 // default the whole argument to an empty object if nothing was passed in
12081 return this.tech_.removeRemoteTextTrack(track);
12089 * current video width
12093 Player.prototype.videoWidth = function videoWidth() {
12094 return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0;
12101 * current video height
12105 Player.prototype.videoHeight = function videoHeight() {
12106 return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0;
12109 // Methods to add support for
12110 // initialTime: function() { return this.techCall_('initialTime'); },
12111 // startOffsetTime: function() { return this.techCall_('startOffsetTime'); },
12112 // played: function() { return this.techCall_('played'); },
12113 // defaultPlaybackRate: function() { return this.techCall_('defaultPlaybackRate'); },
12114 // defaultMuted: function() { return this.techCall_('defaultMuted'); }
12117 * The player's language code
12118 * NOTE: The language should be set in the player options if you want the
12119 * the controls to be built with a specific language. Changing the lanugage
12120 * later will not update controls text.
12122 * @param {string} [code]
12123 * the language code to set the player to
12125 * @return {string|Player}
12126 * - The current language code when getting
12127 * - A reference to the player when setting
12131 Player.prototype.language = function language(code) {
12132 if (code === undefined) {
12133 return this.language_;
12136 this.language_ = String(code).toLowerCase();
12141 * Get the player's language dictionary
12142 * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time
12143 * Languages specified directly in the player options have precedence
12146 * An array of of supported languages
12150 Player.prototype.languages = function languages() {
12151 return (0, _mergeOptions2['default'])(Player.prototype.options_.languages, this.languages_);
12155 * returns a JavaScript object reperesenting the current track
12156 * information. **DOES not return it as JSON**
12159 * Object representing the current of track info
12163 Player.prototype.toJSON = function toJSON() {
12164 var options = (0, _mergeOptions2['default'])(this.options_);
12165 var tracks = options.tracks;
12167 options.tracks = [];
12169 for (var i = 0; i < tracks.length; i++) {
12170 var track = tracks[i];
12172 // deep merge tracks and null out player so no circular references
12173 track = (0, _mergeOptions2['default'])(track);
12174 track.player = undefined;
12175 options.tracks[i] = track;
12182 * Creates a simple modal dialog (an instance of the {@link ModalDialog}
12183 * component) that immediately overlays the player with arbitrary
12184 * content and removes itself when closed.
12186 * @param {string|Function|Element|Array|null} content
12187 * Same as {@link ModalDialog#content}'s param of the same name.
12188 * The most straight-forward usage is to provide a string or DOM
12191 * @param {Object} [options]
12192 * Extra options which will be passed on to the {@link ModalDialog}.
12194 * @return {ModalDialog}
12195 * the {@link ModalDialog} that was created
12199 Player.prototype.createModal = function createModal(content, options) {
12202 options = options || {};
12203 options.content = content || '';
12205 var modal = new _modalDialog2['default'](this, options);
12207 this.addChild(modal);
12208 modal.on('dispose', function () {
12209 _this5.removeChild(modal);
12212 return modal.open();
12216 * Gets tag settings
12218 * @param {Element} tag
12222 * An object containing all of the settings
12227 Player.getTagSettings = function getTagSettings(tag) {
12228 var baseOptions = {
12233 var tagOptions = Dom.getElAttributes(tag);
12234 var dataSetup = tagOptions['data-setup'];
12236 if (Dom.hasElClass(tag, 'vjs-fluid')) {
12237 tagOptions.fluid = true;
12240 // Check if data-setup attr exists.
12241 if (dataSetup !== null) {
12242 // Parse options JSON
12243 // If empty string, make it a parsable json object.
12244 var _safeParseTuple = (0, _tuple2['default'])(dataSetup || '{}'),
12245 err = _safeParseTuple[0],
12246 data = _safeParseTuple[1];
12249 _log2['default'].error(err);
12251 (0, _obj.assign)(tagOptions, data);
12254 (0, _obj.assign)(baseOptions, tagOptions);
12256 // Get tag children settings
12257 if (tag.hasChildNodes()) {
12258 var children = tag.childNodes;
12260 for (var i = 0, j = children.length; i < j; i++) {
12261 var child = children[i];
12262 // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/
12263 var childName = child.nodeName.toLowerCase();
12265 if (childName === 'source') {
12266 baseOptions.sources.push(Dom.getElAttributes(child));
12267 } else if (childName === 'track') {
12268 baseOptions.tracks.push(Dom.getElAttributes(child));
12273 return baseOptions;
12277 * Determine wether or not flexbox is supported
12279 * @return {boolean}
12280 * - true if flexbox is supported
12281 * - false if flexbox is not supported
12285 Player.prototype.flexNotSupported_ = function flexNotSupported_() {
12286 var elem = _document2['default'].createElement('i');
12288 // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more
12289 // common flex features that we can rely on when checking for flex support.
12290 return !('flexBasis' in elem.style || 'webkitFlexBasis' in elem.style || 'mozFlexBasis' in elem.style || 'msFlexBasis' in elem.style ||
12291 // IE10-specific (2012 flex spec)
12292 'msFlexOrder' in elem.style);
12296 }(_component2['default']);
12299 * Global player list
12305 Player.players = {};
12307 var navigator = _window2['default'].navigator;
12310 * Player instance options, surfaced using options
12311 * options = Player.prototype.options_
12312 * Make changes in options, not here.
12317 Player.prototype.options_ = {
12318 // Default order of fallback technology
12319 techOrder: ['html5', 'flash'],
12320 // techOrder: ['flash','html5'],
12325 // defaultVolume: 0.85,
12326 defaultVolume: 0.00,
12328 // default inactivity timeout
12329 inactivityTimeout: 2000,
12331 // default playback rates
12333 // Add playback rate selection by adding rates
12334 // 'playbackRates': [0.5, 1, 1.5, 2],
12336 // Included control sets
12337 children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'],
12339 language: navigator && (navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language) || 'en',
12341 // locales and their language translations
12344 // Default message to show when a video cannot be played.
12345 notSupportedMessage: 'No compatible source was found for this media.'
12350 * Returns whether or not the player is in the "ended" state.
12352 * @return {Boolean} True if the player is in the ended state, false if not.
12353 * @method Player#ended
12357 * Returns whether or not the player is in the "seeking" state.
12359 * @return {Boolean} True if the player is in the seeking state, false if not.
12360 * @method Player#seeking
12364 * Returns the TimeRanges of the media that are currently available
12367 * @return {TimeRanges} the seekable intervals of the media timeline
12368 * @method Player#seekable
12372 * Returns the current state of network activity for the element, from
12373 * the codes in the list below.
12374 * - NETWORK_EMPTY (numeric value 0)
12375 * The element has not yet been initialised. All attributes are in
12376 * their initial states.
12377 * - NETWORK_IDLE (numeric value 1)
12378 * The element's resource selection algorithm is active and has
12379 * selected a resource, but it is not actually using the network at
12381 * - NETWORK_LOADING (numeric value 2)
12382 * The user agent is actively trying to download data.
12383 * - NETWORK_NO_SOURCE (numeric value 3)
12384 * The element's resource selection algorithm is active, but it has
12385 * not yet found a resource to use.
12387 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states
12388 * @return {number} the current network activity state
12389 * @method Player#networkState
12393 * Returns a value that expresses the current state of the element
12394 * with respect to rendering the current playback position, from the
12395 * codes in the list below.
12396 * - HAVE_NOTHING (numeric value 0)
12397 * No information regarding the media resource is available.
12398 * - HAVE_METADATA (numeric value 1)
12399 * Enough of the resource has been obtained that the duration of the
12400 * resource is available.
12401 * - HAVE_CURRENT_DATA (numeric value 2)
12402 * Data for the immediate current playback position is available.
12403 * - HAVE_FUTURE_DATA (numeric value 3)
12404 * Data for the immediate current playback position is available, as
12405 * well as enough data for the user agent to advance the current
12406 * playback position in the direction of playback.
12407 * - HAVE_ENOUGH_DATA (numeric value 4)
12408 * The user agent estimates that enough data is available for
12409 * playback to proceed uninterrupted.
12411 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate
12412 * @return {number} the current playback rendering state
12413 * @method Player#readyState
12415 'readyState'].forEach(function (fn) {
12416 Player.prototype[fn] = function () {
12417 return this.techGet_(fn);
12421 TECH_EVENTS_RETRIGGER.forEach(function (event) {
12422 Player.prototype['handleTech' + (0, _toTitleCase2['default'])(event) + '_'] = function () {
12423 return this.trigger(event);
12428 * Fired when the player has initial duration and dimension information
12430 * @event Player#loadedmetadata
12431 * @type {EventTarget~Event}
12435 * Fired when the player has downloaded data at the current playback position
12437 * @event Player#loadeddata
12438 * @type {EventTarget~Event}
12442 * Fired when the current playback position has changed *
12443 * During playback this is fired every 15-250 milliseconds, depending on the
12444 * playback technology in use.
12446 * @event Player#timeupdate
12447 * @type {EventTarget~Event}
12451 * Fired when the volume changes
12453 * @event Player#volumechange
12454 * @type {EventTarget~Event}
12457 _component2['default'].registerComponent('Player', Player);
12458 exports['default'] = Player;
12460 },{"1":1,"4":4,"41":41,"44":44,"45":45,"46":46,"5":5,"50":50,"55":55,"59":59,"60":60,"61":61,"62":62,"63":63,"68":68,"69":69,"71":71,"76":76,"78":78,"79":79,"8":8,"81":81,"82":82,"83":83,"85":85,"86":86,"87":87,"88":88,"89":89,"90":90,"91":91,"94":94,"95":95,"97":97}],52:[function(_dereq_,module,exports){
12463 exports.__esModule = true;
12465 var _player = _dereq_(51);
12467 var _player2 = _interopRequireDefault(_player);
12469 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12472 * The method for registering a video.js plugin. {@link videojs:videojs.registerPlugin].
12474 * @param {string} name
12475 * The name of the plugin that is being registered
12477 * @param {plugins:PluginFn} init
12478 * The function that gets run when a `Player` initializes.
12480 var plugin = function plugin(name, init) {
12481 _player2['default'].prototype[name] = init;
12486 exports['default'] = plugin;
12488 },{"51":51}],53:[function(_dereq_,module,exports){
12491 exports.__esModule = true;
12493 var _clickableComponent = _dereq_(3);
12495 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
12497 var _component = _dereq_(5);
12499 var _component2 = _interopRequireDefault(_component);
12501 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12503 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12505 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
12507 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
12508 * @file popup-button.js
12513 * A button class for use with {@link Popup} controls
12515 * @extends ClickableComponent
12517 var PopupButton = function (_ClickableComponent) {
12518 _inherits(PopupButton, _ClickableComponent);
12521 * Create an instance of this class.
12523 * @param {Player} player
12524 * The `Player` that this class should be attached to.
12526 * @param {Object} [options]
12527 * The key/value store of player options.
12529 function PopupButton(player) {
12530 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
12532 _classCallCheck(this, PopupButton);
12534 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
12541 * Update the `Popup` that this button is attached to.
12545 PopupButton.prototype.update = function update() {
12546 var popup = this.createPopup();
12549 this.removeChild(this.popup);
12552 this.popup = popup;
12553 this.addChild(popup);
12555 if (this.items && this.items.length === 0) {
12557 } else if (this.items && this.items.length > 1) {
12563 * Create a `Popup`. - Override with specific functionality for component
12569 PopupButton.prototype.createPopup = function createPopup() {};
12572 * Create the `PopupButton`s DOM element.
12574 * @return {Element}
12575 * The element that gets created.
12579 PopupButton.prototype.createEl = function createEl() {
12580 return _ClickableComponent.prototype.createEl.call(this, 'div', {
12581 className: this.buildCSSClass()
12586 * Builds the default DOM `className`.
12589 * The DOM `className` for this object.
12593 PopupButton.prototype.buildCSSClass = function buildCSSClass() {
12594 var menuButtonClass = 'vjs-menu-button';
12596 // If the inline option is passed, we want to use different styles altogether.
12597 if (this.options_.inline === true) {
12598 menuButtonClass += '-inline';
12600 menuButtonClass += '-popup';
12603 return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
12606 return PopupButton;
12607 }(_clickableComponent2['default']);
12609 _component2['default'].registerComponent('PopupButton', PopupButton);
12610 exports['default'] = PopupButton;
12612 },{"3":3,"5":5}],54:[function(_dereq_,module,exports){
12615 exports.__esModule = true;
12617 var _component = _dereq_(5);
12619 var _component2 = _interopRequireDefault(_component);
12621 var _dom = _dereq_(81);
12623 var Dom = _interopRequireWildcard(_dom);
12625 var _fn = _dereq_(83);
12627 var Fn = _interopRequireWildcard(_fn);
12629 var _events = _dereq_(82);
12631 var Events = _interopRequireWildcard(_events);
12633 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
12635 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12637 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12639 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
12641 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
12647 * The Popup component is used to build pop up controls.
12649 * @extends Component
12651 var Popup = function (_Component) {
12652 _inherits(Popup, _Component);
12655 _classCallCheck(this, Popup);
12657 return _possibleConstructorReturn(this, _Component.apply(this, arguments));
12661 * Add a popup item to the popup
12663 * @param {Object|string} component
12664 * Component or component type to add
12667 Popup.prototype.addItem = function addItem(component) {
12668 this.addChild(component);
12669 component.on('click', Fn.bind(this, function () {
12670 this.unlockShowing();
12675 * Create the `PopupButton`s DOM element.
12677 * @return {Element}
12678 * The element that gets created.
12682 Popup.prototype.createEl = function createEl() {
12683 var contentElType = this.options_.contentElType || 'ul';
12685 this.contentEl_ = Dom.createEl(contentElType, {
12686 className: 'vjs-menu-content'
12689 var el = _Component.prototype.createEl.call(this, 'div', {
12690 append: this.contentEl_,
12691 className: 'vjs-menu'
12694 el.appendChild(this.contentEl_);
12696 // Prevent clicks from bubbling up. Needed for Popup Buttons,
12697 // where a click on the parent is significant
12698 Events.on(el, 'click', function (event) {
12699 event.preventDefault();
12700 event.stopImmediatePropagation();
12707 }(_component2['default']);
12709 _component2['default'].registerComponent('Popup', Popup);
12710 exports['default'] = Popup;
12712 },{"5":5,"81":81,"82":82,"83":83}],55:[function(_dereq_,module,exports){
12715 exports.__esModule = true;
12717 var _clickableComponent = _dereq_(3);
12719 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
12721 var _component = _dereq_(5);
12723 var _component2 = _interopRequireDefault(_component);
12725 var _fn = _dereq_(83);
12727 var Fn = _interopRequireWildcard(_fn);
12729 var _dom = _dereq_(81);
12731 var Dom = _interopRequireWildcard(_dom);
12733 var _browser = _dereq_(78);
12735 var browser = _interopRequireWildcard(_browser);
12737 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
12739 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12741 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12743 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
12745 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
12746 * @file poster-image.js
12751 * A `ClickableComponent` that handles showing the poster image for the player.
12753 * @extends ClickableComponent
12755 var PosterImage = function (_ClickableComponent) {
12756 _inherits(PosterImage, _ClickableComponent);
12759 * Create an instance of this class.
12761 * @param {Player} player
12762 * The `Player` that this class should attach to.
12764 * @param {Object} [options]
12765 * The key/value store of player options.
12767 function PosterImage(player, options) {
12768 _classCallCheck(this, PosterImage);
12770 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
12773 player.on('posterchange', Fn.bind(_this, _this.update));
12778 * Clean up and dispose of the `PosterImage`.
12782 PosterImage.prototype.dispose = function dispose() {
12783 this.player().off('posterchange', this.update);
12784 _ClickableComponent.prototype.dispose.call(this);
12788 * Create the `PosterImage`s DOM element.
12790 * @return {Element}
12791 * The element that gets created.
12795 PosterImage.prototype.createEl = function createEl() {
12796 var el = Dom.createEl('div', {
12797 className: 'vjs-poster',
12799 // Don't want poster to be tabbable.
12803 // To ensure the poster image resizes while maintaining its original aspect
12804 // ratio, use a div with `background-size` when available. For browsers that
12805 // do not support `background-size` (e.g. IE8), fall back on using a regular
12807 if (!browser.BACKGROUND_SIZE_SUPPORTED) {
12808 this.fallbackImg_ = Dom.createEl('img');
12809 el.appendChild(this.fallbackImg_);
12816 * An {@link EventTarget~EventListener} for {@link Player#posterchange} events.
12818 * @listens Player#posterchange
12820 * @param {EventTarget~Event} [event]
12821 * The `Player#posterchange` event that triggered this function.
12825 PosterImage.prototype.update = function update(event) {
12826 var url = this.player().poster();
12830 // If there's no poster source we should display:none on this component
12831 // so it's not still clickable or right-clickable
12840 * Set the source of the `PosterImage` depending on the display method.
12842 * @param {string} url
12843 * The URL to the source for the `PosterImage`.
12847 PosterImage.prototype.setSrc = function setSrc(url) {
12848 if (this.fallbackImg_) {
12849 this.fallbackImg_.src = url;
12851 var backgroundImage = '';
12853 // Any falsey values should stay as an empty string, otherwise
12854 // this will throw an extra error
12856 backgroundImage = 'url("' + url + '")';
12859 this.el_.style.backgroundImage = backgroundImage;
12864 * An {@link EventTarget~EventListener} for clicks on the `PosterImage`. See
12865 * {@link ClickableComponent#handleClick} for instances where this will be triggered.
12871 * @param {EventTarget~Event} event
12872 + The `click`, `tap` or `keydown` event that caused this function to be called.
12876 PosterImage.prototype.handleClick = function handleClick(event) {
12877 // We don't want a click to trigger playback when controls are disabled
12878 if (!this.player_.controls()) {
12882 if (this.player_.paused()) {
12883 this.player_.play();
12885 this.player_.pause();
12889 return PosterImage;
12890 }(_clickableComponent2['default']);
12892 _component2['default'].registerComponent('PosterImage', PosterImage);
12893 exports['default'] = PosterImage;
12895 },{"3":3,"5":5,"78":78,"81":81,"83":83}],56:[function(_dereq_,module,exports){
12898 exports.__esModule = true;
12899 exports.hasLoaded = exports.autoSetupTimeout = exports.autoSetup = undefined;
12901 var _dom = _dereq_(81);
12903 var Dom = _interopRequireWildcard(_dom);
12905 var _events = _dereq_(82);
12907 var Events = _interopRequireWildcard(_events);
12909 var _document = _dereq_(94);
12911 var _document2 = _interopRequireDefault(_document);
12913 var _window = _dereq_(95);
12915 var _window2 = _interopRequireDefault(_window);
12917 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12919 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
12922 * @file setup.js - Functions for setting up a player without
12923 * user interaction based on the data-setup `attribute` of the video tag.
12927 var _windowLoaded = false;
12928 var videojs = void 0;
12931 * Set up any tags that have a data-setup `attribute` when the player is started.
12933 var autoSetup = function autoSetup() {
12935 // Protect against breakage in non-browser environments.
12936 if (!Dom.isReal()) {
12940 // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack*
12941 // var vids = Array.prototype.slice.call(document.getElementsByTagName('video'));
12942 // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio'));
12943 // var mediaEls = vids.concat(audios);
12945 // Because IE8 doesn't support calling slice on a node list, we need to loop
12946 // through each list of elements to build up a new, combined list of elements.
12947 var vids = _document2['default'].getElementsByTagName('video');
12948 var audios = _document2['default'].getElementsByTagName('audio');
12951 if (vids && vids.length > 0) {
12952 for (var i = 0, e = vids.length; i < e; i++) {
12953 mediaEls.push(vids[i]);
12957 if (audios && audios.length > 0) {
12958 for (var _i = 0, _e = audios.length; _i < _e; _i++) {
12959 mediaEls.push(audios[_i]);
12963 // Check if any media elements exist
12964 if (mediaEls && mediaEls.length > 0) {
12966 for (var _i2 = 0, _e2 = mediaEls.length; _i2 < _e2; _i2++) {
12967 var mediaEl = mediaEls[_i2];
12969 // Check if element exists, has getAttribute func.
12970 // IE seems to consider typeof el.getAttribute == 'object' instead of
12971 // 'function' like expected, at least when loading the player immediately.
12972 if (mediaEl && mediaEl.getAttribute) {
12974 // Make sure this player hasn't already been set up.
12975 if (mediaEl.player === undefined) {
12976 var options = mediaEl.getAttribute('data-setup');
12978 // Check if data-setup attr exists.
12979 // We only auto-setup if they've added the data-setup attr.
12980 if (options !== null) {
12981 // Create new video.js instance.
12986 // If getAttribute isn't defined, we need to wait for the DOM.
12988 autoSetupTimeout(1);
12993 // No videos were found, so keep looping unless page is finished loading.
12994 } else if (!_windowLoaded) {
12995 autoSetupTimeout(1);
13000 * Wait until the page is loaded before running autoSetup. This will be called in
13001 * autoSetup if `hasLoaded` returns false.
13003 * @param {number} wait
13004 * How long to wait in ms
13006 * @param {videojs} [vjs]
13007 * The videojs library function
13009 function autoSetupTimeout(wait, vjs) {
13014 _window2['default'].setTimeout(autoSetup, wait);
13017 if (Dom.isReal() && _document2['default'].readyState === 'complete') {
13018 _windowLoaded = true;
13021 * Listen for the load event on window, and set _windowLoaded to true.
13025 Events.one(_window2['default'], 'load', function () {
13026 _windowLoaded = true;
13031 * check if the document has been loaded
13033 var hasLoaded = function hasLoaded() {
13034 return _windowLoaded;
13037 exports.autoSetup = autoSetup;
13038 exports.autoSetupTimeout = autoSetupTimeout;
13039 exports.hasLoaded = hasLoaded;
13041 },{"81":81,"82":82,"94":94,"95":95}],57:[function(_dereq_,module,exports){
13044 exports.__esModule = true;
13046 var _component = _dereq_(5);
13048 var _component2 = _interopRequireDefault(_component);
13050 var _dom = _dereq_(81);
13052 var Dom = _interopRequireWildcard(_dom);
13054 var _obj = _dereq_(88);
13056 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
13058 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13060 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
13062 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
13064 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
13070 * The base functionality for a slider. Can be vertical or horizontal.
13071 * For instance the volume bar or the seek bar on a video is a slider.
13073 * @extends Component
13075 var Slider = function (_Component) {
13076 _inherits(Slider, _Component);
13079 * Create an instance of this class
13081 * @param {Player} player
13082 * The `Player` that this class should be attached to.
13084 * @param {Object} [options]
13085 * The key/value store of player options.
13087 function Slider(player, options) {
13088 _classCallCheck(this, Slider);
13090 // Set property names to bar to match with the child Slider class is looking for
13091 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
13093 _this.bar = _this.getChild(_this.options_.barName);
13095 // Set a horizontal or vertical class on the slider depending on the slider type
13096 _this.vertical(!!_this.options_.vertical);
13098 _this.on('mousedown', _this.handleMouseDown);
13099 _this.on('touchstart', _this.handleMouseDown);
13100 _this.on('focus', _this.handleFocus);
13101 _this.on('blur', _this.handleBlur);
13102 _this.on('click', _this.handleClick);
13104 _this.on(player, 'controlsvisible', _this.update);
13105 _this.on(player, _this.playerEvent, _this.update);
13110 * Create the `Button`s DOM element.
13112 * @param {string} type
13113 * Type of element to create.
13115 * @param {Object} [props={}]
13116 * List of properties in Object form.
13118 * @param {Object} [attributes={}]
13119 * list of attributes in Object form.
13121 * @return {Element}
13122 * The element that gets created.
13126 Slider.prototype.createEl = function createEl(type) {
13127 var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
13128 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
13130 // Add the slider element class to all sub classes
13131 props.className = props.className + ' vjs-slider';
13132 props = (0, _obj.assign)({
13136 attributes = (0, _obj.assign)({
13138 'aria-valuenow': 0,
13139 'aria-valuemin': 0,
13140 'aria-valuemax': 100,
13144 return _Component.prototype.createEl.call(this, type, props, attributes);
13148 * Handle `mousedown` or `touchstart` events on the `Slider`.
13150 * @param {EventTarget~Event} event
13151 * `mousedown` or `touchstart` event that triggered this function
13153 * @listens mousedown
13154 * @listens touchstart
13155 * @fires Slider#slideractive
13159 Slider.prototype.handleMouseDown = function handleMouseDown(event) {
13160 var doc = this.bar.el_.ownerDocument;
13162 event.preventDefault();
13163 Dom.blockTextSelection();
13165 this.addClass('vjs-sliding');
13167 * Triggered when the slider is in an active state
13169 * @event Slider#slideractive
13170 * @type {EventTarget~Event}
13172 this.trigger('slideractive');
13174 this.on(doc, 'mousemove', this.handleMouseMove);
13175 this.on(doc, 'mouseup', this.handleMouseUp);
13176 this.on(doc, 'touchmove', this.handleMouseMove);
13177 this.on(doc, 'touchend', this.handleMouseUp);
13179 this.handleMouseMove(event);
13183 * Handle the `mousemove`, `touchmove`, and `mousedown` events on this `Slider`.
13184 * The `mousemove` and `touchmove` events will only only trigger this function during
13185 * `mousedown` and `touchstart`. This is due to {@link Slider#handleMouseDown} and
13186 * {@link Slider#handleMouseUp}.
13188 * @param {EventTarget~Event} event
13189 * `mousedown`, `mousemove`, `touchstart`, or `touchmove` event that triggered
13192 * @listens mousemove
13193 * @listens touchmove
13197 Slider.prototype.handleMouseMove = function handleMouseMove(event) {};
13200 * Handle `mouseup` or `touchend` events on the `Slider`.
13202 * @param {EventTarget~Event} event
13203 * `mouseup` or `touchend` event that triggered this function.
13205 * @listens touchend
13207 * @fires Slider#sliderinactive
13211 Slider.prototype.handleMouseUp = function handleMouseUp() {
13212 var doc = this.bar.el_.ownerDocument;
13214 Dom.unblockTextSelection();
13216 this.removeClass('vjs-sliding');
13218 * Triggered when the slider is no longer in an active state.
13220 * @event Slider#sliderinactive
13221 * @type {EventTarget~Event}
13223 this.trigger('sliderinactive');
13225 this.off(doc, 'mousemove', this.handleMouseMove);
13226 this.off(doc, 'mouseup', this.handleMouseUp);
13227 this.off(doc, 'touchmove', this.handleMouseMove);
13228 this.off(doc, 'touchend', this.handleMouseUp);
13234 * Update the progress bar of the `Slider`.
13238 Slider.prototype.update = function update() {
13239 // In VolumeBar init we have a setTimeout for update that pops and update to the end of the
13240 // execution stack. The player is destroyed before then update will cause an error
13245 // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.
13246 // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.
13247 // var progress = (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration();
13248 var progress = this.getPercent();
13249 var bar = this.bar;
13251 // If there's no bar...
13256 // Protect against no duration and other division issues
13257 if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) {
13261 // Convert to a percentage for setting
13262 var percentage = (progress * 100).toFixed(2) + '%';
13264 // Set the new bar width or height
13265 if (this.vertical()) {
13266 bar.el().style.height = percentage;
13268 bar.el().style.width = percentage;
13273 * Calculate distance for slider
13275 * @param {EventTarget~Event} event
13276 * The event that caused this function to run.
13279 * The current position of the Slider.
13280 * - postition.x for vertical `Slider`s
13281 * - postition.y for horizontal `Slider`s
13285 Slider.prototype.calculateDistance = function calculateDistance(event) {
13286 var position = Dom.getPointerPosition(this.el_, event);
13288 if (this.vertical()) {
13295 * Handle a `focus` event on this `Slider`.
13297 * @param {EventTarget~Event} event
13298 * The `focus` event that caused this function to run.
13304 Slider.prototype.handleFocus = function handleFocus() {
13305 this.on(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
13309 * Handle a `keydown` event on the `Slider`. Watches for left, rigth, up, and down
13310 * arrow keys. This function will only be called when the slider has focus. See
13311 * {@link Slider#handleFocus} and {@link Slider#handleBlur}.
13313 * @param {EventTarget~Event} event
13314 * the `keydown` event that caused this function to run.
13320 Slider.prototype.handleKeyPress = function handleKeyPress(event) {
13321 // Left and Down Arrows
13322 if (event.which === 37 || event.which === 40) {
13323 event.preventDefault();
13326 // Up and Right Arrows
13327 } else if (event.which === 38 || event.which === 39) {
13328 event.preventDefault();
13329 this.stepForward();
13334 * Handle a `blur` event on this `Slider`.
13336 * @param {EventTarget~Event} event
13337 * The `blur` event that caused this function to run.
13342 Slider.prototype.handleBlur = function handleBlur() {
13343 this.off(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
13347 * Listener for click events on slider, used to prevent clicks
13348 * from bubbling up to parent elements like button menus.
13350 * @param {Object} event
13351 * Event that caused this object to run
13355 Slider.prototype.handleClick = function handleClick(event) {
13356 event.stopImmediatePropagation();
13357 event.preventDefault();
13361 * Get/set if slider is horizontal for vertical
13363 * @param {boolean} [bool]
13364 * - true if slider is vertical,
13365 * - false is horizontal
13367 * @return {boolean|Slider}
13368 * - true if slider is vertical, and getting
13369 * - false is horizontal, and getting
13370 * - a reference to this object when setting
13374 Slider.prototype.vertical = function vertical(bool) {
13375 if (bool === undefined) {
13376 return this.vertical_ || false;
13379 this.vertical_ = !!bool;
13381 if (this.vertical_) {
13382 this.addClass('vjs-slider-vertical');
13384 this.addClass('vjs-slider-horizontal');
13391 }(_component2['default']);
13393 _component2['default'].registerComponent('Slider', Slider);
13394 exports['default'] = Slider;
13396 },{"5":5,"81":81,"88":88}],58:[function(_dereq_,module,exports){
13399 exports.__esModule = true;
13401 * @file flash-rtmp.js
13402 * @module flash-rtmp
13406 * Add RTMP properties to the {@link Flash} Tech.
13408 * @param {Flash} Flash
13409 * The flash tech class.
13411 * @mixin FlashRtmpDecorator
13413 function FlashRtmpDecorator(Flash) {
13414 Flash.streamingFormats = {
13420 * Join connection and stream with an ampersand.
13422 * @param {string} connection
13423 * The connection string.
13425 * @param {string} stream
13426 * The stream string.
13428 Flash.streamFromParts = function (connection, stream) {
13429 return connection + '&' + stream;
13433 * The flash parts object that contains connection and stream info.
13435 * @typedef {Object} Flash~PartsObject
13437 * @property {string} connection
13438 * The connection string of a source, defaults to an empty string.
13440 * @property {string} stream
13441 * The stream string of the source, defaults to an empty string.
13445 * Convert a source url into a stream and connection parts.
13447 * @param {string} src
13450 * @return {Flash~PartsObject}
13451 * The parts object that contains a connection and a stream
13453 Flash.streamToParts = function (src) {
13463 // Look for the normal URL separator we expect, '&'.
13464 // If found, we split the URL into two pieces around the
13466 var connEnd = src.search(/&(?!\w+=)/);
13467 var streamBegin = void 0;
13469 if (connEnd !== -1) {
13470 streamBegin = connEnd + 1;
13472 // If there's not a '&', we use the last '/' as the delimiter.
13473 connEnd = streamBegin = src.lastIndexOf('/') + 1;
13474 if (connEnd === 0) {
13475 // really, there's not a '/'?
13476 connEnd = streamBegin = src.length;
13480 parts.connection = src.substring(0, connEnd);
13481 parts.stream = src.substring(streamBegin, src.length);
13487 * Check if the source type is a streaming type.
13489 * @param {string} srcType
13490 * The mime type to check.
13492 * @return {boolean}
13493 * - True if the source type is a streaming type.
13494 * - False if the source type is not a streaming type.
13496 Flash.isStreamingType = function (srcType) {
13497 return srcType in Flash.streamingFormats;
13500 // RTMP has four variations, any string starting
13501 // with one of these protocols should be valid
13504 * Regular expression used to check if the source is an rtmp source.
13506 * @property {RegExp} Flash.RTMP_RE
13508 Flash.RTMP_RE = /^rtmp[set]?:\/\//i;
13511 * Check if the source itself is a streaming type.
13513 * @param {string} src
13514 * The url to the source.
13516 * @return {boolean}
13517 * - True if the source url indicates that the source is streaming.
13518 * - False if the shource url indicates that the source url is not streaming.
13520 Flash.isStreamingSrc = function (src) {
13521 return Flash.RTMP_RE.test(src);
13525 * A source handler for RTMP urls
13528 Flash.rtmpSourceHandler = {};
13531 * Check if Flash can play the given mime type.
13533 * @param {string} type
13534 * The mime type to check
13537 * 'maybe', or '' (empty string)
13539 Flash.rtmpSourceHandler.canPlayType = function (type) {
13540 if (Flash.isStreamingType(type)) {
13548 * Check if Flash can handle the source natively
13550 * @param {Object} source
13551 * The source object
13553 * @param {Object} [options]
13554 * The options passed to the tech
13557 * 'maybe', or '' (empty string)
13559 Flash.rtmpSourceHandler.canHandleSource = function (source, options) {
13560 var can = Flash.rtmpSourceHandler.canPlayType(source.type);
13566 if (Flash.isStreamingSrc(source.src)) {
13574 * Pass the source to the flash object.
13576 * @param {Object} source
13577 * The source object
13579 * @param {Flash} tech
13580 * The instance of the Flash tech
13582 * @param {Object} [options]
13583 * The options to pass to the source
13585 Flash.rtmpSourceHandler.handleSource = function (source, tech, options) {
13586 var srcParts = Flash.streamToParts(source.src);
13588 tech.setRtmpConnection(srcParts.connection);
13589 tech.setRtmpStream(srcParts.stream);
13592 // Register the native source handler
13593 Flash.registerSourceHandler(Flash.rtmpSourceHandler);
13598 exports['default'] = FlashRtmpDecorator;
13600 },{}],59:[function(_dereq_,module,exports){
13603 exports.__esModule = true;
13605 var _tech = _dereq_(62);
13607 var _tech2 = _interopRequireDefault(_tech);
13609 var _dom = _dereq_(81);
13611 var Dom = _interopRequireWildcard(_dom);
13613 var _url = _dereq_(92);
13615 var Url = _interopRequireWildcard(_url);
13617 var _timeRanges = _dereq_(90);
13619 var _flashRtmp = _dereq_(58);
13621 var _flashRtmp2 = _interopRequireDefault(_flashRtmp);
13623 var _component = _dereq_(5);
13625 var _component2 = _interopRequireDefault(_component);
13627 var _window = _dereq_(95);
13629 var _window2 = _interopRequireDefault(_window);
13631 var _obj = _dereq_(88);
13633 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
13635 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13637 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
13639 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
13641 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
13643 * VideoJS-SWF - Custom Flash Player with HTML5-ish API
13644 * https://github.com/zencoder/video-js-swf
13645 * Not using setupTriggers. Using global onEvent func to distribute events
13648 var navigator = _window2['default'].navigator;
13651 * Flash Media Controller - Wrapper for Flash Media API
13653 * @mixes FlashRtmpDecorator
13654 * @mixes Tech~SouceHandlerAdditions
13658 var Flash = function (_Tech) {
13659 _inherits(Flash, _Tech);
13662 * Create an instance of this Tech.
13664 * @param {Object} [options]
13665 * The key/value store of player options.
13667 * @param {Component~ReadyCallback} ready
13668 * Callback function to call when the `Flash` Tech is ready.
13670 function Flash(options, ready) {
13671 _classCallCheck(this, Flash);
13673 // Set the source when ready
13674 var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready));
13676 if (options.source) {
13677 _this.ready(function () {
13678 this.setSource(options.source);
13682 // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers
13683 // This allows resetting the playhead when we catch the reload
13684 if (options.startTime) {
13685 _this.ready(function () {
13688 this.currentTime(options.startTime);
13692 // Add global window functions that the swf expects
13693 // A 4.x workflow we weren't able to solve for in 5.0
13694 // because of the need to hard code these functions
13695 // into the swf for security reasons
13696 _window2['default'].videojs = _window2['default'].videojs || {};
13697 _window2['default'].videojs.Flash = _window2['default'].videojs.Flash || {};
13698 _window2['default'].videojs.Flash.onReady = Flash.onReady;
13699 _window2['default'].videojs.Flash.onEvent = Flash.onEvent;
13700 _window2['default'].videojs.Flash.onError = Flash.onError;
13702 _this.on('seeked', function () {
13703 this.lastSeekTarget_ = undefined;
13710 * Create the `Flash` Tech's DOM element.
13712 * @return {Element}
13713 * The element that gets created.
13717 Flash.prototype.createEl = function createEl() {
13718 var options = this.options_;
13720 // If video.js is hosted locally you should also set the location
13721 // for the hosted swf, which should be relative to the page (not video.js)
13722 // Otherwise this adds a CDN url.
13723 // The CDN also auto-adds a swf URL for that specific version.
13724 if (!options.swf) {
13727 options.swf = '//vjs.zencdn.net/swf/' + ver + '/video-js.swf';
13730 // Generate ID for swf object
13731 var objId = options.techId;
13733 // Merge default flashvars with ones passed in to init
13734 var flashVars = (0, _obj.assign)({
13736 // SWF Callback Functions
13737 readyFunction: 'videojs.Flash.onReady',
13738 eventProxyFunction: 'videojs.Flash.onEvent',
13739 errorEventProxyFunction: 'videojs.Flash.onError',
13742 autoplay: options.autoplay,
13743 preload: options.preload,
13744 loop: options.loop,
13745 muted: options.muted
13747 }, options.flashVars);
13749 // Merge default parames with ones passed in
13750 var params = (0, _obj.assign)({
13751 // Opaque is needed to overlay controls, but can affect playback performance
13753 // Using bgcolor prevents a white flash when the object is loading
13755 }, options.params);
13757 // Merge default attributes with ones passed in
13758 var attributes = (0, _obj.assign)({
13759 // Both ID and Name needed or swf to identify itself
13762 'class': 'vjs-tech'
13763 }, options.attributes);
13765 this.el_ = Flash.embed(options.swf, flashVars, params, attributes);
13766 this.el_.tech = this;
13772 * Called by {@link Player#play} to play using the `Flash` `Tech`.
13776 Flash.prototype.play = function play() {
13777 if (this.ended()) {
13778 this.setCurrentTime(0);
13780 this.el_.vjs_play();
13784 * Called by {@link Player#pause} to pause using the `Flash` `Tech`.
13788 Flash.prototype.pause = function pause() {
13789 this.el_.vjs_pause();
13793 * A getter/setter for the `Flash` Tech's source object.
13794 * > Note: Please use {@link Flash#setSource}
13796 * @param {Tech~SourceObject} [src]
13797 * The source object you want to set on the `Flash` techs.
13799 * @return {Tech~SourceObject|undefined}
13800 * - The current source object when a source is not passed in.
13801 * - undefined when setting
13803 * @deprecated Since version 5.
13807 Flash.prototype.src = function src(_src) {
13808 if (_src === undefined) {
13809 return this.currentSrc();
13812 // Setting src through `src` not `setSrc` will be deprecated
13813 return this.setSrc(_src);
13817 * A getter/setter for the `Flash` Tech's source object.
13819 * @param {Tech~SourceObject} [src]
13820 * The source object you want to set on the `Flash` techs.
13822 * @return {Tech~SourceObject|undefined}
13823 * - The current source object when a source is not passed in.
13824 * - undefined when setting
13828 Flash.prototype.setSrc = function setSrc(src) {
13831 // Make sure source URL is absolute.
13832 src = Url.getAbsoluteURL(src);
13833 this.el_.vjs_src(src);
13835 // Currently the SWF doesn't autoplay if you load a source later.
13836 // e.g. Load player w/ no source, wait 2s, set src.
13837 if (this.autoplay()) {
13838 this.setTimeout(function () {
13839 return _this2.play();
13845 * Indicates whether the media is currently seeking to a new position or not.
13847 * @return {boolean}
13848 * - True if seeking to a new position
13849 * - False otherwise
13853 Flash.prototype.seeking = function seeking() {
13854 return this.lastSeekTarget_ !== undefined;
13858 * Returns the current time in seconds that the media is at in playback.
13860 * @param {number} time
13861 * Current playtime of the media in seconds.
13865 Flash.prototype.setCurrentTime = function setCurrentTime(time) {
13866 var seekable = this.seekable();
13868 if (seekable.length) {
13869 // clamp to the current seekable range
13870 time = time > seekable.start(0) ? time : seekable.start(0);
13871 time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1);
13873 this.lastSeekTarget_ = time;
13874 this.trigger('seeking');
13875 this.el_.vjs_setProperty('currentTime', time);
13876 _Tech.prototype.setCurrentTime.call(this);
13881 * Get the current playback time in seconds
13884 * The current time of playback in seconds.
13888 Flash.prototype.currentTime = function currentTime() {
13889 // when seeking make the reported time keep up with the requested time
13890 // by reading the time we're seeking to
13891 if (this.seeking()) {
13892 return this.lastSeekTarget_ || 0;
13894 return this.el_.vjs_getProperty('currentTime');
13898 * Get the current source
13900 * @method currentSrc
13901 * @return {Tech~SourceObject}
13902 * The current source
13906 Flash.prototype.currentSrc = function currentSrc() {
13907 if (this.currentSource_) {
13908 return this.currentSource_.src;
13910 return this.el_.vjs_getProperty('currentSrc');
13914 * Get the total duration of the current media.
13917 8 The total duration of the current media.
13921 Flash.prototype.duration = function duration() {
13922 if (this.readyState() === 0) {
13925 var duration = this.el_.vjs_getProperty('duration');
13927 return duration >= 0 ? duration : Infinity;
13931 * Load media into Tech.
13935 Flash.prototype.load = function load() {
13936 this.el_.vjs_load();
13940 * Get the poster image that was set on the tech.
13944 Flash.prototype.poster = function poster() {
13945 this.el_.vjs_getProperty('poster');
13949 * Poster images are not handled by the Flash tech so make this is a no-op.
13953 Flash.prototype.setPoster = function setPoster() {};
13956 * Determine the time ranges that can be seeked to in the media.
13958 * @return {TimeRange}
13959 * Returns the time ranges that can be seeked to.
13963 Flash.prototype.seekable = function seekable() {
13964 var duration = this.duration();
13966 if (duration === 0) {
13967 return (0, _timeRanges.createTimeRange)();
13969 return (0, _timeRanges.createTimeRange)(0, duration);
13973 * Get and create a `TimeRange` object for buffering.
13975 * @return {TimeRange}
13976 * The time range object that was created.
13980 Flash.prototype.buffered = function buffered() {
13981 var ranges = this.el_.vjs_getProperty('buffered');
13983 if (ranges.length === 0) {
13984 return (0, _timeRanges.createTimeRange)();
13986 return (0, _timeRanges.createTimeRange)(ranges[0][0], ranges[0][1]);
13990 * Get fullscreen support -
13992 * Flash does not allow fullscreen through javascript
13993 * so this always returns false.
13995 * @return {boolean}
13996 * The Flash tech does not support fullscreen, so it will always return false.
14000 Flash.prototype.supportsFullScreen = function supportsFullScreen() {
14001 // Flash does not allow fullscreen through javascript
14006 * Flash does not allow fullscreen through javascript
14007 * so this always returns false.
14009 * @return {boolean}
14010 * The Flash tech does not support fullscreen, so it will always return false.
14014 Flash.prototype.enterFullScreen = function enterFullScreen() {
14019 }(_tech2['default']);
14021 // Create setters and getters for attributes
14024 var _api = Flash.prototype;
14025 var _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(',');
14026 var _readOnly = 'networkState,readyState,initialTime,startOffsetTime,paused,ended,videoWidth,videoHeight'.split(',');
14028 function _createSetter(attr) {
14029 var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
14031 _api['set' + attrUpper] = function (val) {
14032 return this.el_.vjs_setProperty(attr, val);
14036 function _createGetter(attr) {
14037 _api[attr] = function () {
14038 return this.el_.vjs_getProperty(attr);
14042 // Create getter and setters for all read/write attributes
14043 for (var i = 0; i < _readWrite.length; i++) {
14044 _createGetter(_readWrite[i]);
14045 _createSetter(_readWrite[i]);
14048 // Create getters for read-only attributes
14049 for (var _i = 0; _i < _readOnly.length; _i++) {
14050 _createGetter(_readOnly[_i]);
14053 /** ------------------------------ Getters ------------------------------ **/
14055 * Get the value of `rtmpConnection` from the swf.
14057 * @method Flash#rtmpConnection
14059 * The current value of `rtmpConnection` on the swf.
14063 * Get the value of `rtmpStream` from the swf.
14065 * @method Flash#rtmpStream
14067 * The current value of `rtmpStream` on the swf.
14071 * Get the value of `preload` from the swf. `preload` indicates
14072 * what should download before the media is interacted with. It can have the following
14074 * - none: nothing should be downloaded
14075 * - metadata: poster and the first few frames of the media may be downloaded to get
14076 * media dimensions and other metadata
14077 * - auto: allow the media and metadata for the media to be downloaded before
14080 * @method Flash#preload
14082 * The value of `preload` from the swf. Will be 'none', 'metadata',
14087 * Get the value of `defaultPlaybackRate` from the swf.
14089 * @method Flash#defaultPlaybackRate
14091 * The current value of `defaultPlaybackRate` on the swf.
14095 * Get the value of `playbackRate` from the swf. `playbackRate` indicates
14096 * the rate at which the media is currently playing back. Examples:
14097 * - if playbackRate is set to 2, media will play twice as fast.
14098 * - if playbackRate is set to 0.5, media will play half as fast.
14100 * @method Flash#playbackRate
14102 * The value of `playbackRate` from the swf. A number indicating
14103 * the current playback speed of the media, where 1 is normal speed.
14107 * Get the value of `autoplay` from the swf. `autoplay` indicates
14108 * that the media should start to play as soon as the page is ready.
14110 * @method Flash#autoplay
14111 * @return {boolean}
14112 * - The value of `autoplay` from the swf.
14113 * - True indicates that the media ashould start as soon as the page loads.
14114 * - False indicates that the media should not start as soon as the page loads.
14118 * Get the value of `loop` from the swf. `loop` indicates
14119 * that the media should return to the start of the media and continue playing once
14120 * it reaches the end.
14122 * @method Flash#loop
14123 * @return {boolean}
14124 * - The value of `loop` from the swf.
14125 * - True indicates that playback should seek back to start once
14126 * the end of a media is reached.
14127 * - False indicates that playback should not loop back to the start when the
14128 * end of the media is reached.
14132 * Get the value of `mediaGroup` from the swf.
14134 * @method Flash#mediaGroup
14136 * The current value of `mediaGroup` on the swf.
14140 * Get the value of `controller` from the swf.
14142 * @method Flash#controller
14144 * The current value of `controller` on the swf.
14148 * Get the value of `controls` from the swf. `controls` indicates
14149 * whether the native flash controls should be shown or hidden.
14151 * @method Flash#controls
14152 * @return {boolean}
14153 * - The value of `controls` from the swf.
14154 * - True indicates that native controls should be showing.
14155 * - False indicates that native controls should be hidden.
14159 * Get the value of the `volume` from the swf. `volume` indicates the current
14160 * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
14163 * @method Flash#volume
14165 * The volume percent as a decimal. Value will be between 0-1.
14169 * Get the value of the `muted` from the swf. `muted` indicates the current
14170 * audio level should be silent.
14172 * @method Flash#muted
14173 * @return {boolean}
14174 * - True if the audio should be set to silent
14175 * - False otherwise
14179 * Get the value of `defaultMuted` from the swf. `defaultMuted` indicates
14180 * whether the media should start muted or not. Only changes the default state of the
14181 * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
14184 * @method Flash#defaultMuted
14185 * @return {boolean}
14186 * - The value of `defaultMuted` from the swf.
14187 * - True indicates that the media should start muted.
14188 * - False indicates that the media should not start muted.
14192 * Get the value of `networkState` from the swf. `networkState` indicates
14193 * the current network state. It returns an enumeration from the following list:
14194 * - 0: NETWORK_EMPTY
14196 * - 2: NETWORK_LOADING
14197 * - 3: NETWORK_NO_SOURCE
14199 * @method Flash#networkState
14201 * The value of `networkState` from the swf. This will be a number
14202 * from the list in the description.
14206 * Get the value of `readyState` from the swf. `readyState` indicates
14207 * the current state of the media element. It returns an enumeration from the
14209 * - 0: HAVE_NOTHING
14210 * - 1: HAVE_METADATA
14211 * - 2: HAVE_CURRENT_DATA
14212 * - 3: HAVE_FUTURE_DATA
14213 * - 4: HAVE_ENOUGH_DATA
14215 * @method Flash#readyState
14217 * The value of `readyState` from the swf. This will be a number
14218 * from the list in the description.
14222 * Get the value of `readyState` from the swf. `readyState` indicates
14223 * the current state of the media element. It returns an enumeration from the
14225 * - 0: HAVE_NOTHING
14226 * - 1: HAVE_METADATA
14227 * - 2: HAVE_CURRENT_DATA
14228 * - 3: HAVE_FUTURE_DATA
14229 * - 4: HAVE_ENOUGH_DATA
14231 * @method Flash#readyState
14233 * The value of `readyState` from the swf. This will be a number
14234 * from the list in the description.
14238 * Get the value of `initialTime` from the swf.
14240 * @method Flash#initialTime
14242 * The `initialTime` proprety on the swf.
14246 * Get the value of `startOffsetTime` from the swf.
14248 * @method Flash#startOffsetTime
14250 * The `startOffsetTime` proprety on the swf.
14254 * Get the value of `paused` from the swf. `paused` indicates whether the swf
14255 * is current paused or not.
14257 * @method Flash#paused
14258 * @return {boolean}
14259 * The value of `paused` from the swf.
14263 * Get the value of `ended` from the swf. `ended` indicates whether
14264 * the media has reached the end or not.
14266 * @method Flash#ended
14267 * @return {boolean}
14268 * - True indicates that the media has ended.
14269 * - False indicates that the media has not ended.
14271 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended}
14275 * Get the value of `videoWidth` from the swf. `videoWidth` indicates
14276 * the current width of the media in css pixels.
14278 * @method Flash#videoWidth
14280 * The value of `videoWidth` from the swf. This will be a number
14285 * Get the value of `videoHeight` from the swf. `videoHeigth` indicates
14286 * the current height of the media in css pixels.
14288 * @method Flassh.prototype.videoHeight
14290 * The value of `videoHeight` from the swf. This will be a number
14293 /** ------------------------------ Setters ------------------------------ **/
14296 * Set the value of `rtmpConnection` on the swf.
14298 * @method Flash#setRtmpConnection
14299 * @param {string} rtmpConnection
14300 * New value to set the `rtmpConnection` property to.
14304 * Set the value of `rtmpStream` on the swf.
14306 * @method Flash#setRtmpStream
14307 * @param {string} rtmpStream
14308 * New value to set the `rtmpStream` property to.
14312 * Set the value of `preload` on the swf. `preload` indicates
14313 * what should download before the media is interacted with. It can have the following
14315 * - none: nothing should be downloaded
14316 * - metadata: poster and the first few frames of the media may be downloaded to get
14317 * media dimensions and other metadata
14318 * - auto: allow the media and metadata for the media to be downloaded before
14321 * @method Flash#setPreload
14322 * @param {string} preload
14323 * The value of `preload` to set on the swf. Should be 'none', 'metadata',
14328 * Set the value of `defaultPlaybackRate` on the swf.
14330 * @method Flash#setDefaultPlaybackRate
14331 * @param {number} defaultPlaybackRate
14332 * New value to set the `defaultPlaybackRate` property to.
14336 * Set the value of `playbackRate` on the swf. `playbackRate` indicates
14337 * the rate at which the media is currently playing back. Examples:
14338 * - if playbackRate is set to 2, media will play twice as fast.
14339 * - if playbackRate is set to 0.5, media will play half as fast.
14341 * @method Flash#setPlaybackRate
14342 * @param {number} playbackRate
14343 * New value of `playbackRate` on the swf. A number indicating
14344 * the current playback speed of the media, where 1 is normal speed.
14348 * Set the value of `autoplay` on the swf. `autoplay` indicates
14349 * that the media should start to play as soon as the page is ready.
14351 * @method Flash#setAutoplay
14352 * @param {boolean} autoplay
14353 * - The value of `autoplay` from the swf.
14354 * - True indicates that the media ashould start as soon as the page loads.
14355 * - False indicates that the media should not start as soon as the page loads.
14359 * Set the value of `loop` on the swf. `loop` indicates
14360 * that the media should return to the start of the media and continue playing once
14361 * it reaches the end.
14363 * @method Flash#setLoop
14364 * @param {boolean} loop
14365 * - True indicates that playback should seek back to start once
14366 * the end of a media is reached.
14367 * - False indicates that playback should not loop back to the start when the
14368 * end of the media is reached.
14372 * Set the value of `mediaGroup` on the swf.
14374 * @method Flash#setMediaGroup
14375 * @param {string} mediaGroup
14376 * New value of `mediaGroup` to set on the swf.
14380 * Set the value of `controller` on the swf.
14382 * @method Flash#setController
14383 * @param {string} controller
14384 * New value the current value of `controller` on the swf.
14388 * Get the value of `controls` from the swf. `controls` indicates
14389 * whether the native flash controls should be shown or hidden.
14391 * @method Flash#controls
14392 * @return {boolean}
14393 * - The value of `controls` from the swf.
14394 * - True indicates that native controls should be showing.
14395 * - False indicates that native controls should be hidden.
14399 * Set the value of the `volume` on the swf. `volume` indicates the current
14400 * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
14403 * @method Flash#setVolume
14404 * @param {number} percentAsDecimal
14405 * The volume percent as a decimal. Value will be between 0-1.
14409 * Set the value of the `muted` on the swf. `muted` indicates that the current
14410 * audio level should be silent.
14412 * @method Flash#setMuted
14413 * @param {boolean} muted
14414 * - True if the audio should be set to silent
14415 * - False otherwise
14419 * Set the value of `defaultMuted` on the swf. `defaultMuted` indicates
14420 * whether the media should start muted or not. Only changes the default state of the
14421 * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
14424 * @method Flash#setDefaultMuted
14425 * @param {boolean} defaultMuted
14426 * - True indicates that the media should start muted.
14427 * - False indicates that the media should not start muted.
14430 /* Flash Support Testing -------------------------------------------------------- */
14433 * Check if the Flash tech is currently supported.
14435 * @return {boolean}
14436 * - True if the flash tech is supported.
14437 * - False otherwise.
14439 Flash.isSupported = function () {
14440 return Flash.version()[0] >= 10;
14441 // return swfobject.hasFlashPlayerVersion('10');
14444 // Add Source Handler pattern functions to this tech
14445 _tech2['default'].withSourceHandlers(Flash);
14448 * Native source handler for flash, simply passes the source to the swf element.
14450 * @property {Tech~SourceObject} source
14451 * The source object
14453 * @property {Flash} tech
14454 * The instance of the Flash tech
14456 Flash.nativeSourceHandler = {};
14459 * Check if the Flash can play the given mime type.
14461 * @param {string} type
14462 * The mimetype to check
14465 * 'maybe', or '' (empty string)
14467 Flash.nativeSourceHandler.canPlayType = function (type) {
14468 if (type in Flash.formats) {
14476 * Check if the media element can handle a source natively.
14478 * @param {Tech~SourceObject} source
14479 * The source object
14481 * @param {Object} [options]
14482 * Options to be passed to the tech.
14485 * 'maybe', or '' (empty string).
14487 Flash.nativeSourceHandler.canHandleSource = function (source, options) {
14490 function guessMimeType(src) {
14491 var ext = Url.getFileExtension(src);
14494 return 'video/' + ext;
14499 if (!source.type) {
14500 type = guessMimeType(source.src);
14502 // Strip code information from the type because we don't get that specific
14503 type = source.type.replace(/;.*/, '').toLowerCase();
14506 return Flash.nativeSourceHandler.canPlayType(type);
14510 * Pass the source to the swf.
14512 * @param {Tech~SourceObject} source
14513 * The source object
14515 * @param {Flash} tech
14516 * The instance of the Flash tech
14518 * @param {Object} [options]
14519 * The options to pass to the source
14521 Flash.nativeSourceHandler.handleSource = function (source, tech, options) {
14522 tech.setSrc(source.src);
14526 * noop for native source handler dispose, as cleanup will happen automatically.
14528 Flash.nativeSourceHandler.dispose = function () {};
14530 // Register the native source handler
14531 Flash.registerSourceHandler(Flash.nativeSourceHandler);
14534 * Flash supported mime types.
14536 * @constant {Object}
14539 'video/flv': 'FLV',
14540 'video/x-flv': 'FLV',
14541 'video/mp4': 'MP4',
14546 * Called when the the swf is "ready", and makes sure that the swf is really
14547 * ready using {@link Flash#checkReady}
14549 Flash.onReady = function (currSwf) {
14550 var el = Dom.getEl(currSwf);
14551 var tech = el && el.tech;
14553 // if there is no el then the tech has been disposed
14554 // and the tech element was removed from the player div
14555 if (tech && tech.el()) {
14556 // check that the flash object is really ready
14557 Flash.checkReady(tech);
14562 * The SWF isn't always ready when it says it is. Sometimes the API functions still
14563 * need to be added to the object. If it's not ready, we set a timeout to check again
14566 * @param {Flash} tech
14567 * The instance of the flash tech to check.
14569 Flash.checkReady = function (tech) {
14570 // stop worrying if the tech has been disposed
14575 // check if API property exists
14576 if (tech.el().vjs_getProperty) {
14577 // tell tech it's ready
14578 tech.triggerReady();
14581 this.setTimeout(function () {
14582 Flash.checkReady(tech);
14588 * Trigger events from the swf on the Flash Tech.
14590 * @param {number} swfID
14591 * The id of the swf that had the event
14593 * @param {string} eventName
14594 * The name of the event to trigger
14596 Flash.onEvent = function (swfID, eventName) {
14597 var tech = Dom.getEl(swfID).tech;
14598 var args = Array.prototype.slice.call(arguments, 2);
14600 // dispatch Flash events asynchronously for two reasons:
14601 // - Flash swallows any exceptions generated by javascript it
14603 // - Flash is suspended until the javascript returns which may cause
14604 // playback performance issues
14605 tech.setTimeout(function () {
14606 tech.trigger(eventName, args);
14611 * Log errors from the swf on the Flash tech.
14613 * @param {number} swfID
14614 * The id of the swf that had an error.
14616 * @param {string} The error string
14617 * The error to set on the Flash Tech.
14619 * @return {MediaError|undefined}
14620 * - Returns a MediaError when err is 'srcnotfound'
14621 * - Returns undefined otherwise.
14623 Flash.onError = function (swfID, err) {
14624 var tech = Dom.getEl(swfID).tech;
14626 // trigger MEDIA_ERR_SRC_NOT_SUPPORTED
14627 if (err === 'srcnotfound') {
14628 return tech.error(4);
14631 // trigger a custom error
14632 tech.error('FLASH: ' + err);
14636 * Get the current version of Flash that is in use on the page.
14639 * an array of versions that are available.
14641 Flash.version = function () {
14642 var version = '0,0,0';
14646 version = new _window2['default'].ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
14651 if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) {
14652 version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
14658 return version.split(',');
14662 * Only use for non-iframe embeds.
14664 * @param {Object} swf
14665 * The videojs-swf object.
14667 * @param {Object} flashVars
14668 * Names and values to use as flash option variables.
14670 * @param {Object} params
14671 * Style parameters to set on the object.
14673 * @param {Object} attributes
14674 * Attributes to set on the element.
14676 * @return {Element}
14677 * The embeded Flash DOM element.
14679 Flash.embed = function (swf, flashVars, params, attributes) {
14680 var code = Flash.getEmbedCode(swf, flashVars, params, attributes);
14682 // Get element by embedding code and retrieving created element
14683 var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0];
14689 * Only use for non-iframe embeds.
14691 * @param {Object} swf
14692 * The videojs-swf object.
14694 * @param {Object} flashVars
14695 * Names and values to use as flash option variables.
14697 * @param {Object} params
14698 * Style parameters to set on the object.
14700 * @param {Object} attributes
14701 * Attributes to set on the element.
14703 * @return {Element}
14704 * The embeded Flash DOM element.
14706 Flash.getEmbedCode = function (swf, flashVars, params, attributes) {
14707 var objTag = '<object type="application/x-shockwave-flash" ';
14708 var flashVarsString = '';
14709 var paramsString = '';
14710 var attrsString = '';
14712 // Convert flash vars to string
14714 Object.getOwnPropertyNames(flashVars).forEach(function (key) {
14715 flashVarsString += key + '=' + flashVars[key] + '&';
14719 // Add swf, flashVars, and other default params
14720 params = (0, _obj.assign)({
14722 flashvars: flashVarsString,
14723 // Required to talk to swf
14724 allowScriptAccess: 'always',
14725 // All should be default, but having security issues.
14726 allowNetworking: 'all'
14729 // Create param tags string
14730 Object.getOwnPropertyNames(params).forEach(function (key) {
14731 paramsString += '<param name="' + key + '" value="' + params[key] + '" />';
14734 attributes = (0, _obj.assign)({
14735 // Add swf to attributes (need both for IE and Others to work)
14738 // Default to 100% width/height
14744 // Create Attributes string
14745 Object.getOwnPropertyNames(attributes).forEach(function (key) {
14746 attrsString += key + '="' + attributes[key] + '" ';
14749 return '' + objTag + attrsString + '>' + paramsString + '</object>';
14752 // Run Flash through the RTMP decorator
14753 (0, _flashRtmp2['default'])(Flash);
14755 _component2['default'].registerComponent('Flash', Flash);
14756 _tech2['default'].registerTech('Flash', Flash);
14757 exports['default'] = Flash;
14759 },{"5":5,"58":58,"62":62,"81":81,"88":88,"90":90,"92":92,"95":95}],60:[function(_dereq_,module,exports){
14762 exports.__esModule = true;
14764 var _templateObject = _taggedTemplateLiteralLoose(['Text Tracks are being loaded from another origin but the crossorigin attribute isn\'t used.\n This may prevent text tracks from loading.'], ['Text Tracks are being loaded from another origin but the crossorigin attribute isn\'t used.\n This may prevent text tracks from loading.']);
14766 var _tech = _dereq_(62);
14768 var _tech2 = _interopRequireDefault(_tech);
14770 var _component = _dereq_(5);
14772 var _component2 = _interopRequireDefault(_component);
14774 var _dom = _dereq_(81);
14776 var Dom = _interopRequireWildcard(_dom);
14778 var _url = _dereq_(92);
14780 var Url = _interopRequireWildcard(_url);
14782 var _fn = _dereq_(83);
14784 var Fn = _interopRequireWildcard(_fn);
14786 var _log = _dereq_(86);
14788 var _log2 = _interopRequireDefault(_log);
14790 var _tsml = _dereq_(98);
14792 var _tsml2 = _interopRequireDefault(_tsml);
14794 var _browser = _dereq_(78);
14796 var browser = _interopRequireWildcard(_browser);
14798 var _document = _dereq_(94);
14800 var _document2 = _interopRequireDefault(_document);
14802 var _window = _dereq_(95);
14804 var _window2 = _interopRequireDefault(_window);
14806 var _obj = _dereq_(88);
14808 var _mergeOptions = _dereq_(87);
14810 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
14812 var _toTitleCase = _dereq_(91);
14814 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
14816 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
14818 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
14820 function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
14822 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
14824 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
14826 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
14832 * HTML5 Media Controller - Wrapper for HTML5 Media API
14834 * @mixes Tech~SouceHandlerAdditions
14837 var Html5 = function (_Tech) {
14838 _inherits(Html5, _Tech);
14841 * Create an instance of this Tech.
14843 * @param {Object} [options]
14844 * The key/value store of player options.
14846 * @param {Component~ReadyCallback} ready
14847 * Callback function to call when the `HTML5` Tech is ready.
14849 function Html5(options, ready) {
14850 _classCallCheck(this, Html5);
14852 var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready));
14854 var source = options.source;
14855 var crossoriginTracks = false;
14857 // Set the source if one is provided
14858 // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted)
14859 // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source
14860 // anyway so the error gets fired.
14861 if (source && (_this.el_.currentSrc !== source.src || options.tag && options.tag.initNetworkState_ === 3)) {
14862 _this.setSource(source);
14864 _this.handleLateInit_(_this.el_);
14867 if (_this.el_.hasChildNodes()) {
14869 var nodes = _this.el_.childNodes;
14870 var nodesLength = nodes.length;
14871 var removeNodes = [];
14873 while (nodesLength--) {
14874 var node = nodes[nodesLength];
14875 var nodeName = node.nodeName.toLowerCase();
14877 if (nodeName === 'track') {
14878 if (!_this.featuresNativeTextTracks) {
14879 // Empty video tag tracks so the built-in player doesn't use them also.
14880 // This may not be fast enough to stop HTML5 browsers from reading the tags
14881 // so we'll need to turn off any default tracks if we're manually doing
14882 // captions and subtitles. videoElement.textTracks
14883 removeNodes.push(node);
14885 // store HTMLTrackElement and TextTrack to remote list
14886 _this.remoteTextTrackEls().addTrackElement_(node);
14887 _this.remoteTextTracks().addTrack_(node.track);
14888 if (!crossoriginTracks && !_this.el_.hasAttribute('crossorigin') && Url.isCrossOrigin(node.src)) {
14889 crossoriginTracks = true;
14895 for (var i = 0; i < removeNodes.length; i++) {
14896 _this.el_.removeChild(removeNodes[i]);
14900 // TODO: add text tracks into this list
14901 var trackTypes = ['audio', 'video'];
14903 // ProxyNative Video/Audio Track
14904 trackTypes.forEach(function (type) {
14905 var elTracks = _this.el()[type + 'Tracks'];
14906 var techTracks = _this[type + 'Tracks']();
14907 var capitalType = (0, _toTitleCase2['default'])(type);
14909 if (!_this['featuresNative' + capitalType + 'Tracks'] || !elTracks || !elTracks.addEventListener) {
14913 _this['handle' + capitalType + 'TrackChange_'] = function (e) {
14914 techTracks.trigger({
14916 target: techTracks,
14917 currentTarget: techTracks,
14918 srcElement: techTracks
14922 _this['handle' + capitalType + 'TrackAdd_'] = function (e) {
14923 return techTracks.addTrack(e.track);
14925 _this['handle' + capitalType + 'TrackRemove_'] = function (e) {
14926 return techTracks.removeTrack(e.track);
14929 elTracks.addEventListener('change', _this['handle' + capitalType + 'TrackChange_']);
14930 elTracks.addEventListener('addtrack', _this['handle' + capitalType + 'TrackAdd_']);
14931 elTracks.addEventListener('removetrack', _this['handle' + capitalType + 'TrackRemove_']);
14932 _this['removeOld' + capitalType + 'Tracks_'] = function (e) {
14933 return _this.removeOldTracks_(techTracks, elTracks);
14936 // Remove (native) tracks that are not used anymore
14937 _this.on('loadstart', _this['removeOld' + capitalType + 'Tracks_']);
14940 if (_this.featuresNativeTextTracks) {
14941 if (crossoriginTracks) {
14942 _log2['default'].warn((0, _tsml2['default'])(_templateObject));
14945 _this.handleTextTrackChange_ = Fn.bind(_this, _this.handleTextTrackChange);
14946 _this.handleTextTrackAdd_ = Fn.bind(_this, _this.handleTextTrackAdd);
14947 _this.handleTextTrackRemove_ = Fn.bind(_this, _this.handleTextTrackRemove);
14948 _this.proxyNativeTextTracks_();
14951 // Determine if native controls should be used
14952 // Our goal should be to get the custom controls on mobile solid everywhere
14953 // so we can remove this all together. Right now this will block custom
14954 // controls on touch enabled laptops like the Chrome Pixel
14955 if ((browser.TOUCH_ENABLED || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) && options.nativeControlsForTouch === true) {
14956 _this.setControls(true);
14959 // on iOS, we want to proxy `webkitbeginfullscreen` and `webkitendfullscreen`
14960 // into a `fullscreenchange` event
14961 _this.proxyWebkitFullscreen_();
14963 _this.triggerReady();
14968 * Dispose of `HTML5` media element and remove all tracks.
14972 Html5.prototype.dispose = function dispose() {
14975 // Un-ProxyNativeTracks
14976 ['audio', 'video', 'text'].forEach(function (type) {
14977 var capitalType = (0, _toTitleCase2['default'])(type);
14978 var tl = _this2.el_[type + 'Tracks'];
14980 if (tl && tl.removeEventListener) {
14981 tl.removeEventListener('change', _this2['handle' + capitalType + 'TrackChange_']);
14982 tl.removeEventListener('addtrack', _this2['handle' + capitalType + 'TrackAdd_']);
14983 tl.removeEventListener('removetrack', _this2['handle' + capitalType + 'TrackRemove_']);
14986 // Stop removing old text tracks
14988 _this2.off('loadstart', _this2['removeOld' + capitalType + 'Tracks_']);
14992 Html5.disposeMediaElement(this.el_);
14993 // tech will handle clearing of the emulated track list
14994 _Tech.prototype.dispose.call(this);
14998 * Create the `Html5` Tech's DOM element.
15000 * @return {Element}
15001 * The element that gets created.
15005 Html5.prototype.createEl = function createEl() {
15006 var el = this.options_.tag;
15008 // Check if this browser supports moving the element into the box.
15009 // On the iPhone video will break if you move the element,
15010 // So we have to create a brand new element.
15011 // If we ingested the player div, we do not need to move the media element.
15012 if (!el || !(this.options_.playerElIngest || this.movingMediaElementInDOM)) {
15014 // If the original tag is still there, clone and remove it.
15016 var clone = el.cloneNode(true);
15018 if (el.parentNode) {
15019 el.parentNode.insertBefore(clone, el);
15021 Html5.disposeMediaElement(el);
15024 el = _document2['default'].createElement('video');
15026 // determine if native controls should be used
15027 var tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag);
15028 var attributes = (0, _mergeOptions2['default'])({}, tagAttributes);
15030 if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) {
15031 delete attributes.controls;
15034 Dom.setElAttributes(el, (0, _obj.assign)(attributes, {
15035 id: this.options_.techId,
15036 'class': 'vjs-tech'
15040 el.playerId = this.options_.playerId;
15043 // Update specific tag settings, in case they were overridden
15044 var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted'];
15046 for (var i = settingsAttrs.length - 1; i >= 0; i--) {
15047 var attr = settingsAttrs[i];
15048 var overwriteAttrs = {};
15050 if (typeof this.options_[attr] !== 'undefined') {
15051 overwriteAttrs[attr] = this.options_[attr];
15053 Dom.setElAttributes(el, overwriteAttrs);
15060 * This will be triggered if the loadstart event has already fired, before videojs was
15061 * ready. Two known examples of when this can happen are:
15062 * 1. If we're loading the playback object after it has started loading
15063 * 2. The media is already playing the (often with autoplay on) then
15065 * This function will fire another loadstart so that videojs can catchup.
15067 * @fires Tech#loadstart
15069 * @return {undefined}
15074 Html5.prototype.handleLateInit_ = function handleLateInit_(el) {
15075 if (el.networkState === 0 || el.networkState === 3) {
15076 // The video element hasn't started loading the source yet
15077 // or didn't find a source
15081 if (el.readyState === 0) {
15082 // NetworkState is set synchronously BUT loadstart is fired at the
15083 // end of the current stack, usually before setInterval(fn, 0).
15084 // So at this point we know loadstart may have already fired or is
15085 // about to fire, and either way the player hasn't seen it yet.
15086 // We don't want to fire loadstart prematurely here and cause a
15087 // double loadstart so we'll wait and see if it happens between now
15088 // and the next loop, and fire it if not.
15089 // HOWEVER, we also want to make sure it fires before loadedmetadata
15090 // which could also happen between now and the next loop, so we'll
15091 // watch for that also.
15092 var loadstartFired = false;
15093 var setLoadstartFired = function setLoadstartFired() {
15094 loadstartFired = true;
15097 this.on('loadstart', setLoadstartFired);
15099 var triggerLoadstart = function triggerLoadstart() {
15100 // We did miss the original loadstart. Make sure the player
15101 // sees loadstart before loadedmetadata
15102 if (!loadstartFired) {
15103 this.trigger('loadstart');
15107 this.on('loadedmetadata', triggerLoadstart);
15109 this.ready(function () {
15110 this.off('loadstart', setLoadstartFired);
15111 this.off('loadedmetadata', triggerLoadstart);
15113 if (!loadstartFired) {
15114 // We did miss the original native loadstart. Fire it now.
15115 this.trigger('loadstart');
15122 // From here on we know that loadstart already fired and we missed it.
15123 // The other readyState events aren't as much of a problem if we double
15124 // them, so not going to go to as much trouble as loadstart to prevent
15125 // that unless we find reason to.
15126 var eventsToTrigger = ['loadstart'];
15128 // loadedmetadata: newly equal to HAVE_METADATA (1) or greater
15129 eventsToTrigger.push('loadedmetadata');
15131 // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater
15132 if (el.readyState >= 2) {
15133 eventsToTrigger.push('loadeddata');
15136 // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater
15137 if (el.readyState >= 3) {
15138 eventsToTrigger.push('canplay');
15141 // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4)
15142 if (el.readyState >= 4) {
15143 eventsToTrigger.push('canplaythrough');
15146 // We still need to give the player time to add event listeners
15147 this.ready(function () {
15148 eventsToTrigger.forEach(function (type) {
15149 this.trigger(type);
15155 * Add event listeners to native text track events. This adds the native text tracks
15156 * to our emulated {@link TextTrackList}.
15160 Html5.prototype.proxyNativeTextTracks_ = function proxyNativeTextTracks_() {
15161 var tt = this.el().textTracks;
15164 // Add tracks - if player is initialised after DOM loaded, textTracks
15165 // will not trigger addtrack
15166 for (var i = 0; i < tt.length; i++) {
15167 this.textTracks().addTrack_(tt[i]);
15170 if (tt.addEventListener) {
15171 tt.addEventListener('change', this.handleTextTrackChange_);
15172 tt.addEventListener('addtrack', this.handleTextTrackAdd_);
15173 tt.addEventListener('removetrack', this.handleTextTrackRemove_);
15176 // Remove (native) texttracks that are not used anymore
15177 this.on('loadstart', this.removeOldTextTracks_);
15182 * Handle any {@link TextTrackList} `change` event.
15184 * @param {EventTarget~Event} e
15185 * The `change` event that caused this to run.
15187 * @listens TextTrackList#change
15191 Html5.prototype.handleTextTrackChange = function handleTextTrackChange(e) {
15192 var tt = this.textTracks();
15194 this.textTracks().trigger({
15203 * Handle any {@link TextTrackList} `addtrack` event.
15205 * @param {EventTarget~Event} e
15206 * The `addtrack` event that caused this to run.
15208 * @listens TextTrackList#addtrack
15212 Html5.prototype.handleTextTrackAdd = function handleTextTrackAdd(e) {
15213 this.textTracks().addTrack_(e.track);
15217 * Handle any {@link TextTrackList} `removetrack` event.
15219 * @param {EventTarget~Event} e
15220 * The `removetrack` event that caused this to run.
15222 * @listens TextTrackList#removetrack
15226 Html5.prototype.handleTextTrackRemove = function handleTextTrackRemove(e) {
15227 this.textTracks().removeTrack_(e.track);
15231 * This function removes any {@link AudioTrack}s, {@link VideoTrack}s, or
15232 * {@link TextTrack}s that are not in the media elements TrackList.
15234 * @param {TrackList} techTracks
15235 * HTML5 Tech's TrackList to search through
15237 * @param {TrackList} elTracks
15238 * HTML5 media elements TrackList to search trough.
15244 Html5.prototype.removeOldTracks_ = function removeOldTracks_(techTracks, elTracks) {
15245 // This will loop over the techTracks and check if they are still used by the HTML5 media element
15246 // If not, they will be removed from the emulated list
15247 var removeTracks = [];
15253 for (var i = 0; i < techTracks.length; i++) {
15254 var techTrack = techTracks[i];
15257 for (var j = 0; j < elTracks.length; j++) {
15258 if (elTracks[j] === techTrack) {
15265 removeTracks.push(techTrack);
15269 for (var _i = 0; _i < removeTracks.length; _i++) {
15270 var track = removeTracks[_i];
15272 techTracks.removeTrack_(track);
15277 * Remove {@link TextTrack}s that dont exist in the native track list from our
15278 * emulated {@link TextTrackList}.
15280 * @listens Tech#loadstart
15284 Html5.prototype.removeOldTextTracks_ = function removeOldTextTracks_(e) {
15285 var techTracks = this.textTracks();
15286 var elTracks = this.el().textTracks;
15288 this.removeOldTracks_(techTracks, elTracks);
15292 * Called by {@link Player#play} to play using the `Html5` `Tech`.
15296 Html5.prototype.play = function play() {
15297 var playPromise = this.el_.play();
15299 // Catch/silence error when a pause interrupts a play request
15300 // on browsers which return a promise
15301 if (playPromise !== undefined && typeof playPromise.then === 'function') {
15302 playPromise.then(null, function (e) {});
15307 * Set current time for the `HTML5` tech.
15309 * @param {number} seconds
15310 * Set the current time of the media to this.
15314 Html5.prototype.setCurrentTime = function setCurrentTime(seconds) {
15316 this.el_.currentTime = seconds;
15318 (0, _log2['default'])(e, 'Video is not ready. (Video.js)');
15319 // this.warning(VideoJS.warnings.videoNotReady);
15324 * Get the current duration of the HTML5 media element.
15327 * The duration of the media or 0 if there is no duration.
15331 Html5.prototype.duration = function duration() {
15334 // Android Chrome will report duration as Infinity for VOD HLS until after
15335 // playback has started, which triggers the live display erroneously.
15336 // Return NaN if playback has not started and trigger a durationupdate once
15337 // the duration can be reliably known.
15338 if (this.el_.duration === Infinity && browser.IS_ANDROID && browser.IS_CHROME) {
15339 if (this.el_.currentTime === 0) {
15340 // Wait for the first `timeupdate` with currentTime > 0 - there may be
15342 var checkProgress = function checkProgress() {
15343 if (_this3.el_.currentTime > 0) {
15344 // Trigger durationchange for genuinely live video
15345 if (_this3.el_.duration === Infinity) {
15346 _this3.trigger('durationchange');
15348 _this3.off('timeupdate', checkProgress);
15352 this.on('timeupdate', checkProgress);
15356 return this.el_.duration || NaN;
15360 * Get the current width of the HTML5 media element.
15363 * The width of the HTML5 media element.
15367 Html5.prototype.width = function width() {
15368 return this.el_.offsetWidth;
15372 * Get the current height of the HTML5 media element.
15375 * The heigth of the HTML5 media element.
15379 Html5.prototype.height = function height() {
15380 return this.el_.offsetHeight;
15384 * Proxy iOS `webkitbeginfullscreen` and `webkitendfullscreen` into
15385 * `fullscreenchange` event.
15388 * @fires fullscreenchange
15389 * @listens webkitendfullscreen
15390 * @listens webkitbeginfullscreen
15391 * @listens webkitbeginfullscreen
15395 Html5.prototype.proxyWebkitFullscreen_ = function proxyWebkitFullscreen_() {
15398 if (!('webkitDisplayingFullscreen' in this.el_)) {
15402 var endFn = function endFn() {
15403 this.trigger('fullscreenchange', { isFullscreen: false });
15406 var beginFn = function beginFn() {
15407 this.one('webkitendfullscreen', endFn);
15409 this.trigger('fullscreenchange', { isFullscreen: true });
15412 this.on('webkitbeginfullscreen', beginFn);
15413 this.on('dispose', function () {
15414 _this4.off('webkitbeginfullscreen', beginFn);
15415 _this4.off('webkitendfullscreen', endFn);
15420 * Check if fullscreen is supported on the current playback device.
15422 * @return {boolean}
15423 * - True if fullscreen is supported.
15424 * - False if fullscreen is not supported.
15428 Html5.prototype.supportsFullScreen = function supportsFullScreen() {
15429 if (typeof this.el_.webkitEnterFullScreen === 'function') {
15430 var userAgent = _window2['default'].navigator && _window2['default'].navigator.userAgent || '';
15432 // Seems to be broken in Chromium/Chrome && Safari in Leopard
15433 if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) {
15441 * Request that the `HTML5` Tech enter fullscreen.
15445 Html5.prototype.enterFullScreen = function enterFullScreen() {
15446 var video = this.el_;
15448 if (video.paused && video.networkState <= video.HAVE_METADATA) {
15449 // attempt to prime the video element for programmatic access
15450 // this isn't necessary on the desktop but shouldn't hurt
15453 // playing and pausing synchronously during the transition to fullscreen
15454 // can get iOS ~6.1 devices into a play/pause loop
15455 this.setTimeout(function () {
15457 video.webkitEnterFullScreen();
15460 video.webkitEnterFullScreen();
15465 * Request that the `HTML5` Tech exit fullscreen.
15469 Html5.prototype.exitFullScreen = function exitFullScreen() {
15470 this.el_.webkitExitFullScreen();
15474 * A getter/setter for the `Html5` Tech's source object.
15475 * > Note: Please use {@link Html5#setSource}
15477 * @param {Tech~SourceObject} [src]
15478 * The source object you want to set on the `HTML5` techs element.
15480 * @return {Tech~SourceObject|undefined}
15481 * - The current source object when a source is not passed in.
15482 * - undefined when setting
15484 * @deprecated Since version 5.
15488 Html5.prototype.src = function src(_src) {
15489 if (_src === undefined) {
15490 return this.el_.src;
15493 // Setting src through `src` instead of `setSrc` will be deprecated
15498 * Reset the tech by removing all sources and then calling
15499 * {@link Html5.resetMediaElement}.
15503 Html5.prototype.reset = function reset() {
15504 Html5.resetMediaElement(this.el_);
15508 * Get the current source on the `HTML5` Tech. Falls back to returning the source from
15509 * the HTML5 media element.
15511 * @return {Tech~SourceObject}
15512 * The current source object from the HTML5 tech. With a fallback to the
15517 Html5.prototype.currentSrc = function currentSrc() {
15518 if (this.currentSource_) {
15519 return this.currentSource_.src;
15521 return this.el_.currentSrc;
15525 * Set controls attribute for the HTML5 media Element.
15527 * @param {string} val
15528 * Value to set the controls attribute to
15532 Html5.prototype.setControls = function setControls(val) {
15533 this.el_.controls = !!val;
15537 * Create and returns a remote {@link TextTrack} object.
15539 * @param {string} kind
15540 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
15542 * @param {string} [label]
15543 * Label to identify the text track
15545 * @param {string} [language]
15546 * Two letter language abbreviation
15548 * @return {TextTrack}
15549 * The TextTrack that gets created.
15553 Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) {
15554 if (!this.featuresNativeTextTracks) {
15555 return _Tech.prototype.addTextTrack.call(this, kind, label, language);
15558 return this.el_.addTextTrack(kind, label, language);
15562 * Creates either native TextTrack or an emulated TextTrack depending
15563 * on the value of `featuresNativeTextTracks`
15565 * @param {Object} options
15566 * The object should contain the options to intialize the TextTrack with.
15568 * @param {string} [options.kind]
15569 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
15571 * @param {string} [options.label].
15572 * Label to identify the text track
15574 * @param {string} [options.language]
15575 * Two letter language abbreviation.
15577 * @param {boolean} [options.default]
15578 * Default this track to on.
15580 * @param {string} [options.id]
15581 * The internal id to assign this track.
15583 * @param {string} [options.src]
15584 * A source url for the track.
15586 * @return {HTMLTrackElement}
15587 * The track element that gets created.
15591 Html5.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) {
15592 if (!this.featuresNativeTextTracks) {
15593 return _Tech.prototype.createRemoteTextTrack.call(this, options);
15595 var htmlTrackElement = _document2['default'].createElement('track');
15597 if (options.kind) {
15598 htmlTrackElement.kind = options.kind;
15600 if (options.label) {
15601 htmlTrackElement.label = options.label;
15603 if (options.language || options.srclang) {
15604 htmlTrackElement.srclang = options.language || options.srclang;
15606 if (options['default']) {
15607 htmlTrackElement['default'] = options['default'];
15610 htmlTrackElement.id = options.id;
15613 htmlTrackElement.src = options.src;
15616 return htmlTrackElement;
15620 * Creates a remote text track object and returns an html track element.
15622 * @param {Object} options The object should contain values for
15623 * kind, language, label, and src (location of the WebVTT file)
15624 * @param {Boolean} [manualCleanup=true] if set to false, the TextTrack will be
15625 * automatically removed from the video element whenever the source changes
15626 * @return {HTMLTrackElement} An Html Track Element.
15627 * This can be an emulated {@link HTMLTrackElement} or a native one.
15628 * @deprecated The default value of the "manualCleanup" parameter will default
15629 * to "false" in upcoming versions of Video.js
15633 Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) {
15634 var htmlTrackElement = _Tech.prototype.addRemoteTextTrack.call(this, options, manualCleanup);
15636 if (this.featuresNativeTextTracks) {
15637 this.el().appendChild(htmlTrackElement);
15640 return htmlTrackElement;
15644 * Remove remote `TextTrack` from `TextTrackList` object
15646 * @param {TextTrack} track
15647 * `TextTrack` object to remove
15651 Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
15652 _Tech.prototype.removeRemoteTextTrack.call(this, track);
15654 if (this.featuresNativeTextTracks) {
15655 var tracks = this.$$('track');
15657 var i = tracks.length;
15660 if (track === tracks[i] || track === tracks[i].track) {
15661 this.el().removeChild(tracks[i]);
15668 }(_tech2['default']);
15670 /* HTML5 Support Testing ---------------------------------------------------- */
15672 if (Dom.isReal()) {
15675 * Element for testing browser HTML5 media capabilities
15681 Html5.TEST_VID = _document2['default'].createElement('video');
15682 var track = _document2['default'].createElement('track');
15684 track.kind = 'captions';
15685 track.srclang = 'en';
15686 track.label = 'English';
15687 Html5.TEST_VID.appendChild(track);
15691 * Check if HTML5 media is supported by this browser/device.
15693 * @return {boolean}
15694 * - True if HTML5 media is supported.
15695 * - False if HTML5 media is not supported.
15697 Html5.isSupported = function () {
15698 // IE9 with no Media Player is a LIAR! (#984)
15700 Html5.TEST_VID.volume = 0.5;
15705 return !!(Html5.TEST_VID && Html5.TEST_VID.canPlayType);
15709 * Check if the volume can be changed in this browser/device.
15710 * Volume cannot be changed in a lot of mobile devices.
15711 * Specifically, it can't be changed from 1 on iOS.
15713 * @return {boolean}
15714 * - True if volume can be controlled
15715 * - False otherwise
15717 Html5.canControlVolume = function () {
15718 // IE will error if Windows Media Player not installed #3315
15720 var volume = Html5.TEST_VID.volume;
15722 Html5.TEST_VID.volume = volume / 2 + 0.1;
15723 return volume !== Html5.TEST_VID.volume;
15730 * Check if the playback rate can be changed in this browser/device.
15732 * @return {boolean}
15733 * - True if playback rate can be controlled
15734 * - False otherwise
15736 Html5.canControlPlaybackRate = function () {
15737 // Playback rate API is implemented in Android Chrome, but doesn't do anything
15738 // https://github.com/videojs/video.js/issues/3180
15739 if (browser.IS_ANDROID && browser.IS_CHROME) {
15742 // IE will error if Windows Media Player not installed #3315
15744 var playbackRate = Html5.TEST_VID.playbackRate;
15746 Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1;
15747 return playbackRate !== Html5.TEST_VID.playbackRate;
15754 * Check to see if native `TextTrack`s are supported by this browser/device.
15756 * @return {boolean}
15757 * - True if native `TextTrack`s are supported.
15758 * - False otherwise
15760 Html5.supportsNativeTextTracks = function () {
15761 return browser.IS_ANY_SAFARI;
15765 * Check to see if native `VideoTrack`s are supported by this browser/device
15767 * @return {boolean}
15768 * - True if native `VideoTrack`s are supported.
15769 * - False otherwise
15771 Html5.supportsNativeVideoTracks = function () {
15772 return !!(Html5.TEST_VID && Html5.TEST_VID.videoTracks);
15776 * Check to see if native `AudioTrack`s are supported by this browser/device
15778 * @return {boolean}
15779 * - True if native `AudioTrack`s are supported.
15780 * - False otherwise
15782 Html5.supportsNativeAudioTracks = function () {
15783 return !!(Html5.TEST_VID && Html5.TEST_VID.audioTracks);
15787 * An array of events available on the Html5 tech.
15792 Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'volumechange'];
15795 * Boolean indicating whether the `Tech` supports volume control.
15798 * @default {@link Html5.canControlVolume}
15800 Html5.prototype.featuresVolumeControl = Html5.canControlVolume();
15803 * Boolean indicating whether the `Tech` supports changing the speed at which the media
15805 * - Set player to play 2x (twice) as fast
15806 * - Set player to play 0.5x (half) as fast
15809 * @default {@link Html5.canControlPlaybackRate}
15811 Html5.prototype.featuresPlaybackRate = Html5.canControlPlaybackRate();
15814 * Boolean indicating whether the `HTML5` tech currently supports the media element
15815 * moving in the DOM. iOS breaks if you move the media element, so this is set this to
15816 * false there. Everywhere else this should be true.
15821 Html5.prototype.movingMediaElementInDOM = !browser.IS_IOS;
15823 // TODO: Previous comment: No longer appears to be used. Can probably be removed.
15826 * Boolean indicating whether the `HTML5` tech currently supports automatic media resize
15827 * when going into fullscreen.
15832 Html5.prototype.featuresFullscreenResize = true;
15835 * Boolean indicating whether the `HTML5` tech currently supports the progress event.
15836 * If this is false, manual `progress` events will be triggred instead.
15841 Html5.prototype.featuresProgressEvents = true;
15844 * Boolean indicating whether the `HTML5` tech currently supports the timeupdate event.
15845 * If this is false, manual `timeupdate` events will be triggred instead.
15849 Html5.prototype.featuresTimeupdateEvents = true;
15852 * Boolean indicating whether the `HTML5` tech currently supports native `TextTrack`s.
15855 * @default {@link Html5.supportsNativeTextTracks}
15857 Html5.prototype.featuresNativeTextTracks = Html5.supportsNativeTextTracks();
15860 * Boolean indicating whether the `HTML5` tech currently supports native `VideoTrack`s.
15863 * @default {@link Html5.supportsNativeVideoTracks}
15865 Html5.prototype.featuresNativeVideoTracks = Html5.supportsNativeVideoTracks();
15868 * Boolean indicating whether the `HTML5` tech currently supports native `AudioTrack`s.
15871 * @default {@link Html5.supportsNativeAudioTracks}
15873 Html5.prototype.featuresNativeAudioTracks = Html5.supportsNativeAudioTracks();
15875 // HTML5 Feature detection and Device Fixes --------------------------------- //
15876 var canPlayType = Html5.TEST_VID && Html5.TEST_VID.constructor.prototype.canPlayType;
15877 var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i;
15878 var mp4RE = /^video\/mp4/i;
15880 Html5.patchCanPlayType = function () {
15882 // Android 4.0 and above can play HLS to some extent but it reports being unable to do so
15883 if (browser.ANDROID_VERSION >= 4.0 && !browser.IS_FIREFOX) {
15884 Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
15885 if (type && mpegurlRE.test(type)) {
15888 return canPlayType.call(this, type);
15891 // Override Android 2.2 and less canPlayType method which is broken
15892 } else if (browser.IS_OLD_ANDROID) {
15893 Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
15894 if (type && mp4RE.test(type)) {
15897 return canPlayType.call(this, type);
15902 Html5.unpatchCanPlayType = function () {
15903 var r = Html5.TEST_VID.constructor.prototype.canPlayType;
15905 Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType;
15909 // by default, patch the media element
15910 Html5.patchCanPlayType();
15912 Html5.disposeMediaElement = function (el) {
15917 if (el.parentNode) {
15918 el.parentNode.removeChild(el);
15921 // remove any child track or source nodes to prevent their loading
15922 while (el.hasChildNodes()) {
15923 el.removeChild(el.firstChild);
15926 // remove any src reference. not setting `src=''` because that causes a warning
15928 el.removeAttribute('src');
15930 // force the media element to update its loading state by calling load()
15931 // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793)
15932 if (typeof el.load === 'function') {
15933 // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
15944 Html5.resetMediaElement = function (el) {
15949 var sources = el.querySelectorAll('source');
15950 var i = sources.length;
15953 el.removeChild(sources[i]);
15956 // remove any src reference.
15957 // not setting `src=''` because that throws an error
15958 el.removeAttribute('src');
15960 if (typeof el.load === 'function') {
15961 // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
15972 /* Native HTML5 element property wrapping ----------------------------------- */
15973 // Wrap native properties with a getter
15976 * Get the value of `paused` from the media element. `paused` indicates whether the media element
15977 * is currently paused or not.
15979 * @method Html5#paused
15980 * @return {boolean}
15981 * The value of `paused` from the media element.
15983 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-paused}
15988 * Get the value of `currentTime` from the media element. `currentTime` indicates
15989 * the current second that the media is at in playback.
15991 * @method Html5#currentTime
15993 * The value of `currentTime` from the media element.
15995 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-currenttime}
16000 * Get the value of `buffered` from the media element. `buffered` is a `TimeRange`
16001 * object that represents the parts of the media that are already downloaded and
16002 * available for playback.
16004 * @method Html5#buffered
16005 * @return {TimeRange}
16006 * The value of `buffered` from the media element.
16008 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-buffered}
16013 * Get the value of `volume` from the media element. `volume` indicates
16014 * the current playback volume of audio for a media. `volume` will be a value from 0
16015 * (silent) to 1 (loudest and default).
16017 * @method Html5#volume
16019 * The value of `volume` from the media element. Value will be between 0-1.
16021 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume}
16026 * Get the value of `muted` from the media element. `muted` indicates
16027 * that the volume for the media should be set to silent. This does not actually change
16028 * the `volume` attribute.
16030 * @method Html5#muted
16031 * @return {boolean}
16032 * - True if the value of `volume` should be ignored and the audio set to silent.
16033 * - False if the value of `volume` should be used.
16035 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
16040 * Get the value of `poster` from the media element. `poster` indicates
16041 * that the url of an image file that can/will be shown when no media data is available.
16043 * @method Html5#poster
16045 * The value of `poster` from the media element. Value will be a url to an
16048 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-video-poster}
16053 * Get the value of `preload` from the media element. `preload` indicates
16054 * what should download before the media is interacted with. It can have the following
16056 * - none: nothing should be downloaded
16057 * - metadata: poster and the first few frames of the media may be downloaded to get
16058 * media dimensions and other metadata
16059 * - auto: allow the media and metadata for the media to be downloaded before
16062 * @method Html5#preload
16064 * The value of `preload` from the media element. Will be 'none', 'metadata',
16067 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload}
16072 * Get the value of `autoplay` from the media element. `autoplay` indicates
16073 * that the media should start to play as soon as the page is ready.
16075 * @method Html5#autoplay
16076 * @return {boolean}
16077 * - The value of `autoplay` from the media element.
16078 * - True indicates that the media should start as soon as the page loads.
16079 * - False indicates that the media should not start as soon as the page loads.
16081 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
16086 * Get the value of `controls` from the media element. `controls` indicates
16087 * whether the native media controls should be shown or hidden.
16089 * @method Html5#controls
16090 * @return {boolean}
16091 * - The value of `controls` from the media element.
16092 * - True indicates that native controls should be showing.
16093 * - False indicates that native controls should be hidden.
16095 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-controls}
16100 * Get the value of `loop` from the media element. `loop` indicates
16101 * that the media should return to the start of the media and continue playing once
16102 * it reaches the end.
16104 * @method Html5#loop
16105 * @return {boolean}
16106 * - The value of `loop` from the media element.
16107 * - True indicates that playback should seek back to start once
16108 * the end of a media is reached.
16109 * - False indicates that playback should not loop back to the start when the
16110 * end of the media is reached.
16112 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
16117 * Get the value of the `error` from the media element. `error` indicates any
16118 * MediaError that may have occured during playback. If error returns null there is no
16121 * @method Html5#error
16122 * @return {MediaError|null}
16123 * The value of `error` from the media element. Will be `MediaError` if there
16124 * is a current error and null otherwise.
16126 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-error}
16131 * Get the value of `seeking` from the media element. `seeking` indicates whether the
16132 * media is currently seeking to a new position or not.
16134 * @method Html5#seeking
16135 * @return {boolean}
16136 * - The value of `seeking` from the media element.
16137 * - True indicates that the media is currently seeking to a new position.
16138 * - Flase indicates that the media is not seeking to a new position at this time.
16140 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seeking}
16145 * Get the value of `seekable` from the media element. `seekable` returns a
16146 * `TimeRange` object indicating ranges of time that can currently be `seeked` to.
16148 * @method Html5#seekable
16149 * @return {TimeRange}
16150 * The value of `seekable` from the media element. A `TimeRange` object
16151 * indicating the current ranges of time that can be seeked to.
16153 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seekable}
16158 * Get the value of `ended` from the media element. `ended` indicates whether
16159 * the media has reached the end or not.
16161 * @method Html5#ended
16162 * @return {boolean}
16163 * - The value of `ended` from the media element.
16164 * - True indicates that the media has ended.
16165 * - False indicates that the media has not ended.
16167 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended}
16172 * Get the value of `defaultMuted` from the media element. `defaultMuted` indicates
16173 * whether the media should start muted or not. Only changes the default state of the
16174 * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
16177 * @method Html5#defaultMuted
16178 * @return {boolean}
16179 * - The value of `defaultMuted` from the media element.
16180 * - True indicates that the media should start muted.
16181 * - False indicates that the media should not start muted
16183 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
16188 * Get the value of `playbackRate` from the media element. `playbackRate` indicates
16189 * the rate at which the media is currently playing back. Examples:
16190 * - if playbackRate is set to 2, media will play twice as fast.
16191 * - if playbackRate is set to 0.5, media will play half as fast.
16193 * @method Html5#playbackRate
16195 * The value of `playbackRate` from the media element. A number indicating
16196 * the current playback speed of the media, where 1 is normal speed.
16198 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
16203 * Get the value of `played` from the media element. `played` returns a `TimeRange`
16204 * object representing points in the media timeline that have been played.
16206 * @method Html5#played
16207 * @return {TimeRange}
16208 * The value of `played` from the media element. A `TimeRange` object indicating
16209 * the ranges of time that have been played.
16211 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-played}
16216 * Get the value of `networkState` from the media element. `networkState` indicates
16217 * the current network state. It returns an enumeration from the following list:
16218 * - 0: NETWORK_EMPTY
16220 * - 2: NETWORK_LOADING
16221 * - 3: NETWORK_NO_SOURCE
16223 * @method Html5#networkState
16225 * The value of `networkState` from the media element. This will be a number
16226 * from the list in the description.
16228 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-networkstate}
16233 * Get the value of `readyState` from the media element. `readyState` indicates
16234 * the current state of the media element. It returns an enumeration from the
16236 * - 0: HAVE_NOTHING
16237 * - 1: HAVE_METADATA
16238 * - 2: HAVE_CURRENT_DATA
16239 * - 3: HAVE_FUTURE_DATA
16240 * - 4: HAVE_ENOUGH_DATA
16242 * @method Html5#readyState
16244 * The value of `readyState` from the media element. This will be a number
16245 * from the list in the description.
16247 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#ready-states}
16252 * Get the value of `videoWidth` from the video element. `videoWidth` indicates
16253 * the current width of the video in css pixels.
16255 * @method Html5#videoWidth
16257 * The value of `videoWidth` from the video element. This will be a number
16260 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth}
16265 * Get the value of `videoHeight` from the video element. `videoHeigth` indicates
16266 * the current height of the video in css pixels.
16268 * @method Html5#videoHeight
16270 * The value of `videoHeight` from the video element. This will be a number
16273 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth}
16275 'videoHeight'].forEach(function (prop) {
16276 Html5.prototype[prop] = function () {
16277 return this.el_[prop];
16281 // Wrap native properties with a setter in this format:
16282 // set + toTitleCase(name)
16285 * Set the value of `volume` on the media element. `volume` indicates the current
16286 * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
16289 * @method Html5#setVolume
16290 * @param {number} percentAsDecimal
16291 * The volume percent as a decimal. Valid range is from 0-1.
16293 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume}
16298 * Set the value of `muted` on the media element. `muted` indicates the current
16299 * audio level should be silent.
16301 * @method Html5#setMuted
16302 * @param {boolean} muted
16303 * - True if the audio should be set to silent
16304 * - False otherwise
16306 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
16311 * Set the value of `src` on the media element. `src` indicates the current
16312 * {@link Tech~SourceObject} for the media.
16314 * @method Html5#setSrc
16315 * @param {Tech~SourceObject} src
16316 * The source object to set as the current source.
16318 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-src}
16323 * Set the value of `poster` on the media element. `poster` is the url to
16324 * an image file that can/will be shown when no media data is available.
16326 * @method Html5#setPoster
16327 * @param {string} poster
16328 * The url to an image that should be used as the `poster` for the media
16331 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-poster}
16336 * Set the value of `preload` on the media element. `preload` indicates
16337 * what should download before the media is interacted with. It can have the following
16339 * - none: nothing should be downloaded
16340 * - metadata: poster and the first few frames of the media may be downloaded to get
16341 * media dimensions and other metadata
16342 * - auto: allow the media and metadata for the media to be downloaded before
16345 * @method Html5#setPreload
16346 * @param {string} preload
16347 * The value of `preload` to set on the media element. Must be 'none', 'metadata',
16350 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload}
16355 * Set the value of `autoplay` on the media element. `autoplay` indicates
16356 * that the media should start to play as soon as the page is ready.
16358 * @method Html5#setAutoplay
16359 * @param {boolean} autoplay
16360 * - True indicates that the media should start as soon as the page loads.
16361 * - False indicates that the media should not start as soon as the page loads.
16363 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
16368 * Set the value of `loop` on the media element. `loop` indicates
16369 * that the media should return to the start of the media and continue playing once
16370 * it reaches the end.
16372 * @method Html5#setLoop
16373 * @param {boolean} loop
16374 * - True indicates that playback should seek back to start once
16375 * the end of a media is reached.
16376 * - False indicates that playback should not loop back to the start when the
16377 * end of the media is reached.
16379 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
16384 * Set the value of `playbackRate` on the media element. `playbackRate` indicates
16385 * the rate at which the media should play back. Examples:
16386 * - if playbackRate is set to 2, media will play twice as fast.
16387 * - if playbackRate is set to 0.5, media will play half as fast.
16389 * @method Html5#setPlaybackRate
16391 * The value of `playbackRate` from the media element. A number indicating
16392 * the current playback speed of the media, where 1 is normal speed.
16394 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
16396 'playbackRate'].forEach(function (prop) {
16397 Html5.prototype['set' + (0, _toTitleCase2['default'])(prop)] = function (v) {
16398 this.el_[prop] = v;
16402 // wrap native functions with a function
16405 * A wrapper around the media elements `pause` function. This will call the `HTML5`
16406 * media elements `pause` function.
16408 * @method Html5#pause
16409 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-pause}
16414 * A wrapper around the media elements `load` function. This will call the `HTML5`s
16415 * media element `load` function.
16417 * @method Html5#load
16418 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-load}
16420 'load'].forEach(function (prop) {
16421 Html5.prototype[prop] = function () {
16422 return this.el_[prop]();
16426 _tech2['default'].withSourceHandlers(Html5);
16429 * Native source handler for Html5, simply passes the source to the media element.
16431 * @proprety {Tech~SourceObject} source
16432 * The source object
16434 * @proprety {Html5} tech
16435 * The instance of the HTML5 tech.
16437 Html5.nativeSourceHandler = {};
16440 * Check if the media element can play the given mime type.
16442 * @param {string} type
16443 * The mimetype to check
16446 * 'probably', 'maybe', or '' (empty string)
16448 Html5.nativeSourceHandler.canPlayType = function (type) {
16449 // IE9 on Windows 7 without MediaPlayer throws an error here
16450 // https://github.com/videojs/video.js/issues/519
16452 return Html5.TEST_VID.canPlayType(type);
16459 * Check if the media element can handle a source natively.
16461 * @param {Tech~SourceObject} source
16462 * The source object
16464 * @param {Object} [options]
16465 * Options to be passed to the tech.
16468 * 'probably', 'maybe', or '' (empty string).
16470 Html5.nativeSourceHandler.canHandleSource = function (source, options) {
16472 // If a type was provided we should rely on that
16474 return Html5.nativeSourceHandler.canPlayType(source.type);
16476 // If no type, fall back to checking 'video/[EXTENSION]'
16477 } else if (source.src) {
16478 var ext = Url.getFileExtension(source.src);
16480 return Html5.nativeSourceHandler.canPlayType('video/' + ext);
16487 * Pass the source to the native media element.
16489 * @param {Tech~SourceObject} source
16490 * The source object
16492 * @param {Html5} tech
16493 * The instance of the Html5 tech
16495 * @param {Object} [options]
16496 * The options to pass to the source
16498 Html5.nativeSourceHandler.handleSource = function (source, tech, options) {
16499 tech.setSrc(source.src);
16503 * A noop for the native dispose function, as cleanup is not needed.
16505 Html5.nativeSourceHandler.dispose = function () {};
16507 // Register the native source handler
16508 Html5.registerSourceHandler(Html5.nativeSourceHandler);
16510 _component2['default'].registerComponent('Html5', Html5);
16511 _tech2['default'].registerTech('Html5', Html5);
16512 exports['default'] = Html5;
16514 },{"5":5,"62":62,"78":78,"81":81,"83":83,"86":86,"87":87,"88":88,"91":91,"92":92,"94":94,"95":95,"98":98}],61:[function(_dereq_,module,exports){
16517 exports.__esModule = true;
16519 var _component = _dereq_(5);
16521 var _component2 = _interopRequireDefault(_component);
16523 var _tech = _dereq_(62);
16525 var _tech2 = _interopRequireDefault(_tech);
16527 var _toTitleCase = _dereq_(91);
16529 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
16531 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16533 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16535 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
16537 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
16543 * The `MediaLoader` is the `Component` that decides which playback technology to load
16544 * when a player is initialized.
16546 * @extends Component
16548 var MediaLoader = function (_Component) {
16549 _inherits(MediaLoader, _Component);
16552 * Create an instance of this class.
16554 * @param {Player} player
16555 * The `Player` that this class should attach to.
16557 * @param {Object} [options]
16558 * The key/value stroe of player options.
16560 * @param {Component~ReadyCallback} [ready]
16561 * The function that is run when this component is ready.
16563 function MediaLoader(player, options, ready) {
16564 _classCallCheck(this, MediaLoader);
16566 // If there are no sources when the player is initialized,
16567 // load the first supported playback technology.
16569 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready));
16571 if (!options.playerOptions.sources || options.playerOptions.sources.length === 0) {
16572 for (var i = 0, j = options.playerOptions.techOrder; i < j.length; i++) {
16573 var techName = (0, _toTitleCase2['default'])(j[i]);
16574 var tech = _tech2['default'].getTech(techName);
16576 // Support old behavior of techs being registered as components.
16577 // Remove once that deprecated behavior is removed.
16579 tech = _component2['default'].getComponent(techName);
16582 // Check if the browser supports this technology
16583 if (tech && tech.isSupported()) {
16584 player.loadTech_(techName);
16589 // Loop through playback technologies (HTML5, Flash) and check for support.
16590 // Then load the best source.
16591 // A few assumptions here:
16592 // All playback technologies respect preload false.
16593 player.src(options.playerOptions.sources);
16598 return MediaLoader;
16599 }(_component2['default']);
16601 _component2['default'].registerComponent('MediaLoader', MediaLoader);
16602 exports['default'] = MediaLoader;
16604 },{"5":5,"62":62,"91":91}],62:[function(_dereq_,module,exports){
16607 exports.__esModule = true;
16609 var _component = _dereq_(5);
16611 var _component2 = _interopRequireDefault(_component);
16613 var _htmlTrackElement = _dereq_(66);
16615 var _htmlTrackElement2 = _interopRequireDefault(_htmlTrackElement);
16617 var _htmlTrackElementList = _dereq_(65);
16619 var _htmlTrackElementList2 = _interopRequireDefault(_htmlTrackElementList);
16621 var _mergeOptions = _dereq_(87);
16623 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
16625 var _textTrack = _dereq_(72);
16627 var _textTrack2 = _interopRequireDefault(_textTrack);
16629 var _textTrackList = _dereq_(70);
16631 var _textTrackList2 = _interopRequireDefault(_textTrackList);
16633 var _videoTrackList = _dereq_(76);
16635 var _videoTrackList2 = _interopRequireDefault(_videoTrackList);
16637 var _audioTrackList = _dereq_(63);
16639 var _audioTrackList2 = _interopRequireDefault(_audioTrackList);
16641 var _fn = _dereq_(83);
16643 var Fn = _interopRequireWildcard(_fn);
16645 var _log = _dereq_(86);
16647 var _log2 = _interopRequireDefault(_log);
16649 var _timeRanges = _dereq_(90);
16651 var _buffer = _dereq_(79);
16653 var _mediaError = _dereq_(46);
16655 var _mediaError2 = _interopRequireDefault(_mediaError);
16657 var _window = _dereq_(95);
16659 var _window2 = _interopRequireDefault(_window);
16661 var _document = _dereq_(94);
16663 var _document2 = _interopRequireDefault(_document);
16665 var _obj = _dereq_(88);
16667 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
16669 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16671 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16673 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
16675 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
16680 * An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string
16681 * that just contains the src url alone.
16682 * * `var SourceObject = {src: 'http://ex.com/video.mp4', type: 'video/mp4'};`
16683 * `var SourceString = 'http://example.com/some-video.mp4';`
16685 * @typedef {Object|string} Tech~SourceObject
16687 * @property {string} src
16688 * The url to the source
16690 * @property {string} type
16691 * The mime type of the source
16695 * A function used by {@link Tech} to create a new {@link TextTrack}.
16697 * @param {Tech} self
16698 * An instance of the Tech class.
16700 * @param {string} kind
16701 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
16703 * @param {string} [label]
16704 * Label to identify the text track
16706 * @param {string} [language]
16707 * Two letter language abbreviation
16709 * @param {Object} [options={}]
16710 * An object with additional text track options
16712 * @return {TextTrack}
16713 * The text track that was created.
16715 function createTrackHelper(self, kind, label, language) {
16716 var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
16718 var tracks = self.textTracks();
16720 options.kind = kind;
16723 options.label = label;
16726 options.language = language;
16728 options.tech = self;
16730 var track = new _textTrack2['default'](options);
16732 tracks.addTrack_(track);
16738 * This is the base class for media playback technology controllers, such as
16739 * {@link Flash} and {@link HTML5}
16741 * @extends Component
16744 var Tech = function (_Component) {
16745 _inherits(Tech, _Component);
16748 * Create an instance of this Tech.
16750 * @param {Object} [options]
16751 * The key/value store of player options.
16753 * @param {Component~ReadyCallback} ready
16754 * Callback function to call when the `HTML5` Tech is ready.
16757 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
16758 var ready = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
16760 _classCallCheck(this, Tech);
16762 // we don't want the tech to report user activity automatically.
16763 // This is done manually in addControlsListeners
16764 options.reportTouchActivity = false;
16766 // keep track of whether the current source has played at all to
16767 // implement a very limited played()
16768 var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready));
16770 _this.hasStarted_ = false;
16771 _this.on('playing', function () {
16772 this.hasStarted_ = true;
16774 _this.on('loadstart', function () {
16775 this.hasStarted_ = false;
16778 _this.textTracks_ = options.textTracks;
16779 _this.videoTracks_ = options.videoTracks;
16780 _this.audioTracks_ = options.audioTracks;
16782 // Manually track progress in cases where the browser/flash player doesn't report it.
16783 if (!_this.featuresProgressEvents) {
16784 _this.manualProgressOn();
16787 // Manually track timeupdates in cases where the browser/flash player doesn't report it.
16788 if (!_this.featuresTimeupdateEvents) {
16789 _this.manualTimeUpdatesOn();
16792 ['Text', 'Audio', 'Video'].forEach(function (track) {
16793 if (options['native' + track + 'Tracks'] === false) {
16794 _this['featuresNative' + track + 'Tracks'] = false;
16798 if (options.nativeCaptions === false) {
16799 _this.featuresNativeTextTracks = false;
16802 if (!_this.featuresNativeTextTracks) {
16803 _this.emulateTextTracks();
16806 _this.autoRemoteTextTracks_ = new _textTrackList2['default']();
16808 _this.initTextTrackListeners();
16809 _this.initTrackListeners();
16811 // Turn on component tap events only if not using native controls
16812 if (!options.nativeControlsForTouch) {
16813 _this.emitTapEvents();
16816 if (_this.constructor) {
16817 _this.name_ = _this.constructor.name || 'Unknown Tech';
16822 /* Fallbacks for unsupported event types
16823 ================================================================================ */
16826 * Polyfill the `progress` event for browsers that don't support it natively.
16828 * @see {@link Tech#trackProgress}
16832 Tech.prototype.manualProgressOn = function manualProgressOn() {
16833 this.on('durationchange', this.onDurationChange);
16835 this.manualProgress = true;
16837 // Trigger progress watching when a source begins loading
16838 this.one('ready', this.trackProgress);
16842 * Turn off the polyfill for `progress` events that was created in
16843 * {@link Tech#manualProgressOn}
16847 Tech.prototype.manualProgressOff = function manualProgressOff() {
16848 this.manualProgress = false;
16849 this.stopTrackingProgress();
16851 this.off('durationchange', this.onDurationChange);
16855 * This is used to trigger a `progress` event when the buffered percent changes. It
16856 * sets an interval function that will be called every 500 milliseconds to check if the
16857 * buffer end percent has changed.
16859 * > This function is called by {@link Tech#manualProgressOn}
16861 * @param {EventTarget~Event} event
16862 * The `ready` event that caused this to run.
16864 * @listens Tech#ready
16865 * @fires Tech#progress
16869 Tech.prototype.trackProgress = function trackProgress(event) {
16870 this.stopTrackingProgress();
16871 this.progressInterval = this.setInterval(Fn.bind(this, function () {
16872 // Don't trigger unless buffered amount is greater than last time
16874 var numBufferedPercent = this.bufferedPercent();
16876 if (this.bufferedPercent_ !== numBufferedPercent) {
16878 * See {@link Player#progress}
16880 * @event Tech#progress
16881 * @type {EventTarget~Event}
16883 this.trigger('progress');
16886 this.bufferedPercent_ = numBufferedPercent;
16888 if (numBufferedPercent === 1) {
16889 this.stopTrackingProgress();
16895 * Update our internal duration on a `durationchange` event by calling
16896 * {@link Tech#duration}.
16898 * @param {EventTarget~Event} event
16899 * The `durationchange` event that caused this to run.
16901 * @listens Tech#durationchange
16905 Tech.prototype.onDurationChange = function onDurationChange(event) {
16906 this.duration_ = this.duration();
16910 * Get and create a `TimeRange` object for buffering.
16912 * @return {TimeRange}
16913 * The time range object that was created.
16917 Tech.prototype.buffered = function buffered() {
16918 return (0, _timeRanges.createTimeRange)(0, 0);
16922 * Get the percentage of the current video that is currently buffered.
16925 * A number from 0 to 1 that represents the decimal percentage of the
16926 * video that is buffered.
16931 Tech.prototype.bufferedPercent = function bufferedPercent() {
16932 return (0, _buffer.bufferedPercent)(this.buffered(), this.duration_);
16936 * Turn off the polyfill for `progress` events that was created in
16937 * {@link Tech#manualProgressOn}
16938 * Stop manually tracking progress events by clearing the interval that was set in
16939 * {@link Tech#trackProgress}.
16943 Tech.prototype.stopTrackingProgress = function stopTrackingProgress() {
16944 this.clearInterval(this.progressInterval);
16948 * Polyfill the `timeupdate` event for browsers that don't support it.
16950 * @see {@link Tech#trackCurrentTime}
16954 Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() {
16955 this.manualTimeUpdates = true;
16957 this.on('play', this.trackCurrentTime);
16958 this.on('pause', this.stopTrackingCurrentTime);
16962 * Turn off the polyfill for `timeupdate` events that was created in
16963 * {@link Tech#manualTimeUpdatesOn}
16967 Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() {
16968 this.manualTimeUpdates = false;
16969 this.stopTrackingCurrentTime();
16970 this.off('play', this.trackCurrentTime);
16971 this.off('pause', this.stopTrackingCurrentTime);
16975 * Sets up an interval function to track current time and trigger `timeupdate` every
16976 * 250 milliseconds.
16978 * @listens Tech#play
16979 * @triggers Tech#timeupdate
16983 Tech.prototype.trackCurrentTime = function trackCurrentTime() {
16984 if (this.currentTimeInterval) {
16985 this.stopTrackingCurrentTime();
16987 this.currentTimeInterval = this.setInterval(function () {
16989 * Triggered at an interval of 250ms to indicated that time is passing in the video.
16991 * @event Tech#timeupdate
16992 * @type {EventTarget~Event}
16994 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
16996 // 42 = 24 fps // 250 is what Webkit uses // FF uses 15
17001 * Stop the interval function created in {@link Tech#trackCurrentTime} so that the
17002 * `timeupdate` event is no longer triggered.
17004 * @listens {Tech#pause}
17008 Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() {
17009 this.clearInterval(this.currentTimeInterval);
17011 // #1002 - if the video ends right before the next timeupdate would happen,
17012 // the progress bar won't make it all the way to the end
17013 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
17017 * Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList},
17018 * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech.
17020 * @fires Component#dispose
17024 Tech.prototype.dispose = function dispose() {
17026 // clear out all tracks because we can't reuse them between techs
17027 this.clearTracks(['audio', 'video', 'text']);
17029 // Turn off any manual progress or timeupdate tracking
17030 if (this.manualProgress) {
17031 this.manualProgressOff();
17034 if (this.manualTimeUpdates) {
17035 this.manualTimeUpdatesOff();
17038 _Component.prototype.dispose.call(this);
17042 * Clear out a single `TrackList` or an array of `TrackLists` given their names.
17044 * > Note: Techs without source handlers should call this between sources for `video`
17045 * & `audio` tracks. You don't want to use them between tracks!
17047 * @param {string[]|string} types
17048 * TrackList names to clear, valid names are `video`, `audio`, and
17053 Tech.prototype.clearTracks = function clearTracks(types) {
17056 types = [].concat(types);
17057 // clear out all tracks because we can't reuse them between techs
17058 types.forEach(function (type) {
17059 var list = _this2[type + 'Tracks']() || [];
17060 var i = list.length;
17063 var track = list[i];
17065 if (type === 'text') {
17066 _this2.removeRemoteTextTrack(track);
17068 list.removeTrack_(track);
17074 * Remove any TextTracks added via addRemoteTextTrack that are
17075 * flagged for automatic garbage collection
17079 Tech.prototype.cleanupAutoTextTracks = function cleanupAutoTextTracks() {
17080 var list = this.autoRemoteTextTracks_ || [];
17081 var i = list.length;
17084 var track = list[i];
17086 this.removeRemoteTextTrack(track);
17091 * Reset the tech, which will removes all sources and reset the internal readyState.
17097 Tech.prototype.reset = function reset() {};
17100 * Get or set an error on the Tech.
17102 * @param {MediaError} [err]
17103 * Error to set on the Tech
17105 * @return {MediaError|null}
17106 * The current error object on the tech, or null if there isn't one.
17110 Tech.prototype.error = function error(err) {
17111 if (err !== undefined) {
17112 this.error_ = new _mediaError2['default'](err);
17113 this.trigger('error');
17115 return this.error_;
17119 * Returns the `TimeRange`s that have been played through for the current source.
17121 * > NOTE: This implementation is incomplete. It does not track the played `TimeRange`.
17122 * It only checks wether the source has played at all or not.
17124 * @return {TimeRange}
17125 * - A single time range if this video has played
17126 * - An empty set of ranges if not.
17130 Tech.prototype.played = function played() {
17131 if (this.hasStarted_) {
17132 return (0, _timeRanges.createTimeRange)(0, 0);
17134 return (0, _timeRanges.createTimeRange)();
17138 * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was
17139 * previously called.
17141 * @fires Tech#timeupdate
17145 Tech.prototype.setCurrentTime = function setCurrentTime() {
17146 // improve the accuracy of manual timeupdates
17147 if (this.manualTimeUpdates) {
17149 * A manual `timeupdate` event.
17151 * @event Tech#timeupdate
17152 * @type {EventTarget~Event}
17154 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
17159 * Turn on listeners for {@link TextTrackList} events. This adds
17160 * {@link EventTarget~EventListeners} for `texttrackchange`, `addtrack` and
17163 * @fires Tech#texttrackchange
17167 Tech.prototype.initTextTrackListeners = function initTextTrackListeners() {
17168 var textTrackListChanges = Fn.bind(this, function () {
17170 * Triggered when tracks are added or removed on the Tech {@link TextTrackList}
17172 * @event Tech#texttrackchange
17173 * @type {EventTarget~Event}
17175 this.trigger('texttrackchange');
17178 var tracks = this.textTracks();
17184 tracks.addEventListener('removetrack', textTrackListChanges);
17185 tracks.addEventListener('addtrack', textTrackListChanges);
17187 this.on('dispose', Fn.bind(this, function () {
17188 tracks.removeEventListener('removetrack', textTrackListChanges);
17189 tracks.removeEventListener('addtrack', textTrackListChanges);
17194 * Turn on listeners for {@link VideoTrackList} and {@link {AudioTrackList} events.
17195 * This adds {@link EventTarget~EventListeners} for `addtrack`, and `removetrack`.
17197 * @fires Tech#audiotrackchange
17198 * @fires Tech#videotrackchange
17202 Tech.prototype.initTrackListeners = function initTrackListeners() {
17205 var trackTypes = ['video', 'audio'];
17207 trackTypes.forEach(function (type) {
17209 * Triggered when tracks are added or removed on the Tech {@link AudioTrackList}
17211 * @event Tech#audiotrackchange
17212 * @type {EventTarget~Event}
17216 * Triggered when tracks are added or removed on the Tech {@link VideoTrackList}
17218 * @event Tech#videotrackchange
17219 * @type {EventTarget~Event}
17221 var trackListChanges = function trackListChanges() {
17222 _this3.trigger(type + 'trackchange');
17225 var tracks = _this3[type + 'Tracks']();
17227 tracks.addEventListener('removetrack', trackListChanges);
17228 tracks.addEventListener('addtrack', trackListChanges);
17230 _this3.on('dispose', function () {
17231 tracks.removeEventListener('removetrack', trackListChanges);
17232 tracks.removeEventListener('addtrack', trackListChanges);
17238 * Emulate TextTracks using vtt.js if necessary
17240 * @fires Tech#vttjsloaded
17241 * @fires Tech#vttjserror
17245 Tech.prototype.addWebVttScript_ = function addWebVttScript_() {
17248 if (_window2['default'].WebVTT) {
17252 // Initially, Tech.el_ is a child of a dummy-div wait until the Component system
17253 // signals that the Tech is ready at which point Tech.el_ is part of the DOM
17254 // before inserting the WebVTT script
17255 if (_document2['default'].body.contains(this.el())) {
17258 // load via require if available and vtt.js script location was not passed in
17259 // as an option. novtt builds will turn the above require call into an empty object
17260 // which will cause this if check to always fail.
17261 if (!this.options_['vtt.js'] && (0, _obj.isPlain)(vtt) && Object.keys(vtt).length > 0) {
17262 this.trigger('vttjsloaded');
17266 // load vtt.js via the script location option or the cdn of no location was
17268 var script = _document2['default'].createElement('script');
17270 script.src = this.options_['vtt.js'] || 'https://vjs.zencdn.net/vttjs/0.12.3/vtt.min.js';
17271 script.onload = function () {
17273 * Fired when vtt.js is loaded.
17275 * @event Tech#vttjsloaded
17276 * @type {EventTarget~Event}
17278 _this4.trigger('vttjsloaded');
17280 script.onerror = function () {
17282 * Fired when vtt.js was not loaded due to an error
17284 * @event Tech#vttjsloaded
17285 * @type {EventTarget~Event}
17287 _this4.trigger('vttjserror');
17289 this.on('dispose', function () {
17290 script.onload = null;
17291 script.onerror = null;
17293 // but have not loaded yet and we set it to true before the inject so that
17294 // we don't overwrite the injected window.WebVTT if it loads right away
17295 _window2['default'].WebVTT = true;
17296 this.el().parentNode.appendChild(script);
17298 this.ready(this.addWebVttScript_);
17303 * Emulate texttracks
17305 * @method emulateTextTracks
17309 Tech.prototype.emulateTextTracks = function emulateTextTracks() {
17312 var tracks = this.textTracks();
17318 var remoteTracks = this.remoteTextTracks();
17319 var handleAddTrack = function handleAddTrack(e) {
17320 return tracks.addTrack_(e.track);
17322 var handleRemoveTrack = function handleRemoveTrack(e) {
17323 return tracks.removeTrack_(e.track);
17326 remoteTracks.on('addtrack', handleAddTrack);
17327 remoteTracks.on('removetrack', handleRemoveTrack);
17329 this.addWebVttScript_();
17331 var updateDisplay = function updateDisplay() {
17332 return _this5.trigger('texttrackchange');
17335 var textTracksChanges = function textTracksChanges() {
17338 for (var i = 0; i < tracks.length; i++) {
17339 var track = tracks[i];
17341 track.removeEventListener('cuechange', updateDisplay);
17342 if (track.mode === 'showing') {
17343 track.addEventListener('cuechange', updateDisplay);
17348 textTracksChanges();
17349 tracks.addEventListener('change', textTracksChanges);
17350 tracks.addEventListener('addtrack', textTracksChanges);
17351 tracks.addEventListener('removetrack', textTracksChanges);
17353 this.on('dispose', function () {
17354 remoteTracks.off('addtrack', handleAddTrack);
17355 remoteTracks.off('removetrack', handleRemoveTrack);
17356 tracks.removeEventListener('change', textTracksChanges);
17357 tracks.removeEventListener('addtrack', textTracksChanges);
17358 tracks.removeEventListener('removetrack', textTracksChanges);
17360 for (var i = 0; i < tracks.length; i++) {
17361 var track = tracks[i];
17363 track.removeEventListener('cuechange', updateDisplay);
17369 * Get the `Tech`s {@link VideoTrackList}.
17371 * @return {VideoTrackList}
17372 * The video track list that the Tech is currently using.
17376 Tech.prototype.videoTracks = function videoTracks() {
17377 this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default']();
17378 return this.videoTracks_;
17382 * Get the `Tech`s {@link AudioTrackList}.
17384 * @return {AudioTrackList}
17385 * The audio track list that the Tech is currently using.
17389 Tech.prototype.audioTracks = function audioTracks() {
17390 this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default']();
17391 return this.audioTracks_;
17395 * Get the `Tech`s {@link TextTrackList}.
17397 * @return {TextTrackList}
17398 * The text track list that the Tech is currently using.
17402 Tech.prototype.textTracks = function textTracks() {
17403 this.textTracks_ = this.textTracks_ || new _textTrackList2['default']();
17404 return this.textTracks_;
17408 * Get the `Tech`s remote {@link TextTrackList}, which is created from elements
17409 * that were added to the DOM.
17411 * @return {TextTrackList}
17412 * The remote text track list that the Tech is currently using.
17416 Tech.prototype.remoteTextTracks = function remoteTextTracks() {
17417 this.remoteTextTracks_ = this.remoteTextTracks_ || new _textTrackList2['default']();
17418 return this.remoteTextTracks_;
17422 * Get The `Tech`s {HTMLTrackElementList}, which are the elements in the DOM that are
17423 * being used as TextTracks.
17425 * @return {HTMLTrackElementList}
17426 * The current HTML track elements that exist for the tech.
17430 Tech.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
17431 this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new _htmlTrackElementList2['default']();
17432 return this.remoteTextTrackEls_;
17436 * Create and returns a remote {@link TextTrack} object.
17438 * @param {string} kind
17439 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
17441 * @param {string} [label]
17442 * Label to identify the text track
17444 * @param {string} [language]
17445 * Two letter language abbreviation
17447 * @return {TextTrack}
17448 * The TextTrack that gets created.
17452 Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) {
17454 throw new Error('TextTrack kind is required but was not provided');
17457 return createTrackHelper(this, kind, label, language);
17461 * Create an emulated TextTrack for use by addRemoteTextTrack
17463 * This is intended to be overridden by classes that inherit from
17464 * Tech in order to create native or custom TextTracks.
17466 * @param {Object} options
17467 * The object should contain the options to initialize the TextTrack with.
17469 * @param {string} [options.kind]
17470 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
17472 * @param {string} [options.label].
17473 * Label to identify the text track
17475 * @param {string} [options.language]
17476 * Two letter language abbreviation.
17478 * @return {HTMLTrackElement}
17479 * The track element that gets created.
17483 Tech.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) {
17484 var track = (0, _mergeOptions2['default'])(options, {
17488 return new _htmlTrackElement2['default'](track);
17492 * Creates a remote text track object and returns an html track element.
17494 * > Note: This can be an emulated {@link HTMLTrackElement} or a native one.
17496 * @param {Object} options
17497 * See {@link Tech#createRemoteTextTrack} for more detailed properties.
17499 * @param {boolean} [manualCleanup=true]
17500 * - When false: the TextTrack will be automatically removed from the video
17501 * element whenever the source changes
17502 * - When True: The TextTrack will have to be cleaned up manually
17504 * @return {HTMLTrackElement}
17505 * An Html Track Element.
17507 * @deprecated The default functionality for this function will be equivalent
17508 * to "manualCleanup=false" in the future. The manualCleanup parameter will
17513 Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack() {
17514 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
17515 var manualCleanup = arguments[1];
17517 var htmlTrackElement = this.createRemoteTextTrack(options);
17519 if (manualCleanup !== true && manualCleanup !== false) {
17520 // deprecation warning
17521 _log2['default'].warn('Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js');
17522 manualCleanup = true;
17525 // store HTMLTrackElement and TextTrack to remote list
17526 this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
17527 this.remoteTextTracks().addTrack_(htmlTrackElement.track);
17529 if (manualCleanup !== true) {
17530 // create the TextTrackList if it doesn't exist
17531 this.autoRemoteTextTracks_.addTrack_(htmlTrackElement.track);
17534 return htmlTrackElement;
17538 * Remove a remote text track from the remote `TextTrackList`.
17540 * @param {TextTrack} track
17541 * `TextTrack` to remove from the `TextTrackList`
17545 Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
17546 var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
17548 // remove HTMLTrackElement and TextTrack from remote list
17549 this.remoteTextTrackEls().removeTrackElement_(trackElement);
17550 this.remoteTextTracks().removeTrack_(track);
17551 this.autoRemoteTextTracks_.removeTrack_(track);
17555 * A method to set a poster from a `Tech`.
17561 Tech.prototype.setPoster = function setPoster() {};
17564 * Check if the tech can support the given mime-type.
17566 * The base tech does not support any type, but source handlers might
17569 * @param {string} type
17570 * The mimetype to check for support
17573 * 'probably', 'maybe', or empty string
17575 * @see [Spec]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType}
17581 Tech.prototype.canPlayType = function canPlayType() {
17586 * Return whether the argument is a Tech or not.
17587 * Can be passed either a Class like `Html5` or a instance like `player.tech_`
17589 * @param {Object} component
17590 * The item to check
17592 * @return {boolean}
17593 * Whether it is a tech or not
17594 * - True if it is a tech
17595 * - False if it is not
17599 Tech.isTech = function isTech(component) {
17600 return component.prototype instanceof Tech || component instanceof Tech || component === Tech;
17604 * Registers a `Tech` into a shared list for videojs.
17606 * @param {string} name
17607 * Name of the `Tech` to register.
17609 * @param {Object} tech
17610 * The `Tech` class to register.
17614 Tech.registerTech = function registerTech(name, tech) {
17615 if (!Tech.techs_) {
17619 if (!Tech.isTech(tech)) {
17620 throw new Error('Tech ' + name + ' must be a Tech');
17623 Tech.techs_[name] = tech;
17628 * Get a `Tech` from the shared list by name.
17630 * @param {string} name
17631 * Name of the component to get
17633 * @return {Tech|undefined}
17634 * The `Tech` or undefined if there was no tech with the name requsted.
17638 Tech.getTech = function getTech(name) {
17639 if (Tech.techs_ && Tech.techs_[name]) {
17640 return Tech.techs_[name];
17643 if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) {
17644 _log2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)');
17645 return _window2['default'].videojs[name];
17650 }(_component2['default']);
17653 * List of associated text tracks.
17655 * @type {TextTrackList}
17660 Tech.prototype.textTracks_; // eslint-disable-line
17663 * List of associated audio tracks.
17665 * @type {AudioTrackList}
17668 Tech.prototype.audioTracks_; // eslint-disable-line
17671 * List of associated video tracks.
17673 * @type {VideoTrackList}
17676 Tech.prototype.videoTracks_; // eslint-disable-line
17679 * Boolean indicating wether the `Tech` supports volume control.
17684 Tech.prototype.featuresVolumeControl = true;
17687 * Boolean indicating wether the `Tech` support fullscreen resize control.
17688 * Resizing plugins using request fullscreen reloads the plugin
17693 Tech.prototype.featuresFullscreenResize = false;
17696 * Boolean indicating wether the `Tech` supports changing the speed at which the video
17698 * - Set player to play 2x (twice) as fast
17699 * - Set player to play 0.5x (half) as fast
17704 Tech.prototype.featuresPlaybackRate = false;
17707 * Boolean indicating wether the `Tech` supports the `progress` event. This is currently
17708 * not triggered by video-js-swf. This will be used to determine if
17709 * {@link Tech#manualProgressOn} should be called.
17714 Tech.prototype.featuresProgressEvents = false;
17717 * Boolean indicating wether the `Tech` supports the `timeupdate` event. This is currently
17718 * not triggered by video-js-swf. This will be used to determine if
17719 * {@link Tech#manualTimeUpdates} should be called.
17724 Tech.prototype.featuresTimeupdateEvents = false;
17727 * Boolean indicating wether the `Tech` supports the native `TextTrack`s.
17728 * This will help us integrate with native `TextTrack`s if the browser supports them.
17733 Tech.prototype.featuresNativeTextTracks = false;
17736 * A functional mixin for techs that want to use the Source Handler pattern.
17737 * Source handlers are scripts for handling specific formats.
17738 * The source handler pattern is used for adaptive formats (HLS, DASH) that
17739 * manually load video data and feed it into a Source Buffer (Media Source Extensions)
17740 * Example: `Tech.withSourceHandlers.call(MyTech);`
17742 * @param {Tech} _Tech
17743 * The tech to add source handler functions to.
17745 * @mixes Tech~SourceHandlerAdditions
17747 Tech.withSourceHandlers = function (_Tech) {
17750 * Register a source handler
17752 * @param {Function} handler
17753 * The source handler class
17755 * @param {number} [index]
17756 * Register it at the following index
17758 _Tech.registerSourceHandler = function (handler, index) {
17759 var handlers = _Tech.sourceHandlers;
17762 handlers = _Tech.sourceHandlers = [];
17765 if (index === undefined) {
17766 // add to the end of the list
17767 index = handlers.length;
17770 handlers.splice(index, 0, handler);
17774 * Check if the tech can support the given type. Also checks the
17775 * Techs sourceHandlers.
17777 * @param {string} type
17778 * The mimetype to check.
17781 * 'probably', 'maybe', or '' (empty string)
17783 _Tech.canPlayType = function (type) {
17784 var handlers = _Tech.sourceHandlers || [];
17787 for (var i = 0; i < handlers.length; i++) {
17788 can = handlers[i].canPlayType(type);
17799 * Returns the first source handler that supports the source.
17801 * TODO: Answer question: should 'probably' be prioritized over 'maybe'
17803 * @param {Tech~SourceObject} source
17804 * The source object
17806 * @param {Object} options
17807 * The options passed to the tech
17809 * @return {SourceHandler|null}
17810 * The first source handler that supports the source or null if
17811 * no SourceHandler supports the source
17813 _Tech.selectSourceHandler = function (source, options) {
17814 var handlers = _Tech.sourceHandlers || [];
17817 for (var i = 0; i < handlers.length; i++) {
17818 can = handlers[i].canHandleSource(source, options);
17821 return handlers[i];
17829 * Check if the tech can support the given source.
17831 * @param {Tech~SourceObject} srcObj
17832 * The source object
17834 * @param {Object} options
17835 * The options passed to the tech
17838 * 'probably', 'maybe', or '' (empty string)
17840 _Tech.canPlaySource = function (srcObj, options) {
17841 var sh = _Tech.selectSourceHandler(srcObj, options);
17844 return sh.canHandleSource(srcObj, options);
17851 * When using a source handler, prefer its implementation of
17852 * any function normally provided by the tech.
17854 var deferrable = ['seekable', 'duration'];
17857 * A wrapper around {@link Tech#seekable} that will call a `SourceHandler`s seekable
17858 * function if it exists, with a fallback to the Techs seekable function.
17860 * @method _Tech.seekable
17864 * A wrapper around {@link Tech#duration} that will call a `SourceHandler`s duration
17865 * function if it exists, otherwise it will fallback to the techs duration function.
17867 * @method _Tech.duration
17870 deferrable.forEach(function (fnName) {
17871 var originalFn = this[fnName];
17873 if (typeof originalFn !== 'function') {
17877 this[fnName] = function () {
17878 if (this.sourceHandler_ && this.sourceHandler_[fnName]) {
17879 return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments);
17881 return originalFn.apply(this, arguments);
17883 }, _Tech.prototype);
17886 * Create a function for setting the source using a source object
17887 * and source handlers.
17888 * Should never be called unless a source handler was found.
17890 * @param {Tech~SourceObject} source
17891 * A source object with src and type keys
17894 * Returns itself; this method is chainable
17896 _Tech.prototype.setSource = function (source) {
17897 var sh = _Tech.selectSourceHandler(source, this.options_);
17900 // Fall back to a native source hander when unsupported sources are
17901 // deliberately set
17902 if (_Tech.nativeSourceHandler) {
17903 sh = _Tech.nativeSourceHandler;
17905 _log2['default'].error('No source hander found for the current source.');
17909 // Dispose any existing source handler
17910 this.disposeSourceHandler();
17911 this.off('dispose', this.disposeSourceHandler);
17913 if (sh !== _Tech.nativeSourceHandler) {
17914 this.currentSource_ = source;
17916 // Catch if someone replaced the src without calling setSource.
17917 // If they do, set currentSource_ to null and dispose our source handler.
17918 this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17919 this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17920 this.one(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17923 this.sourceHandler_ = sh.handleSource(source, this, this.options_);
17924 this.on('dispose', this.disposeSourceHandler);
17930 * Called once for the first loadstart of a video.
17932 * @listens Tech#loadstart
17934 _Tech.prototype.firstLoadStartListener_ = function () {
17935 this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17938 // On successive loadstarts when setSource has not been called again
17940 * Called after the first loadstart for a video occurs.
17942 * @listens Tech#loadstart
17944 _Tech.prototype.successiveLoadStartListener_ = function () {
17945 this.disposeSourceHandler();
17946 this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17950 * Clean up any existing SourceHandlers and listeners when the Tech is disposed.
17952 * @listens Tech#dispose
17954 _Tech.prototype.disposeSourceHandler = function () {
17955 // if we have a source and get another one
17956 // then we are loading something new
17957 // than clear all of our current tracks
17958 if (this.currentSource_) {
17959 this.clearTracks(['audio', 'video']);
17960 this.currentSource_ = null;
17963 // always clean up auto-text tracks
17964 this.cleanupAutoTextTracks();
17966 if (this.sourceHandler_) {
17967 this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17968 this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17970 if (this.sourceHandler_.dispose) {
17971 this.sourceHandler_.dispose();
17974 this.sourceHandler_ = null;
17979 _component2['default'].registerComponent('Tech', Tech);
17980 // Old name for Tech
17982 _component2['default'].registerComponent('MediaTechController', Tech);
17983 Tech.registerTech('Tech', Tech);
17984 exports['default'] = Tech;
17986 },{"46":46,"5":5,"63":63,"65":65,"66":66,"70":70,"72":72,"76":76,"79":79,"83":83,"86":86,"87":87,"88":88,"90":90,"94":94,"95":95}],63:[function(_dereq_,module,exports){
17989 exports.__esModule = true;
17991 var _trackList = _dereq_(74);
17993 var _trackList2 = _interopRequireDefault(_trackList);
17995 var _browser = _dereq_(78);
17997 var browser = _interopRequireWildcard(_browser);
17999 var _document = _dereq_(94);
18001 var _document2 = _interopRequireDefault(_document);
18003 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
18005 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18007 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18009 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
18011 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
18012 * @file audio-track-list.js
18017 * Anywhere we call this function we diverge from the spec
18018 * as we only support one enabled audiotrack at a time
18020 * @param {AudioTrackList} list
18023 * @param {AudioTrack} track
18024 * The track to skip
18028 var disableOthers = function disableOthers(list, track) {
18029 for (var i = 0; i < list.length; i++) {
18030 if (track.id === list[i].id) {
18033 // another audio track is enabled, disable it
18034 list[i].enabled = false;
18039 * The current list of {@link AudioTrack} for a media file.
18041 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist}
18042 * @extends TrackList
18045 var AudioTrackList = function (_TrackList) {
18046 _inherits(AudioTrackList, _TrackList);
18049 * Create an instance of this class.
18051 * @param {AudioTrack[]} [tracks=[]]
18052 * A list of `AudioTrack` to instantiate the list with.
18054 function AudioTrackList() {
18057 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
18059 _classCallCheck(this, AudioTrackList);
18063 // make sure only 1 track is enabled
18064 // sorted from last index to first index
18065 for (var i = tracks.length - 1; i >= 0; i--) {
18066 if (tracks[i].enabled) {
18067 disableOthers(tracks, tracks[i]);
18072 // IE8 forces us to implement inheritance ourselves
18073 // as it does not support Object.defineProperty properly
18074 if (browser.IS_IE8) {
18075 list = _document2['default'].createElement('custom');
18076 for (var prop in _trackList2['default'].prototype) {
18077 if (prop !== 'constructor') {
18078 list[prop] = _trackList2['default'].prototype[prop];
18081 for (var _prop in AudioTrackList.prototype) {
18082 if (_prop !== 'constructor') {
18083 list[_prop] = AudioTrackList.prototype[_prop];
18088 list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
18089 list.changing_ = false;
18091 return _ret = list, _possibleConstructorReturn(_this, _ret);
18095 * Add an {@link AudioTrack} to the `AudioTrackList`.
18097 * @param {AudioTrack} track
18098 * The AudioTrack to add to the list
18100 * @fires Track#addtrack
18105 AudioTrackList.prototype.addTrack_ = function addTrack_(track) {
18108 if (track.enabled) {
18109 disableOthers(this, track);
18112 _TrackList.prototype.addTrack_.call(this, track);
18113 // native tracks don't have this
18114 if (!track.addEventListener) {
18119 * @listens AudioTrack#enabledchange
18120 * @fires TrackList#change
18122 track.addEventListener('enabledchange', function () {
18123 // when we are disabling other tracks (since we don't support
18124 // more than one track at a time) we will set changing_
18125 // to true so that we don't trigger additional change events
18126 if (_this2.changing_) {
18129 _this2.changing_ = true;
18130 disableOthers(_this2, track);
18131 _this2.changing_ = false;
18132 _this2.trigger('change');
18137 * Add an {@link AudioTrack} to the `AudioTrackList`.
18139 * @param {AudioTrack} track
18140 * The AudioTrack to add to the list
18142 * @fires Track#addtrack
18146 AudioTrackList.prototype.addTrack = function addTrack(track) {
18147 this.addTrack_(track);
18151 * Remove an {@link AudioTrack} from the `AudioTrackList`.
18153 * @param {AudioTrack} track
18154 * The AudioTrack to remove from the list
18156 * @fires Track#removetrack
18160 AudioTrackList.prototype.removeTrack = function removeTrack(track) {
18161 _TrackList.prototype.removeTrack_.call(this, track);
18164 return AudioTrackList;
18165 }(_trackList2['default']);
18167 exports['default'] = AudioTrackList;
18169 },{"74":74,"78":78,"94":94}],64:[function(_dereq_,module,exports){
18172 exports.__esModule = true;
18174 var _trackEnums = _dereq_(73);
18176 var _track = _dereq_(75);
18178 var _track2 = _interopRequireDefault(_track);
18180 var _mergeOptions = _dereq_(87);
18182 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
18184 var _browser = _dereq_(78);
18186 var browser = _interopRequireWildcard(_browser);
18188 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
18190 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18192 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18194 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
18196 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
18199 * A representation of a single `AudioTrack`. If it is part of an {@link AudioTrackList}
18200 * only one `AudioTrack` in the list will be enabled at a time.
18202 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack}
18205 var AudioTrack = function (_Track) {
18206 _inherits(AudioTrack, _Track);
18209 * Create an instance of this class.
18211 * @param {Object} [options={}]
18212 * Object of option names and values
18214 * @param {AudioTrack~Kind} [options.kind='']
18215 * A valid audio track kind
18217 * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
18218 * A unique id for this AudioTrack.
18220 * @param {string} [options.label='']
18221 * The menu label for this track.
18223 * @param {string} [options.language='']
18224 * A valid two character language code.
18226 * @param {boolean} [options.enabled]
18227 * If this track is the one that is currently playing. If this track is part of
18228 * an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled.
18230 function AudioTrack() {
18233 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
18235 _classCallCheck(this, AudioTrack);
18237 var settings = (0, _mergeOptions2['default'])(options, {
18238 kind: _trackEnums.AudioTrackKind[options.kind] || ''
18240 // on IE8 this will be a document element
18241 // for every other browser this will be a normal object
18242 var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
18243 var enabled = false;
18245 if (browser.IS_IE8) {
18246 for (var prop in AudioTrack.prototype) {
18247 if (prop !== 'constructor') {
18248 track[prop] = AudioTrack.prototype[prop];
18253 * @member {boolean} enabled
18254 * If this `AudioTrack` is enabled or not. When setting this will
18255 * fire {@link AudioTrack#enabledchange} if the state of enabled is changed.
18257 * @fires VideoTrack#selectedchange
18259 Object.defineProperty(track, 'enabled', {
18260 get: function get() {
18263 set: function set(newEnabled) {
18264 // an invalid or unchanged value
18265 if (typeof newEnabled !== 'boolean' || newEnabled === enabled) {
18268 enabled = newEnabled;
18271 * An event that fires when enabled changes on this track. This allows
18272 * the AudioTrackList that holds this track to act accordingly.
18274 * > Note: This is not part of the spec! Native tracks will do
18275 * this internally without an event.
18277 * @event AudioTrack#enabledchange
18278 * @type {EventTarget~Event}
18280 this.trigger('enabledchange');
18284 // if the user sets this track to selected then
18285 // set selected to that true value otherwise
18286 // we keep it false
18287 if (settings.enabled) {
18288 track.enabled = settings.enabled;
18290 track.loaded_ = true;
18292 return _ret = track, _possibleConstructorReturn(_this, _ret);
18296 }(_track2['default']);
18298 exports['default'] = AudioTrack;
18300 },{"73":73,"75":75,"78":78,"87":87}],65:[function(_dereq_,module,exports){
18303 exports.__esModule = true;
18305 var _browser = _dereq_(78);
18307 var browser = _interopRequireWildcard(_browser);
18309 var _document = _dereq_(94);
18311 var _document2 = _interopRequireDefault(_document);
18313 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18315 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
18317 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
18318 * @file html-track-element-list.js
18322 * The current list of {@link HtmlTrackElement}s.
18324 var HtmlTrackElementList = function () {
18327 * Create an instance of this class.
18329 * @param {HtmlTrackElement[]} [tracks=[]]
18330 * A list of `HtmlTrackElement` to instantiate the list with.
18332 function HtmlTrackElementList() {
18333 var trackElements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
18335 _classCallCheck(this, HtmlTrackElementList);
18337 var list = this; // eslint-disable-line
18339 if (browser.IS_IE8) {
18340 list = _document2['default'].createElement('custom');
18342 for (var prop in HtmlTrackElementList.prototype) {
18343 if (prop !== 'constructor') {
18344 list[prop] = HtmlTrackElementList.prototype[prop];
18349 list.trackElements_ = [];
18352 * @member {number} length
18353 * The current number of `Track`s in the this Trackist.
18355 Object.defineProperty(list, 'length', {
18356 get: function get() {
18357 return this.trackElements_.length;
18361 for (var i = 0, length = trackElements.length; i < length; i++) {
18362 list.addTrackElement_(trackElements[i]);
18365 if (browser.IS_IE8) {
18371 * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList`
18373 * @param {HtmlTrackElement} trackElement
18374 * The track element to add to the list.
18380 HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) {
18381 var index = this.trackElements_.length;
18383 if (!('' + index in this)) {
18384 Object.defineProperty(this, index, {
18385 get: function get() {
18386 return this.trackElements_[index];
18391 // Do not add duplicate elements
18392 if (this.trackElements_.indexOf(trackElement) === -1) {
18393 this.trackElements_.push(trackElement);
18398 * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an
18399 * {@link TextTrack}.
18401 * @param {TextTrack} track
18402 * The track associated with a track element.
18404 * @return {HtmlTrackElement|undefined}
18405 * The track element that was found or undefined.
18411 HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) {
18412 var trackElement_ = void 0;
18414 for (var i = 0, length = this.trackElements_.length; i < length; i++) {
18415 if (track === this.trackElements_[i].track) {
18416 trackElement_ = this.trackElements_[i];
18422 return trackElement_;
18426 * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList`
18428 * @param {HtmlTrackElement} trackElement
18429 * The track element to remove from the list.
18435 HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) {
18436 for (var i = 0, length = this.trackElements_.length; i < length; i++) {
18437 if (trackElement === this.trackElements_[i]) {
18438 this.trackElements_.splice(i, 1);
18445 return HtmlTrackElementList;
18448 exports['default'] = HtmlTrackElementList;
18450 },{"78":78,"94":94}],66:[function(_dereq_,module,exports){
18453 exports.__esModule = true;
18455 var _browser = _dereq_(78);
18457 var browser = _interopRequireWildcard(_browser);
18459 var _document = _dereq_(94);
18461 var _document2 = _interopRequireDefault(_document);
18463 var _eventTarget = _dereq_(42);
18465 var _eventTarget2 = _interopRequireDefault(_eventTarget);
18467 var _textTrack = _dereq_(72);
18469 var _textTrack2 = _interopRequireDefault(_textTrack);
18471 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18473 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
18475 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18477 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
18479 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
18480 * @file html-track-element.js
18484 * @typedef {HTMLTrackElement~ReadyState}
18493 * A single track represented in the DOM.
18495 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement}
18496 * @extends EventTarget
18499 var HTMLTrackElement = function (_EventTarget) {
18500 _inherits(HTMLTrackElement, _EventTarget);
18503 * Create an instance of this class.
18505 * @param {Object} options={}
18506 * Object of option names and values
18508 * @param {Tech} options.tech
18509 * A reference to the tech that owns this HTMLTrackElement.
18511 * @param {TextTrack~Kind} [options.kind='subtitles']
18512 * A valid text track kind.
18514 * @param {TextTrack~Mode} [options.mode='disabled']
18515 * A valid text track mode.
18517 * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
18518 * A unique id for this TextTrack.
18520 * @param {string} [options.label='']
18521 * The menu label for this track.
18523 * @param {string} [options.language='']
18524 * A valid two character language code.
18526 * @param {string} [options.srclang='']
18527 * A valid two character language code. An alternative, but deprioritized
18528 * vesion of `options.language`
18530 * @param {string} [options.src]
18531 * A url to TextTrack cues.
18533 * @param {boolean} [options.default]
18534 * If this track should default to on or off.
18536 function HTMLTrackElement() {
18537 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
18539 _classCallCheck(this, HTMLTrackElement);
18541 var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
18543 var readyState = void 0;
18544 var trackElement = _this; // eslint-disable-line
18546 if (browser.IS_IE8) {
18547 trackElement = _document2['default'].createElement('custom');
18549 for (var prop in HTMLTrackElement.prototype) {
18550 if (prop !== 'constructor') {
18551 trackElement[prop] = HTMLTrackElement.prototype[prop];
18556 var track = new _textTrack2['default'](options);
18558 trackElement.kind = track.kind;
18559 trackElement.src = track.src;
18560 trackElement.srclang = track.language;
18561 trackElement.label = track.label;
18562 trackElement['default'] = track['default'];
18565 * @member {HTMLTrackElement~ReadyState} readyState
18566 * The current ready state of the track element.
18568 Object.defineProperty(trackElement, 'readyState', {
18569 get: function get() {
18575 * @member {TextTrack} track
18576 * The underlying TextTrack object.
18578 Object.defineProperty(trackElement, 'track', {
18579 get: function get() {
18587 * @listens TextTrack#loadeddata
18588 * @fires HTMLTrackElement#load
18590 track.addEventListener('loadeddata', function () {
18591 readyState = LOADED;
18593 trackElement.trigger({
18595 target: trackElement
18599 if (browser.IS_IE8) {
18602 return _ret = trackElement, _possibleConstructorReturn(_this, _ret);
18607 return HTMLTrackElement;
18608 }(_eventTarget2['default']);
18610 HTMLTrackElement.prototype.allowedEvents_ = {
18614 HTMLTrackElement.NONE = NONE;
18615 HTMLTrackElement.LOADING = LOADING;
18616 HTMLTrackElement.LOADED = LOADED;
18617 HTMLTrackElement.ERROR = ERROR;
18619 exports['default'] = HTMLTrackElement;
18621 },{"42":42,"72":72,"78":78,"94":94}],67:[function(_dereq_,module,exports){
18624 exports.__esModule = true;
18626 var _browser = _dereq_(78);
18628 var browser = _interopRequireWildcard(_browser);
18630 var _document = _dereq_(94);
18632 var _document2 = _interopRequireDefault(_document);
18634 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18636 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
18638 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
18639 * @file text-track-cue-list.js
18644 * @typedef {Object} TextTrackCue
18646 * @property {string} id
18647 * The unique id for this text track cue
18649 * @property {number} startTime
18650 * The start time for this text track cue
18652 * @property {number} endTime
18653 * The end time for this text track cue
18655 * @property {boolean} pauseOnExit
18656 * Pause when the end time is reached if true.
18658 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcue}
18662 * A List of TextTrackCues.
18664 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist}
18666 var TextTrackCueList = function () {
18669 * Create an instance of this class..
18671 * @param {Array} cues
18672 * A list of cues to be initialized with
18674 function TextTrackCueList(cues) {
18675 _classCallCheck(this, TextTrackCueList);
18677 var list = this; // eslint-disable-line
18679 if (browser.IS_IE8) {
18680 list = _document2['default'].createElement('custom');
18682 for (var prop in TextTrackCueList.prototype) {
18683 if (prop !== 'constructor') {
18684 list[prop] = TextTrackCueList.prototype[prop];
18689 TextTrackCueList.prototype.setCues_.call(list, cues);
18692 * @member {number} length
18693 * The current number of `TextTrackCue`s in the TextTrackCueList.
18695 Object.defineProperty(list, 'length', {
18696 get: function get() {
18697 return this.length_;
18701 if (browser.IS_IE8) {
18707 * A setter for cues in this list. Creates getters
18708 * an an index for the cues.
18710 * @param {Array} cues
18711 * An array of cues to set
18717 TextTrackCueList.prototype.setCues_ = function setCues_(cues) {
18718 var oldLength = this.length || 0;
18720 var l = cues.length;
18723 this.length_ = cues.length;
18725 var defineProp = function defineProp(index) {
18726 if (!('' + index in this)) {
18727 Object.defineProperty(this, '' + index, {
18728 get: function get() {
18729 return this.cues_[index];
18735 if (oldLength < l) {
18738 for (; i < l; i++) {
18739 defineProp.call(this, i);
18745 * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id.
18747 * @param {string} id
18748 * The id of the cue that should be searched for.
18750 * @return {TextTrackCue|null}
18751 * A single cue or null if none was found.
18755 TextTrackCueList.prototype.getCueById = function getCueById(id) {
18758 for (var i = 0, l = this.length; i < l; i++) {
18761 if (cue.id === id) {
18770 return TextTrackCueList;
18773 exports['default'] = TextTrackCueList;
18775 },{"78":78,"94":94}],68:[function(_dereq_,module,exports){
18778 exports.__esModule = true;
18780 var _component = _dereq_(5);
18782 var _component2 = _interopRequireDefault(_component);
18784 var _fn = _dereq_(83);
18786 var Fn = _interopRequireWildcard(_fn);
18788 var _window = _dereq_(95);
18790 var _window2 = _interopRequireDefault(_window);
18792 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
18794 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18796 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18798 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
18800 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
18801 * @file text-track-display.js
18805 var darkGray = '#222';
18806 var lightGray = '#ccc';
18808 monospace: 'monospace',
18809 sansSerif: 'sans-serif',
18811 monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace',
18812 monospaceSerif: '"Courier New", monospace',
18813 proportionalSansSerif: 'sans-serif',
18814 proportionalSerif: 'serif',
18815 casual: '"Comic Sans MS", Impact, fantasy',
18816 script: '"Monotype Corsiva", cursive',
18817 smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif'
18821 * Construct an rgba color from a given hex color code.
18823 * @param {number} color
18824 * Hex number for color, like #f0e.
18826 * @param {number} opacity
18827 * Value for opacity, 0.0 - 1.0.
18830 * The rgba color that was created, like 'rgba(255, 0, 0, 0.3)'.
18834 function constructColor(color, opacity) {
18836 // color looks like "#f0e"
18837 parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')';
18841 * Try to update the style of a DOM element. Some style changes will throw an error,
18842 * particularly in IE8. Those should be noops.
18844 * @param {Element} el
18845 * The DOM element to be styled.
18847 * @param {string} style
18848 * The CSS property on the element that should be styled.
18850 * @param {string} rule
18851 * The style rule that should be applied to the property.
18853 function tryUpdateStyle(el, style, rule) {
18855 el.style[style] = rule;
18858 // Satisfies linter.
18864 * The component for displaying text track cues.
18866 * @extends Component
18869 var TextTrackDisplay = function (_Component) {
18870 _inherits(TextTrackDisplay, _Component);
18873 * Creates an instance of this class.
18875 * @param {Player} player
18876 * The `Player` that this class should be attached to.
18878 * @param {Object} [options]
18879 * The key/value store of player options.
18881 * @param {Component~ReadyCallback} [ready]
18882 * The function to call when `TextTrackDisplay` is ready.
18884 function TextTrackDisplay(player, options, ready) {
18885 _classCallCheck(this, TextTrackDisplay);
18887 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready));
18889 player.on('loadstart', Fn.bind(_this, _this.toggleDisplay));
18890 player.on('texttrackchange', Fn.bind(_this, _this.updateDisplay));
18892 // This used to be called during player init, but was causing an error
18893 // if a track should show by default and the display hadn't loaded yet.
18894 // Should probably be moved to an external track loader when we support
18895 // tracks that don't need a display.
18896 player.ready(Fn.bind(_this, function () {
18897 if (player.tech_ && player.tech_.featuresNativeTextTracks) {
18902 player.on('fullscreenchange', Fn.bind(this, this.updateDisplay));
18904 var tracks = this.options_.playerOptions.tracks || [];
18906 for (var i = 0; i < tracks.length; i++) {
18907 this.player_.addRemoteTextTrack(tracks[i], true);
18910 var modes = { captions: 1, subtitles: 1 };
18911 var trackList = this.player_.textTracks();
18912 var firstDesc = void 0;
18913 var firstCaptions = void 0;
18916 for (var _i = 0; _i < trackList.length; _i++) {
18917 var track = trackList[_i];
18919 if (track['default']) {
18920 if (track.kind === 'descriptions' && !firstDesc) {
18922 } else if (track.kind in modes && !firstCaptions) {
18923 firstCaptions = track;
18928 // We want to show the first default track but captions and subtitles
18929 // take precedence over descriptions.
18930 // So, display the first default captions or subtitles track
18931 // and otherwise the first default descriptions track.
18932 if (firstCaptions) {
18933 firstCaptions.mode = 'showing';
18934 } else if (firstDesc) {
18935 firstDesc.mode = 'showing';
18943 * Turn display of {@link TextTrack}'s from the current state into the other state.
18944 * There are only two states:
18948 * @listens Player#loadstart
18952 TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() {
18953 if (this.player_.tech_ && this.player_.tech_.featuresNativeTextTracks) {
18961 * Create the {@link Component}'s DOM element.
18963 * @return {Element}
18964 * The element that was created.
18968 TextTrackDisplay.prototype.createEl = function createEl() {
18969 return _Component.prototype.createEl.call(this, 'div', {
18970 className: 'vjs-text-track-display'
18972 'aria-live': 'off',
18973 'aria-atomic': 'true'
18978 * Clear all displayed {@link TextTrack}s.
18982 TextTrackDisplay.prototype.clearDisplay = function clearDisplay() {
18983 if (typeof _window2['default'].WebVTT === 'function') {
18984 _window2['default'].WebVTT.processCues(_window2['default'], [], this.el_);
18989 * Update the displayed TextTrack when a either a {@link Player#texttrackchange} or
18990 * a {@link Player#fullscreenchange} is fired.
18992 * @listens Player#texttrackchange
18993 * @listens Player#fullscreenchange
18997 TextTrackDisplay.prototype.updateDisplay = function updateDisplay() {
18998 var tracks = this.player_.textTracks();
19000 this.clearDisplay();
19006 // Track display prioritization model: if multiple tracks are 'showing',
19007 // display the first 'subtitles' or 'captions' track which is 'showing',
19008 // otherwise display the first 'descriptions' track which is 'showing'
19010 var descriptionsTrack = null;
19011 var captionsSubtitlesTrack = null;
19013 var i = tracks.length;
19016 var track = tracks[i];
19018 if (track.mode === 'showing') {
19019 if (track.kind === 'descriptions') {
19020 descriptionsTrack = track;
19022 captionsSubtitlesTrack = track;
19027 if (captionsSubtitlesTrack) {
19028 if (this.getAttribute('aria-live') !== 'off') {
19029 this.setAttribute('aria-live', 'off');
19031 this.updateForTrack(captionsSubtitlesTrack);
19032 } else if (descriptionsTrack) {
19033 if (this.getAttribute('aria-live') !== 'assertive') {
19034 this.setAttribute('aria-live', 'assertive');
19036 this.updateForTrack(descriptionsTrack);
19041 * Add an {@link Texttrack} to to the {@link Tech}s {@link TextTrackList}.
19043 * @param {TextTrack} track
19044 * Text track object to be added to the list.
19048 TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) {
19049 if (typeof _window2['default'].WebVTT !== 'function' || !track.activeCues) {
19053 var overrides = this.player_.textTrackSettings.getValues();
19056 for (var _i2 = 0; _i2 < track.activeCues.length; _i2++) {
19057 cues.push(track.activeCues[_i2]);
19060 _window2['default'].WebVTT.processCues(_window2['default'], cues, this.el_);
19062 var i = cues.length;
19071 var cueDiv = cue.displayState;
19073 if (overrides.color) {
19074 cueDiv.firstChild.style.color = overrides.color;
19076 if (overrides.textOpacity) {
19077 tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity));
19079 if (overrides.backgroundColor) {
19080 cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor;
19082 if (overrides.backgroundOpacity) {
19083 tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity));
19085 if (overrides.windowColor) {
19086 if (overrides.windowOpacity) {
19087 tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity));
19089 cueDiv.style.backgroundColor = overrides.windowColor;
19092 if (overrides.edgeStyle) {
19093 if (overrides.edgeStyle === 'dropshadow') {
19094 cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray;
19095 } else if (overrides.edgeStyle === 'raised') {
19096 cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray;
19097 } else if (overrides.edgeStyle === 'depressed') {
19098 cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray;
19099 } else if (overrides.edgeStyle === 'uniform') {
19100 cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray;
19103 if (overrides.fontPercent && overrides.fontPercent !== 1) {
19104 var fontSize = _window2['default'].parseFloat(cueDiv.style.fontSize);
19106 cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px';
19107 cueDiv.style.height = 'auto';
19108 cueDiv.style.top = 'auto';
19109 cueDiv.style.bottom = '2px';
19111 if (overrides.fontFamily && overrides.fontFamily !== 'default') {
19112 if (overrides.fontFamily === 'small-caps') {
19113 cueDiv.firstChild.style.fontVariant = 'small-caps';
19115 cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily];
19121 return TextTrackDisplay;
19122 }(_component2['default']);
19124 _component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay);
19125 exports['default'] = TextTrackDisplay;
19127 },{"5":5,"83":83,"95":95}],69:[function(_dereq_,module,exports){
19130 exports.__esModule = true;
19132 * @file text-track-list-converter.js Utilities for capturing text track state and
19133 * re-creating tracks based on a capture.
19135 * @module text-track-list-converter
19139 * Examine a single {@link TextTrack} and return a JSON-compatible javascript object that
19140 * represents the {@link TextTrack}'s state.
19142 * @param {TextTrack} track
19143 * The text track to query.
19146 * A serializable javascript representation of the TextTrack.
19149 var trackToJson_ = function trackToJson_(track) {
19150 var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) {
19153 acc[prop] = track[prop];
19158 cues: track.cues && Array.prototype.map.call(track.cues, function (cue) {
19160 startTime: cue.startTime,
19161 endTime: cue.endTime,
19172 * Examine a {@link Tech} and return a JSON-compatible javascript array that represents the
19173 * state of all {@link TextTrack}s currently configured. The return array is compatible with
19174 * {@link text-track-list-converter:jsonToTextTracks}.
19176 * @param {Tech} tech
19177 * The tech object to query
19180 * A serializable javascript representation of the {@link Tech}s
19181 * {@link TextTrackList}.
19183 var textTracksToJson = function textTracksToJson(tech) {
19185 var trackEls = tech.$$('track');
19187 var trackObjs = Array.prototype.map.call(trackEls, function (t) {
19190 var tracks = Array.prototype.map.call(trackEls, function (trackEl) {
19191 var json = trackToJson_(trackEl.track);
19194 json.src = trackEl.src;
19199 return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) {
19200 return trackObjs.indexOf(track) === -1;
19201 }).map(trackToJson_));
19205 * Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript
19206 * object {@link TextTrack} representations.
19208 * @param {Array} json
19209 * An array of `TextTrack` representation objects, like those that would be
19210 * produced by `textTracksToJson`.
19212 * @param {Tech} tech
19213 * The `Tech` to create the `TextTrack`s on.
19215 var jsonToTextTracks = function jsonToTextTracks(json, tech) {
19216 json.forEach(function (track) {
19217 var addedTrack = tech.addRemoteTextTrack(track).track;
19219 if (!track.src && track.cues) {
19220 track.cues.forEach(function (cue) {
19221 return addedTrack.addCue(cue);
19226 return tech.textTracks();
19229 exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ };
19231 },{}],70:[function(_dereq_,module,exports){
19234 exports.__esModule = true;
19236 var _trackList = _dereq_(74);
19238 var _trackList2 = _interopRequireDefault(_trackList);
19240 var _fn = _dereq_(83);
19242 var Fn = _interopRequireWildcard(_fn);
19244 var _browser = _dereq_(78);
19246 var browser = _interopRequireWildcard(_browser);
19248 var _document = _dereq_(94);
19250 var _document2 = _interopRequireDefault(_document);
19252 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
19254 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19256 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19258 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
19260 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
19261 * @file text-track-list.js
19266 * The current list of {@link TextTrack} for a media file.
19268 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist}
19269 * @extends TrackList
19271 var TextTrackList = function (_TrackList) {
19272 _inherits(TextTrackList, _TrackList);
19275 * Create an instance of this class.
19277 * @param {TextTrack[]} [tracks=[]]
19278 * A list of `TextTrack` to instantiate the list with.
19280 function TextTrackList() {
19283 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
19285 _classCallCheck(this, TextTrackList);
19289 // IE8 forces us to implement inheritance ourselves
19290 // as it does not support Object.defineProperty properly
19291 if (browser.IS_IE8) {
19292 list = _document2['default'].createElement('custom');
19293 for (var prop in _trackList2['default'].prototype) {
19294 if (prop !== 'constructor') {
19295 list[prop] = _trackList2['default'].prototype[prop];
19298 for (var _prop in TextTrackList.prototype) {
19299 if (_prop !== 'constructor') {
19300 list[_prop] = TextTrackList.prototype[_prop];
19305 list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
19306 return _ret = list, _possibleConstructorReturn(_this, _ret);
19310 * Add a {@link TextTrack} to the `TextTrackList`
19312 * @param {TextTrack} track
19313 * The text track to add to the list.
19315 * @fires TrackList#addtrack
19320 TextTrackList.prototype.addTrack_ = function addTrack_(track) {
19321 _TrackList.prototype.addTrack_.call(this, track);
19324 * @listens TextTrack#modechange
19325 * @fires TrackList#change
19327 track.addEventListener('modechange', Fn.bind(this, function () {
19328 this.trigger('change');
19332 return TextTrackList;
19333 }(_trackList2['default']);
19335 exports['default'] = TextTrackList;
19337 },{"74":74,"78":78,"83":83,"94":94}],71:[function(_dereq_,module,exports){
19340 exports.__esModule = true;
19342 var _window = _dereq_(95);
19344 var _window2 = _interopRequireDefault(_window);
19346 var _component = _dereq_(5);
19348 var _component2 = _interopRequireDefault(_component);
19350 var _dom = _dereq_(81);
19352 var _fn = _dereq_(83);
19354 var Fn = _interopRequireWildcard(_fn);
19356 var _obj = _dereq_(88);
19358 var Obj = _interopRequireWildcard(_obj);
19360 var _log = _dereq_(86);
19362 var _log2 = _interopRequireDefault(_log);
19364 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
19366 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19368 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19370 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
19372 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
19373 * @file text-track-settings.js
19377 var LOCAL_STORAGE_KEY = 'vjs-text-track-settings';
19379 var COLOR_BLACK = ['#000', 'Black'];
19380 var COLOR_BLUE = ['#00F', 'Blue'];
19381 var COLOR_CYAN = ['#0FF', 'Cyan'];
19382 var COLOR_GREEN = ['#0F0', 'Green'];
19383 var COLOR_MAGENTA = ['#F0F', 'Magenta'];
19384 var COLOR_RED = ['#F00', 'Red'];
19385 var COLOR_WHITE = ['#FFF', 'White'];
19386 var COLOR_YELLOW = ['#FF0', 'Yellow'];
19388 var OPACITY_OPAQUE = ['1', 'Opaque'];
19389 var OPACITY_SEMI = ['0.5', 'Semi-Transparent'];
19390 var OPACITY_TRANS = ['0', 'Transparent'];
19392 // Configuration for the various <select> elements in the DOM of this component.
19394 // Possible keys include:
19397 // The default option index. Only needs to be provided if not zero.
19399 // A function which is used to parse the value from the selected option in
19400 // a customized way.
19402 // The selector used to find the associated <select> element.
19403 var selectConfigs = {
19405 selector: '.vjs-bg-color > select',
19406 id: 'captions-background-color-%s',
19408 options: [COLOR_BLACK, COLOR_WHITE, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
19411 backgroundOpacity: {
19412 selector: '.vjs-bg-opacity > select',
19413 id: 'captions-background-opacity-%s',
19414 label: 'Transparency',
19415 options: [OPACITY_OPAQUE, OPACITY_SEMI, OPACITY_TRANS]
19419 selector: '.vjs-fg-color > select',
19420 id: 'captions-foreground-color-%s',
19422 options: [COLOR_WHITE, COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
19426 selector: '.vjs-edge-style > select',
19428 label: 'Text Edge Style',
19429 options: [['none', 'None'], ['raised', 'Raised'], ['depressed', 'Depressed'], ['uniform', 'Uniform'], ['dropshadow', 'Dropshadow']]
19433 selector: '.vjs-font-family > select',
19434 id: 'captions-font-family-%s',
19435 label: 'Font Family',
19436 options: [['proportionalSansSerif', 'Proportional Sans-Serif'], ['monospaceSansSerif', 'Monospace Sans-Serif'], ['proportionalSerif', 'Proportional Serif'], ['monospaceSerif', 'Monospace Serif'], ['casual', 'Casual'], ['script', 'Script'], ['small-caps', 'Small Caps']]
19440 selector: '.vjs-font-percent > select',
19441 id: 'captions-font-size-%s',
19442 label: 'Font Size',
19443 options: [['0.50', '50%'], ['0.75', '75%'], ['1.00', '100%'], ['1.25', '125%'], ['1.50', '150%'], ['1.75', '175%'], ['2.00', '200%'], ['3.00', '300%'], ['4.00', '400%']],
19445 parser: function parser(v) {
19446 return v === '1.00' ? null : Number(v);
19451 selector: '.vjs-text-opacity > select',
19452 id: 'captions-foreground-opacity-%s',
19453 label: 'Transparency',
19454 options: [OPACITY_OPAQUE, OPACITY_SEMI]
19457 // Options for this object are defined below.
19459 selector: '.vjs-window-color > select',
19460 id: 'captions-window-color-%s',
19464 // Options for this object are defined below.
19466 selector: '.vjs-window-opacity > select',
19467 id: 'captions-window-opacity-%s',
19468 label: 'Transparency',
19469 options: [OPACITY_TRANS, OPACITY_SEMI, OPACITY_OPAQUE]
19473 selectConfigs.windowColor.options = selectConfigs.backgroundColor.options;
19476 * Get the actual value of an option.
19478 * @param {string} value
19481 * @param {Function} [parser]
19482 * Optional function to adjust the value.
19485 * - Will be `undefined` if no value exists
19486 * - Will be `undefined` if the given value is "none".
19487 * - Will be the actual value otherwise.
19491 function parseOptionValue(value, parser) {
19493 value = parser(value);
19496 if (value && value !== 'none') {
19502 * Gets the value of the selected <option> element within a <select> element.
19504 * @param {Element} el
19505 * the element to look in
19507 * @param {Function} [parser]
19508 * Optional function to adjust the value.
19511 * - Will be `undefined` if no value exists
19512 * - Will be `undefined` if the given value is "none".
19513 * - Will be the actual value otherwise.
19517 function getSelectedOptionValue(el, parser) {
19518 var value = el.options[el.options.selectedIndex].value;
19520 return parseOptionValue(value, parser);
19524 * Sets the selected <option> element within a <select> element based on a
19527 * @param {Element} el
19528 * The element to look in.
19530 * @param {string} value
19531 * the property to look on.
19533 * @param {Function} [parser]
19534 * Optional function to adjust the value before comparing.
19538 function setSelectedOption(el, value, parser) {
19543 for (var i = 0; i < el.options.length; i++) {
19544 if (parseOptionValue(el.options[i].value, parser) === value) {
19545 el.selectedIndex = i;
19552 * Manipulate Text Tracks settings.
19554 * @extends Component
19557 var TextTrackSettings = function (_Component) {
19558 _inherits(TextTrackSettings, _Component);
19561 * Creates an instance of this class.
19563 * @param {Player} player
19564 * The `Player` that this class should be attached to.
19566 * @param {Object} [options]
19567 * The key/value store of player options.
19569 function TextTrackSettings(player, options) {
19570 _classCallCheck(this, TextTrackSettings);
19572 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
19574 _this.setDefaults();
19577 _this.updateDisplay = Fn.bind(_this, _this.updateDisplay);
19579 // Grab `persistTextTrackSettings` from the player options if not passed in child options
19580 if (options.persistTextTrackSettings === undefined) {
19581 _this.options_.persistTextTrackSettings = _this.options_.playerOptions.persistTextTrackSettings;
19584 _this.on(_this.$('.vjs-done-button'), 'click', function () {
19585 _this.saveSettings();
19589 _this.on(_this.$('.vjs-default-button'), 'click', function () {
19590 _this.setDefaults();
19591 _this.updateDisplay();
19594 Obj.each(selectConfigs, function (config) {
19595 _this.on(_this.$(config.selector), 'change', _this.updateDisplay);
19598 if (_this.options_.persistTextTrackSettings) {
19599 _this.restoreSettings();
19605 * Create a <select> element with configured options.
19607 * @param {string} key
19608 * Configuration key to use during creation.
19610 * @return {Element}
19611 * The DOM element that gets created.
19616 TextTrackSettings.prototype.createElSelect_ = function createElSelect_(key) {
19619 var config = selectConfigs[key];
19620 var id = config.id.replace('%s', this.id_);
19622 return [(0, _dom.createEl)('label', {
19623 className: 'vjs-label',
19624 textContent: config.label
19627 }), (0, _dom.createEl)('select', { id: id }, undefined, config.options.map(function (o) {
19628 return (0, _dom.createEl)('option', {
19629 textContent: _this2.localize(o[1]),
19636 * Create foreground color element for the component
19638 * @return {Element}
19639 * The element that was created.
19645 TextTrackSettings.prototype.createElFgColor_ = function createElFgColor_() {
19646 var legend = (0, _dom.createEl)('legend', {
19647 textContent: this.localize('Text')
19650 var select = this.createElSelect_('color');
19652 var opacity = (0, _dom.createEl)('span', {
19653 className: 'vjs-text-opacity vjs-opacity'
19654 }, undefined, this.createElSelect_('textOpacity'));
19656 return (0, _dom.createEl)('fieldset', {
19657 className: 'vjs-fg-color vjs-tracksetting'
19658 }, undefined, [legend].concat(select, opacity));
19662 * Create background color element for the component
19664 * @return {Element}
19665 * The element that was created
19671 TextTrackSettings.prototype.createElBgColor_ = function createElBgColor_() {
19672 var legend = (0, _dom.createEl)('legend', {
19673 textContent: this.localize('Background')
19676 var select = this.createElSelect_('backgroundColor');
19678 var opacity = (0, _dom.createEl)('span', {
19679 className: 'vjs-bg-opacity vjs-opacity'
19680 }, undefined, this.createElSelect_('backgroundOpacity'));
19682 return (0, _dom.createEl)('fieldset', {
19683 className: 'vjs-bg-color vjs-tracksetting'
19684 }, undefined, [legend].concat(select, opacity));
19688 * Create window color element for the component
19690 * @return {Element}
19691 * The element that was created
19697 TextTrackSettings.prototype.createElWinColor_ = function createElWinColor_() {
19698 var legend = (0, _dom.createEl)('legend', {
19699 textContent: this.localize('Window')
19702 var select = this.createElSelect_('windowColor');
19704 var opacity = (0, _dom.createEl)('span', {
19705 className: 'vjs-window-opacity vjs-opacity'
19706 }, undefined, this.createElSelect_('windowOpacity'));
19708 return (0, _dom.createEl)('fieldset', {
19709 className: 'vjs-window-color vjs-tracksetting'
19710 }, undefined, [legend].concat(select, opacity));
19714 * Create color elements for the component
19716 * @return {Element}
19717 * The element that was created
19723 TextTrackSettings.prototype.createElColors_ = function createElColors_() {
19724 return (0, _dom.createEl)('div', {
19725 className: 'vjs-tracksettings-colors'
19726 }, undefined, [this.createElFgColor_(), this.createElBgColor_(), this.createElWinColor_()]);
19730 * Create font elements for the component
19732 * @return {Element}
19733 * The element that was created.
19739 TextTrackSettings.prototype.createElFont_ = function createElFont_() {
19740 var fontPercent = (0, _dom.createEl)('div', {
19741 className: 'vjs-font-percent vjs-tracksetting'
19742 }, undefined, this.createElSelect_('fontPercent'));
19744 var edgeStyle = (0, _dom.createEl)('div', {
19745 className: 'vjs-edge-style vjs-tracksetting'
19746 }, undefined, this.createElSelect_('edgeStyle'));
19748 var fontFamily = (0, _dom.createEl)('div', {
19749 className: 'vjs-font-family vjs-tracksetting'
19750 }, undefined, this.createElSelect_('fontFamily'));
19752 return (0, _dom.createEl)('div', {
19753 className: 'vjs-tracksettings-font'
19754 }, undefined, [fontPercent, edgeStyle, fontFamily]);
19758 * Create controls for the component
19760 * @return {Element}
19761 * The element that was created.
19767 TextTrackSettings.prototype.createElControls_ = function createElControls_() {
19768 var defaultsButton = (0, _dom.createEl)('button', {
19769 className: 'vjs-default-button',
19770 textContent: this.localize('Defaults')
19773 var doneButton = (0, _dom.createEl)('button', {
19774 className: 'vjs-done-button',
19775 textContent: 'Done'
19778 return (0, _dom.createEl)('div', {
19779 className: 'vjs-tracksettings-controls'
19780 }, undefined, [defaultsButton, doneButton]);
19784 * Create the component's DOM element
19786 * @return {Element}
19787 * The element that was created.
19791 TextTrackSettings.prototype.createEl = function createEl() {
19792 var settings = (0, _dom.createEl)('div', {
19793 className: 'vjs-tracksettings'
19794 }, undefined, [this.createElColors_(), this.createElFont_(), this.createElControls_()]);
19796 var heading = (0, _dom.createEl)('div', {
19797 className: 'vjs-control-text',
19798 id: 'TTsettingsDialogLabel-' + this.id_,
19799 textContent: 'Caption Settings Dialog'
19805 var description = (0, _dom.createEl)('div', {
19806 className: 'vjs-control-text',
19807 id: 'TTsettingsDialogDescription-' + this.id_,
19808 textContent: 'Beginning of dialog window. Escape will cancel and close the window.'
19811 var doc = (0, _dom.createEl)('div', undefined, {
19813 }, [heading, description, settings]);
19815 return (0, _dom.createEl)('div', {
19816 className: 'vjs-caption-settings vjs-modal-overlay',
19820 'aria-labelledby': heading.id,
19821 'aria-describedby': description.id
19826 * Gets an object of text track settings (or null).
19829 * An object with config values parsed from the DOM or localStorage.
19833 TextTrackSettings.prototype.getValues = function getValues() {
19836 return Obj.reduce(selectConfigs, function (accum, config, key) {
19837 var value = getSelectedOptionValue(_this3.$(config.selector), config.parser);
19839 if (value !== undefined) {
19840 accum[key] = value;
19848 * Sets text track settings from an object of values.
19850 * @param {Object} values
19851 * An object with config values parsed from the DOM or localStorage.
19855 TextTrackSettings.prototype.setValues = function setValues(values) {
19858 Obj.each(selectConfigs, function (config, key) {
19859 setSelectedOption(_this4.$(config.selector), values[key], config.parser);
19864 * Sets all <select> elements to their default values.
19868 TextTrackSettings.prototype.setDefaults = function setDefaults() {
19871 Obj.each(selectConfigs, function (config) {
19872 var index = config.hasOwnProperty('default') ? config['default'] : 0;
19874 _this5.$(config.selector).selectedIndex = index;
19879 * Restore texttrack settings from localStorage
19883 TextTrackSettings.prototype.restoreSettings = function restoreSettings() {
19884 var values = void 0;
19887 values = JSON.parse(_window2['default'].localStorage.getItem(LOCAL_STORAGE_KEY));
19889 _log2['default'].warn(err);
19893 this.setValues(values);
19898 * Save text track settings to localStorage
19902 TextTrackSettings.prototype.saveSettings = function saveSettings() {
19903 if (!this.options_.persistTextTrackSettings) {
19907 var values = this.getValues();
19910 if (Object.keys(values).length) {
19911 _window2['default'].localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(values));
19913 _window2['default'].localStorage.removeItem(LOCAL_STORAGE_KEY);
19916 _log2['default'].warn(err);
19921 * Update display of text track settings
19925 TextTrackSettings.prototype.updateDisplay = function updateDisplay() {
19926 var ttDisplay = this.player_.getChild('textTrackDisplay');
19929 ttDisplay.updateDisplay();
19933 return TextTrackSettings;
19934 }(_component2['default']);
19936 _component2['default'].registerComponent('TextTrackSettings', TextTrackSettings);
19938 exports['default'] = TextTrackSettings;
19940 },{"5":5,"81":81,"83":83,"86":86,"88":88,"95":95}],72:[function(_dereq_,module,exports){
19943 exports.__esModule = true;
19945 var _textTrackCueList = _dereq_(67);
19947 var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList);
19949 var _fn = _dereq_(83);
19951 var Fn = _interopRequireWildcard(_fn);
19953 var _trackEnums = _dereq_(73);
19955 var _log = _dereq_(86);
19957 var _log2 = _interopRequireDefault(_log);
19959 var _window = _dereq_(95);
19961 var _window2 = _interopRequireDefault(_window);
19963 var _track = _dereq_(75);
19965 var _track2 = _interopRequireDefault(_track);
19967 var _url = _dereq_(92);
19969 var _xhr = _dereq_(99);
19971 var _xhr2 = _interopRequireDefault(_xhr);
19973 var _mergeOptions = _dereq_(87);
19975 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
19977 var _browser = _dereq_(78);
19979 var browser = _interopRequireWildcard(_browser);
19981 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
19983 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19985 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19987 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
19989 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
19990 * @file text-track.js
19995 * Takes a webvtt file contents and parses it into cues
19997 * @param {string} srcContent
19998 * webVTT file contents
20000 * @param {TextTrack} track
20001 * TextTrack to add cues to. Cues come from the srcContent.
20005 var parseCues = function parseCues(srcContent, track) {
20006 var parser = new _window2['default'].WebVTT.Parser(_window2['default'], _window2['default'].vttjs, _window2['default'].WebVTT.StringDecoder());
20009 parser.oncue = function (cue) {
20013 parser.onparsingerror = function (error) {
20014 errors.push(error);
20017 parser.onflush = function () {
20019 type: 'loadeddata',
20024 parser.parse(srcContent);
20025 if (errors.length > 0) {
20026 if (_window2['default'].console && _window2['default'].console.groupCollapsed) {
20027 _window2['default'].console.groupCollapsed('Text Track parsing errors for ' + track.src);
20029 errors.forEach(function (error) {
20030 return _log2['default'].error(error);
20032 if (_window2['default'].console && _window2['default'].console.groupEnd) {
20033 _window2['default'].console.groupEnd();
20041 * Load a `TextTrack` from a specifed url.
20043 * @param {string} src
20044 * Url to load track from.
20046 * @param {TextTrack} track
20047 * Track to add cues to. Comes from the content at the end of `url`.
20051 var loadTrack = function loadTrack(src, track) {
20055 var crossOrigin = (0, _url.isCrossOrigin)(src);
20058 opts.cors = crossOrigin;
20061 (0, _xhr2['default'])(opts, Fn.bind(this, function (err, response, responseBody) {
20063 return _log2['default'].error(err, response);
20066 track.loaded_ = true;
20068 // Make sure that vttjs has loaded, otherwise, wait till it finished loading
20069 // NOTE: this is only used for the alt/video.novtt.js build
20070 if (typeof _window2['default'].WebVTT !== 'function') {
20072 var loadHandler = function loadHandler() {
20073 return parseCues(responseBody, track);
20076 track.tech_.on('vttjsloaded', loadHandler);
20077 track.tech_.on('vttjserror', function () {
20078 _log2['default'].error('vttjs failed to load, stopping trying to process ' + track.src);
20079 track.tech_.off('vttjsloaded', loadHandler);
20083 parseCues(responseBody, track);
20089 * A representation of a single `TextTrack`.
20091 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack}
20095 var TextTrack = function (_Track) {
20096 _inherits(TextTrack, _Track);
20099 * Create an instance of this class.
20101 * @param {Object} options={}
20102 * Object of option names and values
20104 * @param {Tech} options.tech
20105 * A reference to the tech that owns this TextTrack.
20107 * @param {TextTrack~Kind} [options.kind='subtitles']
20108 * A valid text track kind.
20110 * @param {TextTrack~Mode} [options.mode='disabled']
20111 * A valid text track mode.
20113 * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
20114 * A unique id for this TextTrack.
20116 * @param {string} [options.label='']
20117 * The menu label for this track.
20119 * @param {string} [options.language='']
20120 * A valid two character language code.
20122 * @param {string} [options.srclang='']
20123 * A valid two character language code. An alternative, but deprioritized
20124 * vesion of `options.language`
20126 * @param {string} [options.src]
20127 * A url to TextTrack cues.
20129 * @param {boolean} [options.default]
20130 * If this track should default to on or off.
20132 function TextTrack() {
20135 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
20137 _classCallCheck(this, TextTrack);
20139 if (!options.tech) {
20140 throw new Error('A tech was not provided.');
20143 var settings = (0, _mergeOptions2['default'])(options, {
20144 kind: _trackEnums.TextTrackKind[options.kind] || 'subtitles',
20145 language: options.language || options.srclang || ''
20147 var mode = _trackEnums.TextTrackMode[settings.mode] || 'disabled';
20148 var default_ = settings['default'];
20150 if (settings.kind === 'metadata' || settings.kind === 'chapters') {
20153 // on IE8 this will be a document element
20154 // for every other browser this will be a normal object
20155 var tt = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
20157 tt.tech_ = settings.tech;
20159 if (browser.IS_IE8) {
20160 for (var prop in TextTrack.prototype) {
20161 if (prop !== 'constructor') {
20162 tt[prop] = TextTrack.prototype[prop];
20168 tt.activeCues_ = [];
20170 var cues = new _textTrackCueList2['default'](tt.cues_);
20171 var activeCues = new _textTrackCueList2['default'](tt.activeCues_);
20172 var changed = false;
20173 var timeupdateHandler = Fn.bind(tt, function () {
20175 // Accessing this.activeCues for the side-effects of updating itself
20176 // due to it's nature as a getter function. Do not remove or cues will
20178 /* eslint-disable no-unused-expressions */
20180 /* eslint-enable no-unused-expressions */
20182 this.trigger('cuechange');
20187 if (mode !== 'disabled') {
20188 tt.tech_.ready(function () {
20189 tt.tech_.on('timeupdate', timeupdateHandler);
20194 * @member {boolean} default
20195 * If this track was set to be on or off by default. Cannot be changed after
20200 Object.defineProperty(tt, 'default', {
20201 get: function get() {
20204 set: function set() {}
20208 * @member {string} mode
20209 * Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will
20210 * not be set if setting to an invalid mode.
20212 * @fires TextTrack#modechange
20214 Object.defineProperty(tt, 'mode', {
20215 get: function get() {
20218 set: function set(newMode) {
20221 if (!_trackEnums.TextTrackMode[newMode]) {
20225 if (mode === 'showing') {
20226 this.tech_.ready(function () {
20227 _this2.tech_.on('timeupdate', timeupdateHandler);
20231 * An event that fires when mode changes on this track. This allows
20232 * the TextTrackList that holds this track to act accordingly.
20234 * > Note: This is not part of the spec!
20236 * @event TextTrack#modechange
20237 * @type {EventTarget~Event}
20239 this.trigger('modechange');
20244 * @member {TextTrackCueList} cues
20245 * The text track cue list for this TextTrack.
20247 Object.defineProperty(tt, 'cues', {
20248 get: function get() {
20249 if (!this.loaded_) {
20255 set: function set() {}
20259 * @member {TextTrackCueList} activeCues
20260 * The list text track cues that are currently active for this TextTrack.
20262 Object.defineProperty(tt, 'activeCues', {
20263 get: function get() {
20264 if (!this.loaded_) {
20269 if (this.cues.length === 0) {
20273 var ct = this.tech_.currentTime();
20276 for (var i = 0, l = this.cues.length; i < l; i++) {
20277 var cue = this.cues[i];
20279 if (cue.startTime <= ct && cue.endTime >= ct) {
20281 } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) {
20288 if (active.length !== this.activeCues_.length) {
20291 for (var _i = 0; _i < active.length; _i++) {
20292 if (this.activeCues_.indexOf(active[_i]) === -1) {
20298 this.activeCues_ = active;
20299 activeCues.setCues_(this.activeCues_);
20303 set: function set() {}
20306 if (settings.src) {
20307 tt.src = settings.src;
20308 loadTrack(settings.src, tt);
20313 return _ret = tt, _possibleConstructorReturn(_this, _ret);
20317 * Add a cue to the internal list of cues.
20319 * @param {TextTrack~Cue} cue
20320 * The cue to add to our internal list
20324 TextTrack.prototype.addCue = function addCue(originalCue) {
20325 var cue = originalCue;
20327 if (_window2['default'].vttjs && !(originalCue instanceof _window2['default'].vttjs.VTTCue)) {
20328 cue = new _window2['default'].vttjs.VTTCue(originalCue.startTime, originalCue.endTime, originalCue.text);
20330 for (var prop in originalCue) {
20331 if (!(prop in cue)) {
20332 cue[prop] = originalCue[prop];
20336 // make sure that `id` is copied over
20337 cue.id = originalCue.id;
20338 cue.originalCue_ = originalCue;
20341 var tracks = this.tech_.textTracks();
20344 for (var i = 0; i < tracks.length; i++) {
20345 if (tracks[i] !== this) {
20346 tracks[i].removeCue(cue);
20351 this.cues_.push(cue);
20352 this.cues.setCues_(this.cues_);
20356 * Remove a cue from our internal list
20358 * @param {TextTrack~Cue} removeCue
20359 * The cue to remove from our internal list
20363 TextTrack.prototype.removeCue = function removeCue(_removeCue) {
20364 var i = this.cues_.length;
20367 var cue = this.cues_[i];
20369 if (cue === _removeCue || cue.originalCue_ && cue.originalCue_ === _removeCue) {
20370 this.cues_.splice(i, 1);
20371 this.cues.setCues_(this.cues_);
20378 }(_track2['default']);
20381 * cuechange - One or more cues in the track have become active or stopped being active.
20385 TextTrack.prototype.allowedEvents_ = {
20386 cuechange: 'cuechange'
20389 exports['default'] = TextTrack;
20391 },{"67":67,"73":73,"75":75,"78":78,"83":83,"86":86,"87":87,"92":92,"95":95,"99":99}],73:[function(_dereq_,module,exports){
20394 exports.__esModule = true;
20396 * @file track-kinds.js
20400 * All possible `VideoTrackKind`s
20402 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind
20403 * @typedef VideoTrack~Kind
20406 var VideoTrackKind = exports.VideoTrackKind = {
20407 alternative: 'alternative',
20408 captions: 'captions',
20411 subtitles: 'subtitles',
20412 commentary: 'commentary'
20416 * All possible `AudioTrackKind`s
20418 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind
20419 * @typedef AudioTrack~Kind
20422 var AudioTrackKind = exports.AudioTrackKind = {
20423 'alternative': 'alternative',
20424 'descriptions': 'descriptions',
20426 'main-desc': 'main-desc',
20427 'translation': 'translation',
20428 'commentary': 'commentary'
20432 * All possible `TextTrackKind`s
20434 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-texttrack-kind
20435 * @typedef TextTrack~Kind
20438 var TextTrackKind = exports.TextTrackKind = {
20439 subtitles: 'subtitles',
20440 captions: 'captions',
20441 descriptions: 'descriptions',
20442 chapters: 'chapters',
20443 metadata: 'metadata'
20447 * All possible `TextTrackMode`s
20449 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode
20450 * @typedef TextTrack~Mode
20453 var TextTrackMode = exports.TextTrackMode = {
20454 disabled: 'disabled',
20459 },{}],74:[function(_dereq_,module,exports){
20462 exports.__esModule = true;
20464 var _eventTarget = _dereq_(42);
20466 var _eventTarget2 = _interopRequireDefault(_eventTarget);
20468 var _browser = _dereq_(78);
20470 var browser = _interopRequireWildcard(_browser);
20472 var _document = _dereq_(94);
20474 var _document2 = _interopRequireDefault(_document);
20476 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
20478 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
20480 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20482 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
20484 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
20485 * @file track-list.js
20490 * Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and
20491 * {@link VideoTrackList}
20493 * @extends EventTarget
20495 var TrackList = function (_EventTarget) {
20496 _inherits(TrackList, _EventTarget);
20499 * Create an instance of this class
20501 * @param {Track[]} tracks
20502 * A list of tracks to initialize the list with.
20504 * @param {Object} [list]
20505 * The child object with inheritance done manually for ie8.
20509 function TrackList() {
20510 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
20514 var list = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
20516 _classCallCheck(this, TrackList);
20518 var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
20521 list = _this; // eslint-disable-line
20522 if (browser.IS_IE8) {
20523 list = _document2['default'].createElement('custom');
20524 for (var prop in TrackList.prototype) {
20525 if (prop !== 'constructor') {
20526 list[prop] = TrackList.prototype[prop];
20535 * @member {number} length
20536 * The current number of `Track`s in the this Trackist.
20538 Object.defineProperty(list, 'length', {
20539 get: function get() {
20540 return this.tracks_.length;
20544 for (var i = 0; i < tracks.length; i++) {
20545 list.addTrack_(tracks[i]);
20548 // must return the object, as for ie8 it will not be this
20549 // but a reference to a document object
20550 return _ret = list, _possibleConstructorReturn(_this, _ret);
20554 * Add a {@link Track} to the `TrackList`
20556 * @param {Track} track
20557 * The audio, video, or text track to add to the list.
20559 * @fires TrackList#addtrack
20564 TrackList.prototype.addTrack_ = function addTrack_(track) {
20565 var index = this.tracks_.length;
20567 if (!('' + index in this)) {
20568 Object.defineProperty(this, index, {
20569 get: function get() {
20570 return this.tracks_[index];
20575 // Do not add duplicate tracks
20576 if (this.tracks_.indexOf(track) === -1) {
20577 this.tracks_.push(track);
20579 * Triggered when a track is added to a track list.
20581 * @event TrackList#addtrack
20582 * @type {EventTarget~Event}
20583 * @property {Track} track
20584 * A reference to track that was added.
20594 * Remove a {@link Track} from the `TrackList`
20596 * @param {Track} track
20597 * The audio, video, or text track to remove from the list.
20599 * @fires TrackList#removetrack
20604 TrackList.prototype.removeTrack_ = function removeTrack_(rtrack) {
20605 var track = void 0;
20607 for (var i = 0, l = this.length; i < l; i++) {
20608 if (this[i] === rtrack) {
20614 this.tracks_.splice(i, 1);
20625 * Triggered when a track is removed from track list.
20627 * @event TrackList#removetrack
20628 * @type {EventTarget~Event}
20629 * @property {Track} track
20630 * A reference to track that was removed.
20634 type: 'removetrack'
20639 * Get a Track from the TrackList by a tracks id
20641 * @param {String} id - the id of the track to get
20642 * @method getTrackById
20648 TrackList.prototype.getTrackById = function getTrackById(id) {
20651 for (var i = 0, l = this.length; i < l; i++) {
20652 var track = this[i];
20654 if (track.id === id) {
20664 }(_eventTarget2['default']);
20667 * Triggered when a different track is selected/enabled.
20669 * @event TrackList#change
20670 * @type {EventTarget~Event}
20674 * Events that can be called with on + eventName. See {@link EventHandler}.
20676 * @property {Object} TrackList#allowedEvents_
20681 TrackList.prototype.allowedEvents_ = {
20683 addtrack: 'addtrack',
20684 removetrack: 'removetrack'
20687 // emulate attribute EventHandler support to allow for feature detection
20688 for (var event in TrackList.prototype.allowedEvents_) {
20689 TrackList.prototype['on' + event] = null;
20692 exports['default'] = TrackList;
20694 },{"42":42,"78":78,"94":94}],75:[function(_dereq_,module,exports){
20697 exports.__esModule = true;
20699 var _browser = _dereq_(78);
20701 var browser = _interopRequireWildcard(_browser);
20703 var _document = _dereq_(94);
20705 var _document2 = _interopRequireDefault(_document);
20707 var _guid = _dereq_(85);
20709 var Guid = _interopRequireWildcard(_guid);
20711 var _eventTarget = _dereq_(42);
20713 var _eventTarget2 = _interopRequireDefault(_eventTarget);
20715 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
20717 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
20719 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20721 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
20723 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
20729 * A Track class that contains all of the common functionality for {@link AudioTrack},
20730 * {@link VideoTrack}, and {@link TextTrack}.
20732 * > Note: This class should not be used directly
20734 * @see {@link https://html.spec.whatwg.org/multipage/embedded-content.html}
20735 * @extends EventTarget
20738 var Track = function (_EventTarget) {
20739 _inherits(Track, _EventTarget);
20742 * Create an instance of this class.
20744 * @param {Object} [options={}]
20745 * Object of option names and values
20747 * @param {string} [options.kind='']
20748 * A valid kind for the track type you are creating.
20750 * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
20751 * A unique id for this AudioTrack.
20753 * @param {string} [options.label='']
20754 * The menu label for this track.
20756 * @param {string} [options.language='']
20757 * A valid two character language code.
20764 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
20766 _classCallCheck(this, Track);
20768 var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
20770 var track = _this; // eslint-disable-line
20772 if (browser.IS_IE8) {
20773 track = _document2['default'].createElement('custom');
20774 for (var prop in Track.prototype) {
20775 if (prop !== 'constructor') {
20776 track[prop] = Track.prototype[prop];
20782 id: options.id || 'vjs_track_' + Guid.newGUID(),
20783 kind: options.kind || '',
20784 label: options.label || '',
20785 language: options.language || ''
20789 * @member {string} id
20790 * The id of this track. Cannot be changed after creation.
20796 * @member {string} kind
20797 * The kind of track that this is. Cannot be changed after creation.
20803 * @member {string} label
20804 * The label of this track. Cannot be changed after creation.
20810 * @member {string} language
20811 * The two letter language code for this track. Cannot be changed after
20817 var _loop = function _loop(key) {
20818 Object.defineProperty(track, key, {
20819 get: function get() {
20820 return trackProps[key];
20822 set: function set() {}
20826 for (var key in trackProps) {
20830 return _ret = track, _possibleConstructorReturn(_this, _ret);
20834 }(_eventTarget2['default']);
20836 exports['default'] = Track;
20838 },{"42":42,"78":78,"85":85,"94":94}],76:[function(_dereq_,module,exports){
20841 exports.__esModule = true;
20843 var _trackList = _dereq_(74);
20845 var _trackList2 = _interopRequireDefault(_trackList);
20847 var _browser = _dereq_(78);
20849 var browser = _interopRequireWildcard(_browser);
20851 var _document = _dereq_(94);
20853 var _document2 = _interopRequireDefault(_document);
20855 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
20857 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
20859 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20861 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
20863 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
20864 * @file video-track-list.js
20869 * Un-select all other {@link VideoTrack}s that are selected.
20871 * @param {VideoTrackList} list
20874 * @param {VideoTrack} track
20875 * The track to skip
20879 var disableOthers = function disableOthers(list, track) {
20880 for (var i = 0; i < list.length; i++) {
20881 if (track.id === list[i].id) {
20884 // another video track is enabled, disable it
20885 list[i].selected = false;
20890 * The current list of {@link VideoTrack} for a video.
20892 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist}
20893 * @extends TrackList
20896 var VideoTrackList = function (_TrackList) {
20897 _inherits(VideoTrackList, _TrackList);
20900 * Create an instance of this class.
20902 * @param {VideoTrack[]} [tracks=[]]
20903 * A list of `VideoTrack` to instantiate the list with.
20905 function VideoTrackList() {
20908 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
20910 _classCallCheck(this, VideoTrackList);
20914 // make sure only 1 track is enabled
20915 // sorted from last index to first index
20916 for (var i = tracks.length - 1; i >= 0; i--) {
20917 if (tracks[i].selected) {
20918 disableOthers(tracks, tracks[i]);
20923 // IE8 forces us to implement inheritance ourselves
20924 // as it does not support Object.defineProperty properly
20925 if (browser.IS_IE8) {
20926 list = _document2['default'].createElement('custom');
20927 for (var prop in _trackList2['default'].prototype) {
20928 if (prop !== 'constructor') {
20929 list[prop] = _trackList2['default'].prototype[prop];
20932 for (var _prop in VideoTrackList.prototype) {
20933 if (_prop !== 'constructor') {
20934 list[_prop] = VideoTrackList.prototype[_prop];
20939 list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
20940 list.changing_ = false;
20943 * @member {number} VideoTrackList#selectedIndex
20944 * The current index of the selected {@link VideoTrack`}.
20946 Object.defineProperty(list, 'selectedIndex', {
20947 get: function get() {
20948 for (var _i = 0; _i < this.length; _i++) {
20949 if (this[_i].selected) {
20955 set: function set() {}
20958 return _ret = list, _possibleConstructorReturn(_this, _ret);
20962 * Add a {@link VideoTrack} to the `VideoTrackList`.
20964 * @param {VideoTrack} track
20965 * The VideoTrack to add to the list
20967 * @fires TrackList#addtrack
20972 VideoTrackList.prototype.addTrack_ = function addTrack_(track) {
20975 if (track.selected) {
20976 disableOthers(this, track);
20979 _TrackList.prototype.addTrack_.call(this, track);
20980 // native tracks don't have this
20981 if (!track.addEventListener) {
20986 * @listens VideoTrack#selectedchange
20987 * @fires TrackList#change
20989 track.addEventListener('selectedchange', function () {
20990 if (_this2.changing_) {
20993 _this2.changing_ = true;
20994 disableOthers(_this2, track);
20995 _this2.changing_ = false;
20996 _this2.trigger('change');
21001 * Add a {@link VideoTrack} to the `VideoTrackList`.
21003 * @param {VideoTrack} track
21004 * The VideoTrack to add to the list
21006 * @fires TrackList#addtrack
21010 VideoTrackList.prototype.addTrack = function addTrack(track) {
21011 this.addTrack_(track);
21015 * Remove a {@link VideoTrack} to the `VideoTrackList`.
21017 * @param {VideoTrack} track
21018 * The VideoTrack to remove from the list.
21020 * @fires TrackList#removetrack
21024 VideoTrackList.prototype.removeTrack = function removeTrack(track) {
21025 _TrackList.prototype.removeTrack_.call(this, track);
21028 return VideoTrackList;
21029 }(_trackList2['default']);
21031 exports['default'] = VideoTrackList;
21033 },{"74":74,"78":78,"94":94}],77:[function(_dereq_,module,exports){
21036 exports.__esModule = true;
21038 var _trackEnums = _dereq_(73);
21040 var _track = _dereq_(75);
21042 var _track2 = _interopRequireDefault(_track);
21044 var _mergeOptions = _dereq_(87);
21046 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
21048 var _browser = _dereq_(78);
21050 var browser = _interopRequireWildcard(_browser);
21052 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
21054 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21056 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
21058 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
21060 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
21063 * A representation of a single `VideoTrack`.
21065 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack}
21068 var VideoTrack = function (_Track) {
21069 _inherits(VideoTrack, _Track);
21072 * Create an instance of this class.
21074 * @param {Object} [options={}]
21075 * Object of option names and values
21077 * @param {string} [options.kind='']
21078 * A valid {@link VideoTrack~Kind}
21080 * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
21081 * A unique id for this AudioTrack.
21083 * @param {string} [options.label='']
21084 * The menu label for this track.
21086 * @param {string} [options.language='']
21087 * A valid two character language code.
21089 * @param {boolean} [options.selected]
21090 * If this track is the one that is currently playing.
21092 function VideoTrack() {
21095 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
21097 _classCallCheck(this, VideoTrack);
21099 var settings = (0, _mergeOptions2['default'])(options, {
21100 kind: _trackEnums.VideoTrackKind[options.kind] || ''
21103 // on IE8 this will be a document element
21104 // for every other browser this will be a normal object
21105 var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
21106 var selected = false;
21108 if (browser.IS_IE8) {
21109 for (var prop in VideoTrack.prototype) {
21110 if (prop !== 'constructor') {
21111 track[prop] = VideoTrack.prototype[prop];
21117 * @member {boolean} selected
21118 * If this `VideoTrack` is selected or not. When setting this will
21119 * fire {@link VideoTrack#selectedchange} if the state of selected changed.
21121 * @fires VideoTrack#selectedchange
21123 Object.defineProperty(track, 'selected', {
21124 get: function get() {
21127 set: function set(newSelected) {
21128 // an invalid or unchanged value
21129 if (typeof newSelected !== 'boolean' || newSelected === selected) {
21132 selected = newSelected;
21135 * An event that fires when selected changes on this track. This allows
21136 * the VideoTrackList that holds this track to act accordingly.
21138 * > Note: This is not part of the spec! Native tracks will do
21139 * this internally without an event.
21141 * @event VideoTrack#selectedchange
21142 * @type {EventTarget~Event}
21144 this.trigger('selectedchange');
21148 // if the user sets this track to selected then
21149 // set selected to that true value otherwise
21150 // we keep it false
21151 if (settings.selected) {
21152 track.selected = settings.selected;
21155 return _ret = track, _possibleConstructorReturn(_this, _ret);
21159 }(_track2['default']);
21161 exports['default'] = VideoTrack;
21163 },{"73":73,"75":75,"78":78,"87":87}],78:[function(_dereq_,module,exports){
21166 exports.__esModule = true;
21167 exports.BACKGROUND_SIZE_SUPPORTED = exports.TOUCH_ENABLED = exports.IS_ANY_SAFARI = exports.IS_SAFARI = exports.IE_VERSION = exports.IS_IE8 = exports.IS_CHROME = exports.IS_EDGE = exports.IS_FIREFOX = exports.IS_NATIVE_ANDROID = exports.IS_OLD_ANDROID = exports.ANDROID_VERSION = exports.IS_ANDROID = exports.IOS_VERSION = exports.IS_IOS = exports.IS_IPOD = exports.IS_IPHONE = exports.IS_IPAD = undefined;
21169 var _dom = _dereq_(81);
21171 var Dom = _interopRequireWildcard(_dom);
21173 var _window = _dereq_(95);
21175 var _window2 = _interopRequireDefault(_window);
21177 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21179 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
21185 var USER_AGENT = _window2['default'].navigator && _window2['default'].navigator.userAgent || '';
21186 var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT);
21187 var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null;
21190 * Device is an iPhone
21196 var IS_IPAD = exports.IS_IPAD = /iPad/i.test(USER_AGENT);
21198 // The Facebook app's UIWebView identifies as both an iPhone and iPad, so
21199 // to identify iPhones, we need to exclude iPads.
21200 // http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/
21201 var IS_IPHONE = exports.IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD;
21202 var IS_IPOD = exports.IS_IPOD = /iPod/i.test(USER_AGENT);
21203 var IS_IOS = exports.IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;
21205 var IOS_VERSION = exports.IOS_VERSION = function () {
21206 var match = USER_AGENT.match(/OS (\d+)_/i);
21208 if (match && match[1]) {
21214 var IS_ANDROID = exports.IS_ANDROID = /Android/i.test(USER_AGENT);
21215 var ANDROID_VERSION = exports.ANDROID_VERSION = function () {
21216 // This matches Android Major.Minor.Patch versions
21217 // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
21218 var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);
21224 var major = match[1] && parseFloat(match[1]);
21225 var minor = match[2] && parseFloat(match[2]);
21227 if (major && minor) {
21228 return parseFloat(match[1] + '.' + match[2]);
21229 } else if (major) {
21235 // Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser
21236 var IS_OLD_ANDROID = exports.IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3;
21237 var IS_NATIVE_ANDROID = exports.IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537;
21239 var IS_FIREFOX = exports.IS_FIREFOX = /Firefox/i.test(USER_AGENT);
21240 var IS_EDGE = exports.IS_EDGE = /Edge/i.test(USER_AGENT);
21241 var IS_CHROME = exports.IS_CHROME = !IS_EDGE && /Chrome/i.test(USER_AGENT);
21242 var IS_IE8 = exports.IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT);
21243 var IE_VERSION = exports.IE_VERSION = function () {
21244 var result = /MSIE\s(\d+)\.\d/.exec(USER_AGENT);
21245 var version = result && parseFloat(result[1]);
21247 if (!version && /Trident\/7.0/i.test(USER_AGENT) && /rv:11.0/.test(USER_AGENT)) {
21248 // IE 11 has a different user agent string than other IE versions
21255 var IS_SAFARI = exports.IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE;
21256 var IS_ANY_SAFARI = exports.IS_ANY_SAFARI = IS_SAFARI || IS_IOS;
21258 var TOUCH_ENABLED = exports.TOUCH_ENABLED = Dom.isReal() && ('ontouchstart' in _window2['default'] || _window2['default'].DocumentTouch && _window2['default'].document instanceof _window2['default'].DocumentTouch);
21260 var BACKGROUND_SIZE_SUPPORTED = exports.BACKGROUND_SIZE_SUPPORTED = Dom.isReal() && 'backgroundSize' in _window2['default'].document.createElement('video').style;
21262 },{"81":81,"95":95}],79:[function(_dereq_,module,exports){
21265 exports.__esModule = true;
21266 exports.bufferedPercent = bufferedPercent;
21268 var _timeRanges = _dereq_(90);
21271 * Compute the percentage of the media that has been buffered.
21273 * @param {TimeRange} buffered
21274 * The current `TimeRange` object representing buffered time ranges
21276 * @param {number} duration
21277 * Total duration of the media
21280 * Percent buffered of the total duration in decimal form.
21282 function bufferedPercent(buffered, duration) {
21283 var bufferedDuration = 0;
21284 var start = void 0;
21291 if (!buffered || !buffered.length) {
21292 buffered = (0, _timeRanges.createTimeRange)(0, 0);
21295 for (var i = 0; i < buffered.length; i++) {
21296 start = buffered.start(i);
21297 end = buffered.end(i);
21299 // buffered end can be bigger than duration by a very small fraction
21300 if (end > duration) {
21304 bufferedDuration += end - start;
21307 return bufferedDuration / duration;
21313 },{"90":90}],80:[function(_dereq_,module,exports){
21316 exports.__esModule = true;
21317 exports['default'] = computedStyle;
21319 var _window = _dereq_(95);
21321 var _window2 = _interopRequireDefault(_window);
21323 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21326 * A safe getComputedStyle with an IE8 fallback.
21328 * This is needed because in Firefox, if the player is loaded in an iframe with
21329 * `display:none`, then `getComputedStyle` returns `null`, so, we do a null-check to
21330 * make sure that the player doesn't break in these cases.
21332 * @param {Element} el
21333 * The element you want the computed style of
21335 * @param {string} prop
21336 * The property name you want
21338 * @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397
21340 function computedStyle(el, prop) {
21341 if (!el || !prop) {
21345 if (typeof _window2['default'].getComputedStyle === 'function') {
21346 var cs = _window2['default'].getComputedStyle(el);
21348 return cs ? cs[prop] : '';
21351 return el.currentStyle[prop] || '';
21353 * @file computed-style.js
21354 * @module computed-style
21357 },{"95":95}],81:[function(_dereq_,module,exports){
21360 exports.__esModule = true;
21361 exports.$$ = exports.$ = undefined;
21363 var _templateObject = _taggedTemplateLiteralLoose(['Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set ', ' to ', '.'], ['Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set ', ' to ', '.']);
21365 exports.isReal = isReal;
21366 exports.isEl = isEl;
21367 exports.getEl = getEl;
21368 exports.createEl = createEl;
21369 exports.textContent = textContent;
21370 exports.insertElFirst = insertElFirst;
21371 exports.getElData = getElData;
21372 exports.hasElData = hasElData;
21373 exports.removeElData = removeElData;
21374 exports.hasElClass = hasElClass;
21375 exports.addElClass = addElClass;
21376 exports.removeElClass = removeElClass;
21377 exports.toggleElClass = toggleElClass;
21378 exports.setElAttributes = setElAttributes;
21379 exports.getElAttributes = getElAttributes;
21380 exports.getAttribute = getAttribute;
21381 exports.setAttribute = setAttribute;
21382 exports.removeAttribute = removeAttribute;
21383 exports.blockTextSelection = blockTextSelection;
21384 exports.unblockTextSelection = unblockTextSelection;
21385 exports.findElPosition = findElPosition;
21386 exports.getPointerPosition = getPointerPosition;
21387 exports.isTextNode = isTextNode;
21388 exports.emptyEl = emptyEl;
21389 exports.normalizeContent = normalizeContent;
21390 exports.appendContent = appendContent;
21391 exports.insertContent = insertContent;
21393 var _document = _dereq_(94);
21395 var _document2 = _interopRequireDefault(_document);
21397 var _window = _dereq_(95);
21399 var _window2 = _interopRequireDefault(_window);
21401 var _guid = _dereq_(85);
21403 var Guid = _interopRequireWildcard(_guid);
21405 var _log = _dereq_(86);
21407 var _log2 = _interopRequireDefault(_log);
21409 var _tsml = _dereq_(98);
21411 var _tsml2 = _interopRequireDefault(_tsml);
21413 var _obj = _dereq_(88);
21415 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
21417 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21419 function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } /**
21426 * Detect if a value is a string with any non-whitespace characters.
21428 * @param {string} str
21429 * The string to check
21431 * @return {boolean}
21432 * - True if the string is non-blank
21433 * - False otherwise
21436 function isNonBlankString(str) {
21437 return typeof str === 'string' && /\S/.test(str);
21441 * Throws an error if the passed string has whitespace. This is used by
21442 * class methods to be relatively consistent with the classList API.
21444 * @param {string} str
21445 * The string to check for whitespace.
21448 * Throws an error if there is whitespace in the string.
21451 function throwIfWhitespace(str) {
21452 if (/\s/.test(str)) {
21453 throw new Error('class has illegal whitespace characters');
21458 * Produce a regular expression for matching a className within an elements className.
21460 * @param {string} className
21461 * The className to generate the RegExp for.
21464 * The RegExp that will check for a specific `className` in an elements
21467 function classRegExp(className) {
21468 return new RegExp('(^|\\s)' + className + '($|\\s)');
21472 * Whether the current DOM interface appears to be real.
21474 * @return {Boolean}
21476 function isReal() {
21479 // Both document and window will never be undefined thanks to `global`.
21480 _document2['default'] === _window2['default'].document &&
21482 // In IE < 9, DOM methods return "object" as their type, so all we can
21483 // confidently check is that it exists.
21484 typeof _document2['default'].createElement !== 'undefined'
21489 * Determines, via duck typing, whether or not a value is a DOM element.
21491 * @param {Mixed} value
21492 * The thing to check
21494 * @return {boolean}
21495 * - True if it is a DOM element
21496 * - False otherwise
21498 function isEl(value) {
21499 return (0, _obj.isObject)(value) && value.nodeType === 1;
21503 * Creates functions to query the DOM using a given method.
21505 * @param {string} method
21506 * The method to create the query with.
21508 * @return {Function}
21511 function createQuerier(method) {
21512 return function (selector, context) {
21513 if (!isNonBlankString(selector)) {
21514 return _document2['default'][method](null);
21516 if (isNonBlankString(context)) {
21517 context = _document2['default'].querySelector(context);
21520 var ctx = isEl(context) ? context : _document2['default'];
21522 return ctx[method] && ctx[method](selector);
21527 * Shorthand for document.getElementById()
21528 * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs.
21530 * @param {string} id
21531 * The id of the element to get
21533 * @return {Element|null}
21534 * Element with supplied ID or null if there wasn't one.
21536 function getEl(id) {
21537 if (id.indexOf('#') === 0) {
21541 return _document2['default'].getElementById(id);
21545 * Creates an element and applies properties.
21547 * @param {string} [tagName='div']
21548 * Name of tag to be created.
21550 * @param {Object} [properties={}]
21551 * Element properties to be applied.
21553 * @param {Object} [attributes={}]
21554 * Element attributes to be applied.
21556 * @param {String|Element|TextNode|Array|Function} [content]
21557 * Contents for the element (see: {@link dom:normalizeContent})
21559 * @return {Element}
21560 * The element that was created.
21562 function createEl() {
21563 var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
21564 var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
21565 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
21566 var content = arguments[3];
21568 var el = _document2['default'].createElement(tagName);
21570 Object.getOwnPropertyNames(properties).forEach(function (propName) {
21571 var val = properties[propName];
21574 // We originally were accepting both properties and attributes in the
21575 // same object, but that doesn't work so well.
21576 if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') {
21577 _log2['default'].warn((0, _tsml2['default'])(_templateObject, propName, val));
21578 el.setAttribute(propName, val);
21580 // Handle textContent since it's not supported everywhere and we have a
21582 } else if (propName === 'textContent') {
21583 textContent(el, val);
21585 el[propName] = val;
21589 Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
21590 el.setAttribute(attrName, attributes[attrName]);
21594 appendContent(el, content);
21601 * Injects text into an element, replacing any existing contents entirely.
21603 * @param {Element} el
21604 * The element to add text content into
21606 * @param {string} text
21607 * The text content to add.
21609 * @return {Element}
21610 * The element with added text content.
21612 function textContent(el, text) {
21613 if (typeof el.textContent === 'undefined') {
21614 el.innerText = text;
21616 el.textContent = text;
21622 * Insert an element as the first child node of another
21624 * @param {Element} child
21625 * Element to insert
21627 * @param {Element} parent
21628 * Element to insert child into
21631 function insertElFirst(child, parent) {
21632 if (parent.firstChild) {
21633 parent.insertBefore(child, parent.firstChild);
21635 parent.appendChild(child);
21640 * Element Data Store. Allows for binding data to an element without putting it directly on the element.
21641 * Ex. Event listeners are stored here.
21642 * (also from jsninja.com, slightly modified and updated for closure compiler)
21650 * Unique attribute name to store an element's guid in
21656 var elIdAttr = 'vdata' + new Date().getTime();
21659 * Returns the cache object where data for an element is stored
21661 * @param {Element} el
21662 * Element to store data for.
21665 * The cache object for that el that was passed in.
21667 function getElData(el) {
21668 var id = el[elIdAttr];
21671 id = el[elIdAttr] = Guid.newGUID();
21682 * Returns whether or not an element has cached data
21684 * @param {Element} el
21685 * Check if this element has cached data.
21687 * @return {boolean}
21688 * - True if the DOM element has cached data.
21689 * - False otherwise.
21691 function hasElData(el) {
21692 var id = el[elIdAttr];
21698 return !!Object.getOwnPropertyNames(elData[id]).length;
21702 * Delete data for the element from the cache and the guid attr from getElementById
21704 * @param {Element} el
21705 * Remove cached data for this element.
21707 function removeElData(el) {
21708 var id = el[elIdAttr];
21714 // Remove all stored data
21717 // Remove the elIdAttr property from the DOM node
21719 delete el[elIdAttr];
21721 if (el.removeAttribute) {
21722 el.removeAttribute(elIdAttr);
21724 // IE doesn't appear to support removeAttribute on the document element
21725 el[elIdAttr] = null;
21731 * Check if an element has a CSS class
21733 * @param {Element} element
21736 * @param {string} classToCheck
21737 * Class name to check for
21739 * @return {boolean}
21740 * - True if the element had the class
21741 * - False otherwise.
21744 * Throws an error if `classToCheck` has white space.
21746 function hasElClass(element, classToCheck) {
21747 throwIfWhitespace(classToCheck);
21748 if (element.classList) {
21749 return element.classList.contains(classToCheck);
21751 return classRegExp(classToCheck).test(element.className);
21755 * Add a CSS class name to an element
21757 * @param {Element} element
21758 * Element to add class name to.
21760 * @param {string} classToAdd
21761 * Class name to add.
21763 * @return {Element}
21764 * The dom element with the added class name.
21766 function addElClass(element, classToAdd) {
21767 if (element.classList) {
21768 element.classList.add(classToAdd);
21770 // Don't need to `throwIfWhitespace` here because `hasElClass` will do it
21771 // in the case of classList not being supported.
21772 } else if (!hasElClass(element, classToAdd)) {
21773 element.className = (element.className + ' ' + classToAdd).trim();
21780 * Remove a CSS class name from an element
21782 * @param {Element} element
21783 * Element to remove a class name from.
21785 * @param {string} classToRemove
21786 * Class name to remove
21788 * @return {Element}
21789 * The dom element with class name removed.
21791 function removeElClass(element, classToRemove) {
21792 if (element.classList) {
21793 element.classList.remove(classToRemove);
21795 throwIfWhitespace(classToRemove);
21796 element.className = element.className.split(/\s+/).filter(function (c) {
21797 return c !== classToRemove;
21805 * The callback definition for toggleElClass.
21807 * @callback Dom~PredicateCallback
21808 * @param {Element} element
21809 * The DOM element of the Component.
21811 * @param {string} classToToggle
21812 * The `className` that wants to be toggled
21814 * @return {boolean|undefined}
21815 * - If true the `classToToggle` will get added to `element`.
21816 * - If false the `classToToggle` will get removed from `element`.
21817 * - If undefined this callback will be ignored
21821 * Adds or removes a CSS class name on an element depending on an optional
21822 * condition or the presence/absence of the class name.
21824 * @param {Element} element
21825 * The element to toggle a class name on.
21827 * @param {string} classToToggle
21828 * The class that should be toggled
21830 * @param {boolean|PredicateCallback} [predicate]
21831 * See the return value for {@link Dom~PredicateCallback}
21833 * @return {Element}
21834 * The element with a class that has been toggled.
21836 function toggleElClass(element, classToToggle, predicate) {
21838 // This CANNOT use `classList` internally because IE does not support the
21839 // second parameter to the `classList.toggle()` method! Which is fine because
21840 // `classList` will be used by the add/remove functions.
21841 var has = hasElClass(element, classToToggle);
21843 if (typeof predicate === 'function') {
21844 predicate = predicate(element, classToToggle);
21847 if (typeof predicate !== 'boolean') {
21851 // If the necessary class operation matches the current state of the
21852 // element, no action is required.
21853 if (predicate === has) {
21858 addElClass(element, classToToggle);
21860 removeElClass(element, classToToggle);
21867 * Apply attributes to an HTML element.
21869 * @param {Element} el
21870 * Element to add attributes to.
21872 * @param {Object} [attributes]
21873 * Attributes to be applied.
21875 function setElAttributes(el, attributes) {
21876 Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
21877 var attrValue = attributes[attrName];
21879 if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
21880 el.removeAttribute(attrName);
21882 el.setAttribute(attrName, attrValue === true ? '' : attrValue);
21888 * Get an element's attribute values, as defined on the HTML tag
21889 * Attributes are not the same as properties. They're defined on the tag
21890 * or with setAttribute (which shouldn't be used with HTML)
21891 * This will return true or false for boolean attributes.
21893 * @param {Element} tag
21894 * Element from which to get tag attributes.
21897 * All attributes of the element.
21899 function getElAttributes(tag) {
21902 // known boolean attributes
21903 // we can check for matching boolean properties, but older browsers
21904 // won't know about HTML5 boolean attributes that we still read from
21905 var knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ',';
21907 if (tag && tag.attributes && tag.attributes.length > 0) {
21908 var attrs = tag.attributes;
21910 for (var i = attrs.length - 1; i >= 0; i--) {
21911 var attrName = attrs[i].name;
21912 var attrVal = attrs[i].value;
21914 // check for known booleans
21915 // the matching element property will return a value for typeof
21916 if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {
21917 // the value of an included boolean attribute is typically an empty
21918 // string ('') which would equal false if we just check for a false value.
21919 // we also don't want support bad code like autoplay='false'
21920 attrVal = attrVal !== null ? true : false;
21923 obj[attrName] = attrVal;
21931 * Get the value of an element's attribute
21933 * @param {Element} el
21936 * @param {string} attribute
21937 * Attribute to get the value of
21940 * value of the attribute
21942 function getAttribute(el, attribute) {
21943 return el.getAttribute(attribute);
21947 * Set the value of an element's attribute
21949 * @param {Element} el
21952 * @param {string} attribute
21955 * @param {string} value
21956 * Value to set the attribute to
21958 function setAttribute(el, attribute, value) {
21959 el.setAttribute(attribute, value);
21963 * Remove an element's attribute
21965 * @param {Element} el
21968 * @param {string} attribute
21969 * Attribute to remove
21971 function removeAttribute(el, attribute) {
21972 el.removeAttribute(attribute);
21976 * Attempt to block the ability to select text while dragging controls
21978 function blockTextSelection() {
21979 _document2['default'].body.focus();
21980 _document2['default'].onselectstart = function () {
21986 * Turn off text selection blocking
21988 function unblockTextSelection() {
21989 _document2['default'].onselectstart = function () {
21995 * The postion of a DOM element on the page.
21997 * @typedef {Object} Dom~Position
21999 * @property {number} left
22000 * Pixels to the left
22002 * @property {number} top
22008 * getBoundingClientRect technique from
22011 * @see http://ejohn.org/blog/getboundingclientrect-is-awesome/
22013 * @param {Element} el
22014 * Element from which to get offset
22016 * @return {Dom~Position}
22017 * The position of the element that was passed in.
22019 function findElPosition(el) {
22022 if (el.getBoundingClientRect && el.parentNode) {
22023 box = el.getBoundingClientRect();
22033 var docEl = _document2['default'].documentElement;
22034 var body = _document2['default'].body;
22036 var clientLeft = docEl.clientLeft || body.clientLeft || 0;
22037 var scrollLeft = _window2['default'].pageXOffset || body.scrollLeft;
22038 var left = box.left + scrollLeft - clientLeft;
22040 var clientTop = docEl.clientTop || body.clientTop || 0;
22041 var scrollTop = _window2['default'].pageYOffset || body.scrollTop;
22042 var top = box.top + scrollTop - clientTop;
22044 // Android sometimes returns slightly off decimal values, so need to round
22046 left: Math.round(left),
22047 top: Math.round(top)
22052 * x and y coordinates for a dom element or mouse pointer
22054 * @typedef {Object} Dom~Coordinates
22056 * @property {number} x
22057 * x coordinate in pixels
22059 * @property {number} y
22060 * y coordinate in pixels
22064 * Get pointer position in element
22065 * Returns an object with x and y coordinates.
22066 * The base on the coordinates are the bottom left of the element.
22068 * @param {Element} el
22069 * Element on which to get the pointer position on
22071 * @param {EventTarget~Event} event
22074 * @return {Dom~Coordinates}
22075 * A Coordinates object corresponding to the mouse position.
22078 function getPointerPosition(el, event) {
22080 var box = findElPosition(el);
22081 var boxW = el.offsetWidth;
22082 var boxH = el.offsetHeight;
22084 var boxY = box.top;
22085 var boxX = box.left;
22086 var pageY = event.pageY;
22087 var pageX = event.pageX;
22089 if (event.changedTouches) {
22090 pageX = event.changedTouches[0].pageX;
22091 pageY = event.changedTouches[0].pageY;
22094 position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH));
22095 position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));
22101 * Determines, via duck typing, whether or not a value is a text node.
22103 * @param {Mixed} value
22104 * Check if this value is a text node.
22106 * @return {boolean}
22107 * - True if it is a text node
22108 * - False otherwise
22110 function isTextNode(value) {
22111 return (0, _obj.isObject)(value) && value.nodeType === 3;
22115 * Empties the contents of an element.
22117 * @param {Element} el
22118 * The element to empty children from
22120 * @return {Element}
22121 * The element with no children
22123 function emptyEl(el) {
22124 while (el.firstChild) {
22125 el.removeChild(el.firstChild);
22131 * Normalizes content for eventual insertion into the DOM.
22133 * This allows a wide range of content definition methods, but protects
22134 * from falling into the trap of simply writing to `innerHTML`, which is
22137 * The content for an element can be passed in multiple types and
22138 * combinations, whose behavior is as follows:
22140 * @param {String|Element|TextNode|Array|Function} content
22141 * - String: Normalized into a text node.
22142 * - Element/TextNode: Passed through.
22143 * - Array: A one-dimensional array of strings, elements, nodes, or functions
22144 * (which return single strings, elements, or nodes).
22145 * - Function: If the sole argument, is expected to produce a string, element,
22146 * node, or array as defined above.
22149 * All of the content that was passed in normalized.
22151 function normalizeContent(content) {
22153 // First, invoke content if it is a function. If it produces an array,
22154 // that needs to happen before normalization.
22155 if (typeof content === 'function') {
22156 content = content();
22159 // Next up, normalize to an array, so one or many items can be normalized,
22160 // filtered, and returned.
22161 return (Array.isArray(content) ? content : [content]).map(function (value) {
22163 // First, invoke value if it is a function to produce a new value,
22164 // which will be subsequently normalized to a Node of some kind.
22165 if (typeof value === 'function') {
22169 if (isEl(value) || isTextNode(value)) {
22173 if (typeof value === 'string' && /\S/.test(value)) {
22174 return _document2['default'].createTextNode(value);
22176 }).filter(function (value) {
22182 * Normalizes and appends content to an element.
22184 * @param {Element} el
22185 * Element to append normalized content to.
22188 * @param {String|Element|TextNode|Array|Function} content
22189 * See the `content` argument of {@link dom:normalizeContent}
22191 * @return {Element}
22192 * The element with appended normalized content.
22194 function appendContent(el, content) {
22195 normalizeContent(content).forEach(function (node) {
22196 return el.appendChild(node);
22202 * Normalizes and inserts content into an element; this is identical to
22203 * `appendContent()`, except it empties the element first.
22205 * @param {Element} el
22206 * Element to insert normalized content into.
22208 * @param {String|Element|TextNode|Array|Function} content
22209 * See the `content` argument of {@link dom:normalizeContent}
22211 * @return {Element}
22212 * The element with inserted normalized content.
22215 function insertContent(el, content) {
22216 return appendContent(emptyEl(el), content);
22220 * Finds a single DOM element matching `selector` within the optional
22221 * `context` of another DOM element (defaulting to `document`).
22223 * @param {string} selector
22224 * A valid CSS selector, which will be passed to `querySelector`.
22226 * @param {Element|String} [context=document]
22227 * A DOM element within which to query. Can also be a selector
22228 * string in which case the first matching element will be used
22229 * as context. If missing (or no element matches selector), falls
22230 * back to `document`.
22232 * @return {Element|null}
22233 * The element that was found or null.
22235 var $ = exports.$ = createQuerier('querySelector');
22238 * Finds a all DOM elements matching `selector` within the optional
22239 * `context` of another DOM element (defaulting to `document`).
22241 * @param {string} selector
22242 * A valid CSS selector, which will be passed to `querySelectorAll`.
22244 * @param {Element|String} [context=document]
22245 * A DOM element within which to query. Can also be a selector
22246 * string in which case the first matching element will be used
22247 * as context. If missing (or no element matches selector), falls
22248 * back to `document`.
22250 * @return {NodeList}
22251 * A element list of elements that were found. Will be empty if none were found.
22254 var $$ = exports.$$ = createQuerier('querySelectorAll');
22256 },{"85":85,"86":86,"88":88,"94":94,"95":95,"98":98}],82:[function(_dereq_,module,exports){
22259 exports.__esModule = true;
22260 exports.fixEvent = fixEvent;
22263 exports.trigger = trigger;
22266 var _dom = _dereq_(81);
22268 var Dom = _interopRequireWildcard(_dom);
22270 var _guid = _dereq_(85);
22272 var Guid = _interopRequireWildcard(_guid);
22274 var _log = _dereq_(86);
22276 var _log2 = _interopRequireDefault(_log);
22278 var _window = _dereq_(95);
22280 var _window2 = _interopRequireDefault(_window);
22282 var _document = _dereq_(94);
22284 var _document2 = _interopRequireDefault(_document);
22286 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
22288 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
22291 * Clean up the listener cache and dispatchers
22293 * @param {Element|Object} elem
22294 * Element to clean up
22296 * @param {string} type
22297 * Type of event to clean up
22299 function _cleanUpEvents(elem, type) {
22300 var data = Dom.getElData(elem);
22302 // Remove the events of a particular type if there are none left
22303 if (data.handlers[type].length === 0) {
22304 delete data.handlers[type];
22305 // data.handlers[type] = null;
22306 // Setting to null was causing an error with data.handlers
22308 // Remove the meta-handler from the element
22309 if (elem.removeEventListener) {
22310 elem.removeEventListener(type, data.dispatcher, false);
22311 } else if (elem.detachEvent) {
22312 elem.detachEvent('on' + type, data.dispatcher);
22316 // Remove the events object if there are no types left
22317 if (Object.getOwnPropertyNames(data.handlers).length <= 0) {
22318 delete data.handlers;
22319 delete data.dispatcher;
22320 delete data.disabled;
22323 // Finally remove the element data if there is no data left
22324 if (Object.getOwnPropertyNames(data).length === 0) {
22325 Dom.removeElData(elem);
22330 * Loops through an array of event types and calls the requested method for each type.
22332 * @param {Function} fn
22333 * The event method we want to use.
22335 * @param {Element|Object} elem
22336 * Element or object to bind listeners to
22338 * @param {string} type
22339 * Type of event to bind to.
22341 * @param {EventTarget~EventListener} callback
22345 * @file events.js. An Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/)
22346 * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible)
22347 * This should work very similarly to jQuery's events, however it's based off the book version which isn't as
22348 * robust as jquery's, so there's probably some differences.
22353 function _handleMultipleEvents(fn, elem, types, callback) {
22354 types.forEach(function (type) {
22355 // Call the event method for each one of the types
22356 fn(elem, type, callback);
22361 * Fix a native event to have standard property values
22363 * @param {Object} event
22364 * Event object to fix.
22367 * Fixed event object.
22369 function fixEvent(event) {
22371 function returnTrue() {
22375 function returnFalse() {
22379 // Test if fixing up is needed
22380 // Used to check if !event.stopPropagation instead of isPropagationStopped
22381 // But native events return true for stopPropagation, but don't have
22382 // other expected methods like isPropagationStopped. Seems to be a problem
22383 // with the Javascript Ninja code. So we're just overriding all events now.
22384 if (!event || !event.isPropagationStopped) {
22385 var old = event || _window2['default'].event;
22388 // Clone the old object so that we can modify the values event = {};
22389 // IE8 Doesn't like when you mess with native event properties
22390 // Firefox returns false for event.hasOwnProperty('type') and other props
22391 // which makes copying more difficult.
22392 // TODO: Probably best to create a whitelist of event props
22393 for (var key in old) {
22394 // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
22395 // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation
22396 // and webkitMovementX/Y
22397 if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') {
22398 // Chrome 32+ warns if you try to copy deprecated returnValue, but
22399 // we still want to if preventDefault isn't supported (IE8).
22400 if (!(key === 'returnValue' && old.preventDefault)) {
22401 event[key] = old[key];
22406 // The event occurred on this element
22407 if (!event.target) {
22408 event.target = event.srcElement || _document2['default'];
22411 // Handle which other element the event is related to
22412 if (!event.relatedTarget) {
22413 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
22416 // Stop the default browser action
22417 event.preventDefault = function () {
22418 if (old.preventDefault) {
22419 old.preventDefault();
22421 event.returnValue = false;
22422 old.returnValue = false;
22423 event.defaultPrevented = true;
22426 event.defaultPrevented = false;
22428 // Stop the event from bubbling
22429 event.stopPropagation = function () {
22430 if (old.stopPropagation) {
22431 old.stopPropagation();
22433 event.cancelBubble = true;
22434 old.cancelBubble = true;
22435 event.isPropagationStopped = returnTrue;
22438 event.isPropagationStopped = returnFalse;
22440 // Stop the event from bubbling and executing other handlers
22441 event.stopImmediatePropagation = function () {
22442 if (old.stopImmediatePropagation) {
22443 old.stopImmediatePropagation();
22445 event.isImmediatePropagationStopped = returnTrue;
22446 event.stopPropagation();
22449 event.isImmediatePropagationStopped = returnFalse;
22451 // Handle mouse position
22452 if (event.clientX !== null && event.clientX !== undefined) {
22453 var doc = _document2['default'].documentElement;
22454 var body = _document2['default'].body;
22456 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
22457 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
22460 // Handle key presses
22461 event.which = event.charCode || event.keyCode;
22463 // Fix button for mouse clicks:
22464 // 0 == left; 1 == middle; 2 == right
22465 if (event.button !== null && event.button !== undefined) {
22467 // The following is disabled because it does not pass videojs-standard
22469 /* eslint-disable */
22470 event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0;
22471 /* eslint-enable */
22475 // Returns fixed-up instance
22480 * Add an event listener to element
22481 * It stores the handler function in a separate cache object
22482 * and adds a generic handler to the element's event,
22483 * along with a unique id (guid) to the element.
22485 * @param {Element|Object} elem
22486 * Element or object to bind listeners to
22488 * @param {string|string[]} type
22489 * Type of event to bind to.
22491 * @param {EventTarget~EventListener} fn
22494 function on(elem, type, fn) {
22495 if (Array.isArray(type)) {
22496 return _handleMultipleEvents(on, elem, type, fn);
22499 var data = Dom.getElData(elem);
22501 // We need a place to store all our handler data
22502 if (!data.handlers) {
22503 data.handlers = {};
22506 if (!data.handlers[type]) {
22507 data.handlers[type] = [];
22511 fn.guid = Guid.newGUID();
22514 data.handlers[type].push(fn);
22516 if (!data.dispatcher) {
22517 data.disabled = false;
22519 data.dispatcher = function (event, hash) {
22521 if (data.disabled) {
22525 event = fixEvent(event);
22527 var handlers = data.handlers[event.type];
22530 // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.
22531 var handlersCopy = handlers.slice(0);
22533 for (var m = 0, n = handlersCopy.length; m < n; m++) {
22534 if (event.isImmediatePropagationStopped()) {
22538 handlersCopy[m].call(elem, event, hash);
22540 _log2['default'].error(e);
22548 if (data.handlers[type].length === 1) {
22549 if (elem.addEventListener) {
22550 elem.addEventListener(type, data.dispatcher, false);
22551 } else if (elem.attachEvent) {
22552 elem.attachEvent('on' + type, data.dispatcher);
22558 * Removes event listeners from an element
22560 * @param {Element|Object} elem
22561 * Object to remove listeners from.
22563 * @param {string|string[]} [type]
22564 * Type of listener to remove. Don't include to remove all events from element.
22566 * @param {EventTarget~EventListener} [fn]
22567 * Specific listener to remove. Don't include to remove listeners for an event
22570 function off(elem, type, fn) {
22571 // Don't want to add a cache object through getElData if not needed
22572 if (!Dom.hasElData(elem)) {
22576 var data = Dom.getElData(elem);
22578 // If no events exist, nothing to unbind
22579 if (!data.handlers) {
22583 if (Array.isArray(type)) {
22584 return _handleMultipleEvents(off, elem, type, fn);
22587 // Utility function
22588 var removeType = function removeType(t) {
22589 data.handlers[t] = [];
22590 _cleanUpEvents(elem, t);
22593 // Are we removing all bound events?
22595 for (var t in data.handlers) {
22601 var handlers = data.handlers[type];
22603 // If no handlers exist, nothing to unbind
22608 // If no listener was provided, remove all listeners for type
22614 // We're only removing a single handler
22616 for (var n = 0; n < handlers.length; n++) {
22617 if (handlers[n].guid === fn.guid) {
22618 handlers.splice(n--, 1);
22623 _cleanUpEvents(elem, type);
22627 * Trigger an event for an element
22629 * @param {Element|Object} elem
22630 * Element to trigger an event on
22632 * @param {EventTarget~Event|string} event
22633 * A string (the type) or an event object with a type attribute
22635 * @param {Object} [hash]
22636 * data hash to pass along with the event
22638 * @return {boolean|undefined}
22639 * - Returns the opposite of `defaultPrevented` if default was prevented
22640 * - Otherwise returns undefined
22642 function trigger(elem, event, hash) {
22643 // Fetches element data and a reference to the parent (for bubbling).
22644 // Don't want to add a data object to cache for every parent,
22645 // so checking hasElData first.
22646 var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {};
22647 var parent = elem.parentNode || elem.ownerDocument;
22648 // type = event.type || event,
22651 // If an event name was passed as a string, creates an event out of it
22652 if (typeof event === 'string') {
22653 event = { type: event, target: elem };
22655 // Normalizes the event properties.
22656 event = fixEvent(event);
22658 // If the passed element has a dispatcher, executes the established handlers.
22659 if (elemData.dispatcher) {
22660 elemData.dispatcher.call(elem, event, hash);
22663 // Unless explicitly stopped or the event does not bubble (e.g. media events)
22664 // recursively calls this function to bubble the event up the DOM.
22665 if (parent && !event.isPropagationStopped() && event.bubbles === true) {
22666 trigger.call(null, parent, event, hash);
22668 // If at the top of the DOM, triggers the default action unless disabled.
22669 } else if (!parent && !event.defaultPrevented) {
22670 var targetData = Dom.getElData(event.target);
22672 // Checks if the target has a default action for this event.
22673 if (event.target[event.type]) {
22674 // Temporarily disables event dispatching on the target as we have already executed the handler.
22675 targetData.disabled = true;
22676 // Executes the default action.
22677 if (typeof event.target[event.type] === 'function') {
22678 event.target[event.type]();
22680 // Re-enables event dispatching.
22681 targetData.disabled = false;
22685 // Inform the triggerer if the default was prevented by returning false
22686 return !event.defaultPrevented;
22690 * Trigger a listener only once for an event
22692 * @param {Element|Object} elem
22693 * Element or object to bind to.
22695 * @param {string|string[]} type
22696 * Name/type of event
22698 * @param {Event~EventListener} fn
22699 * Event Listener function
22701 function one(elem, type, fn) {
22702 if (Array.isArray(type)) {
22703 return _handleMultipleEvents(one, elem, type, fn);
22705 var func = function func() {
22706 off(elem, type, func);
22707 fn.apply(this, arguments);
22710 // copy the guid to the new function so it can removed using the original function's ID
22711 func.guid = fn.guid = fn.guid || Guid.newGUID();
22712 on(elem, type, func);
22715 },{"81":81,"85":85,"86":86,"94":94,"95":95}],83:[function(_dereq_,module,exports){
22718 exports.__esModule = true;
22719 exports.throttle = exports.bind = undefined;
22721 var _guid = _dereq_(85);
22724 * Bind (a.k.a proxy or Context). A simple method for changing the context of a function
22725 * It also stores a unique id on the function so it can be easily removed from events.
22727 * @param {Mixed} context
22728 * The object to bind as scope.
22730 * @param {Function} fn
22731 * The function to be bound to a scope.
22733 * @param {number} [uid]
22734 * An optional unique ID for the function to be set
22736 * @return {Function}
22737 * The new function that will be bound into the context given
22739 var bind = exports.bind = function bind(context, fn, uid) {
22740 // Make sure the function has a unique ID
22742 fn.guid = (0, _guid.newGUID)();
22745 // Create the new function that changes the context
22746 var bound = function bound() {
22747 return fn.apply(context, arguments);
22750 // Allow for the ability to individualize this function
22751 // Needed in the case where multiple objects might share the same prototype
22752 // IF both items add an event listener with the same function, then you try to remove just one
22753 // it will remove both because they both have the same guid.
22754 // when using this, you need to use the bind method when you remove the listener as well.
22755 // currently used in text tracks
22756 bound.guid = uid ? uid + '_' + fn.guid : fn.guid;
22762 * Wraps the given function, `fn`, with a new function that only invokes `fn`
22763 * at most once per every `wait` milliseconds.
22765 * @param {Function} fn
22766 * The function to be throttled.
22768 * @param {Number} wait
22769 * The number of milliseconds by which to throttle.
22771 * @return {Function}
22777 var throttle = exports.throttle = function throttle(fn, wait) {
22778 var last = Date.now();
22780 var throttled = function throttled() {
22781 var now = Date.now();
22783 if (now - last >= wait) {
22784 fn.apply(undefined, arguments);
22792 },{"85":85}],84:[function(_dereq_,module,exports){
22795 exports.__esModule = true;
22797 * @file format-time.js
22798 * @module Format-time
22802 * Format seconds as a time string, H:MM:SS or M:SS. Supplying a guide (in seconds)
22803 * will force a number of leading zeros to cover the length of the guide.
22805 * @param {number} seconds
22806 * Number of seconds to be turned into a string
22808 * @param {number} guide
22809 * Number (in seconds) to model the string after
22812 * Time formatted as H:MM:SS or M:SS
22814 function formatTime(seconds) {
22815 var guide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : seconds;
22817 seconds = seconds < 0 ? 0 : seconds;
22818 var s = Math.floor(seconds % 60);
22819 var m = Math.floor(seconds / 60 % 60);
22820 var h = Math.floor(seconds / 3600);
22821 var gm = Math.floor(guide / 60 % 60);
22822 var gh = Math.floor(guide / 3600);
22824 // handle invalid times
22825 if (isNaN(seconds) || seconds === Infinity) {
22826 // '-' is false for all relational operators (e.g. <, >=) so this setting
22827 // will add the minimum number of fields specified by the guide
22831 // Check if we need to show hours
22832 h = h > 0 || gh > 0 ? h + ':' : '';
22834 // If hours are showing, we may need to add a leading zero.
22835 // Always show at least one digit of minutes.
22836 m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':';
22838 // Check if leading zero is need for seconds
22839 s = s < 10 ? '0' + s : s;
22844 exports['default'] = formatTime;
22846 },{}],85:[function(_dereq_,module,exports){
22849 exports.__esModule = true;
22850 exports.newGUID = newGUID;
22857 * Unique ID for an element or function
22863 * Get a unique auto-incrementing ID by number that has not been returned before.
22868 function newGUID() {
22872 },{}],86:[function(_dereq_,module,exports){
22875 exports.__esModule = true;
22876 exports.logByType = undefined;
22878 var _window = _dereq_(95);
22880 var _window2 = _interopRequireDefault(_window);
22882 var _browser = _dereq_(78);
22884 var _obj = _dereq_(88);
22886 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
22891 * Log messages to the console and history based on the type of message
22893 * @param {string} type
22894 * The name of the console method to use.
22896 * @param {Array} args
22897 * The arguments to be passed to the matching console method.
22899 * @param {boolean} [stringify]
22900 * By default, only old IEs should get console argument stringification,
22901 * but this is exposed as a parameter to facilitate testing.
22907 var logByType = exports.logByType = function logByType(type, args) {
22908 var stringify = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : !!_browser.IE_VERSION && _browser.IE_VERSION < 11;
22911 if (type !== 'log') {
22913 // add the type to the front of the message when it's not "log"
22914 args.unshift(type.toUpperCase() + ':');
22918 log.history.push(args);
22920 // add console prefix after adding to history
22921 args.unshift('VIDEOJS:');
22923 // If there's no console then don't try to output messages, but they will
22924 // still be stored in `log.history`.
22926 // Was setting these once outside of this function, but containing them
22927 // in the function makes it easier to test cases where console doesn't exist
22928 // when the module is executed.
22929 var fn = _window2['default'].console && _window2['default'].console[type];
22931 // Bail out if there's no console.
22936 // IEs previous to 11 log objects uselessly as "[object Object]"; so, JSONify
22937 // objects and arrays for those less-capable browsers.
22939 args = args.map(function (a) {
22940 if ((0, _obj.isObject)(a) || Array.isArray(a)) {
22942 return JSON.stringify(a);
22948 // Cast to string before joining, so we get null and undefined explicitly
22949 // included in output (as we would in a modern console).
22954 // Old IE versions do not allow .apply() for console methods (they are
22955 // reported as objects rather than functions).
22959 fn[Array.isArray(args) ? 'apply' : 'call'](_window2['default'].console, args);
22964 * Log plain debug messages
22966 * @param {Mixed[]} args
22967 * One or more messages or objects that should be logged.
22969 log = function log() {
22970 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
22971 args[_key] = arguments[_key];
22974 logByType('log', args);
22978 * Keep a history of log messages
22985 * Log error messages
22987 * @param {Mixed[]} args
22988 * One or more messages or objects that should be logged as an error
22990 log.error = function () {
22991 for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
22992 args[_key2] = arguments[_key2];
22995 return logByType('error', args);
22999 * Log warning messages
23001 * @param {Mixed[]} args
23002 * One or more messages or objects that should be logged as a warning.
23004 log.warn = function () {
23005 for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
23006 args[_key3] = arguments[_key3];
23009 return logByType('warn', args);
23012 exports['default'] = log;
23014 },{"78":78,"88":88,"95":95}],87:[function(_dereq_,module,exports){
23017 exports.__esModule = true;
23018 exports['default'] = mergeOptions;
23020 var _obj = _dereq_(88);
23023 * Deep-merge one or more options objects, recursively merging **only** plain
23024 * object properties.
23026 * @param {Object[]} sources
23027 * One or more objects to merge into a new object.
23029 * @returns {Object}
23030 * A new object that is the merged result of all sources.
23032 function mergeOptions() {
23035 for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {
23036 sources[_key] = arguments[_key];
23039 sources.forEach(function (source) {
23044 (0, _obj.each)(source, function (value, key) {
23045 if (!(0, _obj.isPlain)(value)) {
23046 result[key] = value;
23050 if (!(0, _obj.isPlain)(result[key])) {
23054 result[key] = mergeOptions(result[key], value);
23060 * @file merge-options.js
23061 * @module merge-options
23064 },{"88":88}],88:[function(_dereq_,module,exports){
23067 exports.__esModule = true;
23069 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
23071 exports.each = each;
23072 exports.reduce = reduce;
23073 exports.assign = assign;
23074 exports.isObject = isObject;
23075 exports.isPlain = isPlain;
23082 * @callback obj:EachCallback
23084 * @param {Mixed} value
23085 * The current key for the object that is being iterated over.
23087 * @param {string} key
23088 * The current key-value for object that is being iterated over
23092 * @callback obj:ReduceCallback
23094 * @param {Mixed} accum
23095 * The value that is accumulating over the reduce loop.
23097 * @param {Mixed} value
23098 * The current key for the object that is being iterated over.
23100 * @param {string} key
23101 * The current key-value for object that is being iterated over
23104 * The new accumulated value.
23106 var toString = Object.prototype.toString;
23109 * Get the keys of an Object
23112 * The Object to get the keys from
23114 * @return {string[]}
23115 * An array of the keys from the object. Returns an empty array if the
23116 * object passed in was invalid or had no keys.
23120 var keys = function keys(object) {
23121 return isObject(object) ? Object.keys(object) : [];
23125 * Array-like iteration for objects.
23127 * @param {Object} object
23128 * The object to iterate over
23130 * @param {obj:EachCallback} fn
23131 * The callback function which is called for each key in the object.
23133 function each(object, fn) {
23134 keys(object).forEach(function (key) {
23135 return fn(object[key], key);
23140 * Array-like reduce for objects.
23142 * @param {Object} object
23143 * The Object that you want to reduce.
23145 * @param {Function} fn
23146 * A callback function which is called for each key in the object. It
23147 * receives the accumulated value and the per-iteration value and key
23150 * @param {Mixed} [initial = 0]
23154 * The final accumulated value.
23156 function reduce(object, fn) {
23157 var initial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
23159 return keys(object).reduce(function (accum, key) {
23160 return fn(accum, object[key], key);
23165 * Object.assign-style object shallow merge/extend.
23167 * @param {Object} target
23168 * @param {Object} ...sources
23171 function assign(target) {
23172 for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
23173 sources[_key - 1] = arguments[_key];
23176 if (Object.assign) {
23177 return Object.assign.apply(Object, [target].concat(sources));
23180 sources.forEach(function (source) {
23185 each(source, function (value, key) {
23186 target[key] = value;
23194 * Returns whether a value is an object of any kind - including DOM nodes,
23195 * arrays, regular expressions, etc. Not functions, though.
23197 * This avoids the gotcha where using `typeof` on a `null` value
23198 * results in `'object'`.
23200 * @param {Object} value
23201 * @return {Boolean}
23203 function isObject(value) {
23204 return !!value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object';
23208 * Returns whether an object appears to be a "plain" object - that is, a
23209 * direct instance of `Object`.
23211 * @param {Object} value
23212 * @return {Boolean}
23214 function isPlain(value) {
23215 return isObject(value) && toString.call(value) === '[object Object]' && value.constructor === Object;
23218 },{}],89:[function(_dereq_,module,exports){
23221 exports.__esModule = true;
23222 exports.setTextContent = exports.createStyleElement = undefined;
23224 var _document = _dereq_(94);
23226 var _document2 = _interopRequireDefault(_document);
23228 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23231 * Create a DOM syle element given a className for it.
23233 * @param {string} className
23234 * The className to add to the created style element.
23236 * @return {Element}
23237 * The element that was created.
23239 var createStyleElement = exports.createStyleElement = function createStyleElement(className) {
23240 var style = _document2['default'].createElement('style');
23242 style.className = className;
23248 * Add text to a DOM element.
23250 * @param {Element} el
23251 * The Element to add text content to.
23253 * @param {string} content
23254 * The text to add to the element.
23257 * @file stylesheet.js
23258 * @module stylesheet
23260 var setTextContent = exports.setTextContent = function setTextContent(el, content) {
23261 if (el.styleSheet) {
23262 el.styleSheet.cssText = content;
23264 el.textContent = content;
23268 },{"94":94}],90:[function(_dereq_,module,exports){
23271 exports.__esModule = true;
23272 exports.createTimeRange = undefined;
23273 exports.createTimeRanges = createTimeRanges;
23275 var _log = _dereq_(86);
23277 var _log2 = _interopRequireDefault(_log);
23279 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23282 * Returns the time for the specified index at the start or end
23283 * of a TimeRange object.
23285 * @function time-ranges:indexFunction
23287 * @param {number} [index=0]
23288 * The range number to return the time for.
23291 * The time that offset at the specified index.
23293 * @depricated index must be set to a value, in the future this will throw an error.
23297 * An object that contains ranges of time for various reasons.
23299 * @typedef {Object} TimeRange
23301 * @property {number} length
23302 * The number of time ranges represented by this Object
23304 * @property {time-ranges:indexFunction} start
23305 * Returns the time offset at which a specified time range begins.
23307 * @property {time-ranges:indexFunction} end
23308 * Returns the time offset at which a specified time range begins.
23310 * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges
23314 * Check if any of the time ranges are over the maximum index.
23316 * @param {string} fnName
23317 * The function name to use for logging
23319 * @param {number} index
23320 * The index to check
23322 * @param {number} maxIndex
23323 * The maximum possible index
23325 * @throws {Error} if the timeRanges provided are over the maxIndex
23327 function rangeCheck(fnName, index, maxIndex) {
23328 if (index < 0 || index > maxIndex) {
23329 throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is greater than or equal to the maximum bound (' + maxIndex + ').');
23334 * Check if any of the time ranges are over the maximum index.
23336 * @param {string} fnName
23337 * The function name to use for logging
23339 * @param {string} valueIndex
23340 * The proprety that should be used to get the time. should be 'start' or 'end'
23342 * @param {Array} ranges
23343 * An array of time ranges
23345 * @param {Array} [rangeIndex=0]
23346 * The index to start the search at
23349 * The time that offset at the specified index.
23352 * @depricated rangeIndex must be set to a value, in the future this will throw an error.
23353 * @throws {Error} if rangeIndex is more than the length of ranges
23356 * @file time-ranges.js
23357 * @module time-ranges
23359 function getRange(fnName, valueIndex, ranges, rangeIndex) {
23360 if (rangeIndex === undefined) {
23361 _log2['default'].warn('DEPRECATED: Function \'' + fnName + '\' on \'TimeRanges\' called without an index argument.');
23364 rangeCheck(fnName, rangeIndex, ranges.length - 1);
23365 return ranges[rangeIndex][valueIndex];
23369 * Create a time range object givent ranges of time.
23371 * @param {Array} [ranges]
23372 * An array of time ranges.
23374 function createTimeRangesObj(ranges) {
23375 if (ranges === undefined || ranges.length === 0) {
23378 start: function start() {
23379 throw new Error('This TimeRanges object is empty');
23381 end: function end() {
23382 throw new Error('This TimeRanges object is empty');
23387 length: ranges.length,
23388 start: getRange.bind(null, 'start', 0, ranges),
23389 end: getRange.bind(null, 'end', 1, ranges)
23394 * Should create a fake `TimeRange` object which mimics an HTML5 time range instance.
23396 * @param {number|Array} start
23397 * The start of a single range or an array of ranges
23399 * @param {number} end
23400 * The end of a single range.
23404 function createTimeRanges(start, end) {
23405 if (Array.isArray(start)) {
23406 return createTimeRangesObj(start);
23407 } else if (start === undefined || end === undefined) {
23408 return createTimeRangesObj();
23410 return createTimeRangesObj([[start, end]]);
23413 exports.createTimeRange = createTimeRanges;
23415 },{"86":86}],91:[function(_dereq_,module,exports){
23418 exports.__esModule = true;
23420 * @file to-title-case.js
23421 * @module to-title-case
23425 * Uppercase the first letter of a string.
23427 * @param {string} string
23428 * String to be uppercased
23431 * The string with an uppercased first letter
23433 function toTitleCase(string) {
23434 if (typeof string !== 'string') {
23438 return string.charAt(0).toUpperCase() + string.slice(1);
23441 exports['default'] = toTitleCase;
23443 },{}],92:[function(_dereq_,module,exports){
23446 exports.__esModule = true;
23447 exports.isCrossOrigin = exports.getFileExtension = exports.getAbsoluteURL = exports.parseUrl = undefined;
23449 var _document = _dereq_(94);
23451 var _document2 = _interopRequireDefault(_document);
23453 var _window = _dereq_(95);
23455 var _window2 = _interopRequireDefault(_window);
23457 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23460 * @typedef {Object} url:URLObject
23462 * @property {string} protocol
23463 * The protocol of the url that was parsed.
23465 * @property {string} hostname
23466 * The hostname of the url that was parsed.
23468 * @property {string} port
23469 * The port of the url that was parsed.
23471 * @property {string} pathname
23472 * The pathname of the url that was parsed.
23474 * @property {string} search
23475 * The search query of the url that was parsed.
23477 * @property {string} hash
23478 * The hash of the url that was parsed.
23480 * @property {string} host
23481 * The host of the url that was parsed.
23485 * Resolve and parse the elements of a URL.
23487 * @param {String} url
23490 * @return {url:URLObject}
23491 * An object of url details
23497 var parseUrl = exports.parseUrl = function parseUrl(url) {
23498 var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host'];
23500 // add the url to an anchor and let the browser parse the URL
23501 var a = _document2['default'].createElement('a');
23505 // IE8 (and 9?) Fix
23506 // ie8 doesn't parse the URL correctly until the anchor is actually
23507 // added to the body, and an innerHTML is needed to trigger the parsing
23508 var addToBody = a.host === '' && a.protocol !== 'file:';
23512 div = _document2['default'].createElement('div');
23513 div.innerHTML = '<a href="' + url + '"></a>';
23514 a = div.firstChild;
23515 // prevent the div from affecting layout
23516 div.setAttribute('style', 'display:none; position:absolute;');
23517 _document2['default'].body.appendChild(div);
23520 // Copy the specific URL properties to a new object
23521 // This is also needed for IE8 because the anchor loses its
23522 // properties when it's removed from the dom
23525 for (var i = 0; i < props.length; i++) {
23526 details[props[i]] = a[props[i]];
23529 // IE9 adds the port to the host property unlike everyone else. If
23530 // a port identifier is added for standard ports, strip it.
23531 if (details.protocol === 'http:') {
23532 details.host = details.host.replace(/:80$/, '');
23535 if (details.protocol === 'https:') {
23536 details.host = details.host.replace(/:443$/, '');
23540 _document2['default'].body.removeChild(div);
23547 * Get absolute version of relative URL. Used to tell flash correct URL.
23550 * @param {string} url
23551 * URL to make absolute
23556 * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
23558 var getAbsoluteURL = exports.getAbsoluteURL = function getAbsoluteURL(url) {
23559 // Check if absolute URL
23560 if (!url.match(/^https?:\/\//)) {
23561 // Convert to absolute URL. Flash hosted off-site needs an absolute URL.
23562 var div = _document2['default'].createElement('div');
23564 div.innerHTML = '<a href="' + url + '">x</a>';
23565 url = div.firstChild.href;
23572 * Returns the extension of the passed file name. It will return an empty string
23573 * if passed an invalid path.
23575 * @param {string} path
23576 * The fileName path like '/path/to/file.mp4'
23578 * @returns {string}
23579 * The extension in lower case or an empty string if no
23580 * extension could be found.
23582 var getFileExtension = exports.getFileExtension = function getFileExtension(path) {
23583 if (typeof path === 'string') {
23584 var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i;
23585 var pathParts = splitPathRe.exec(path);
23588 return pathParts.pop().toLowerCase();
23596 * Returns whether the url passed is a cross domain request or not.
23598 * @param {string} url
23599 * The url to check.
23601 * @return {boolean}
23602 * Whether it is a cross domain request or not.
23604 var isCrossOrigin = exports.isCrossOrigin = function isCrossOrigin(url) {
23605 var winLoc = _window2['default'].location;
23606 var urlInfo = parseUrl(url);
23608 // IE8 protocol relative urls will return ':' for protocol
23609 var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol;
23611 // Check if url is for another domain/origin
23612 // IE8 doesn't know location.origin, so we won't rely on it here
23613 var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host;
23615 return crossOrigin;
23618 },{"94":94,"95":95}],93:[function(_dereq_,module,exports){
23621 exports.__esModule = true;
23623 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /**
23628 /* global define */
23630 // Include the built-in techs
23633 var _window = _dereq_(95);
23635 var _window2 = _interopRequireDefault(_window);
23637 var _document = _dereq_(94);
23639 var _document2 = _interopRequireDefault(_document);
23641 var _setup = _dereq_(56);
23643 var setup = _interopRequireWildcard(_setup);
23645 var _stylesheet = _dereq_(89);
23647 var stylesheet = _interopRequireWildcard(_stylesheet);
23649 var _component = _dereq_(5);
23651 var _component2 = _interopRequireDefault(_component);
23653 var _eventTarget = _dereq_(42);
23655 var _eventTarget2 = _interopRequireDefault(_eventTarget);
23657 var _events = _dereq_(82);
23659 var Events = _interopRequireWildcard(_events);
23661 var _player = _dereq_(51);
23663 var _player2 = _interopRequireDefault(_player);
23665 var _plugins = _dereq_(52);
23667 var _plugins2 = _interopRequireDefault(_plugins);
23669 var _mergeOptions2 = _dereq_(87);
23671 var _mergeOptions3 = _interopRequireDefault(_mergeOptions2);
23673 var _fn = _dereq_(83);
23675 var Fn = _interopRequireWildcard(_fn);
23677 var _textTrack = _dereq_(72);
23679 var _textTrack2 = _interopRequireDefault(_textTrack);
23681 var _audioTrack = _dereq_(64);
23683 var _audioTrack2 = _interopRequireDefault(_audioTrack);
23685 var _videoTrack = _dereq_(77);
23687 var _videoTrack2 = _interopRequireDefault(_videoTrack);
23689 var _timeRanges = _dereq_(90);
23691 var _formatTime = _dereq_(84);
23693 var _formatTime2 = _interopRequireDefault(_formatTime);
23695 var _log = _dereq_(86);
23697 var _log2 = _interopRequireDefault(_log);
23699 var _dom = _dereq_(81);
23701 var Dom = _interopRequireWildcard(_dom);
23703 var _browser = _dereq_(78);
23705 var browser = _interopRequireWildcard(_browser);
23707 var _url = _dereq_(92);
23709 var Url = _interopRequireWildcard(_url);
23711 var _obj = _dereq_(88);
23713 var _computedStyle = _dereq_(80);
23715 var _computedStyle2 = _interopRequireDefault(_computedStyle);
23717 var _extend = _dereq_(43);
23719 var _extend2 = _interopRequireDefault(_extend);
23721 var _xhr = _dereq_(99);
23723 var _xhr2 = _interopRequireDefault(_xhr);
23725 var _tech = _dereq_(62);
23727 var _tech2 = _interopRequireDefault(_tech);
23729 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
23731 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23733 // HTML5 Element Shim for IE8
23734 if (typeof HTMLVideoElement === 'undefined' && Dom.isReal()) {
23735 _document2['default'].createElement('video');
23736 _document2['default'].createElement('audio');
23737 _document2['default'].createElement('track');
23741 * Doubles as the main function for users to create a player instance and also
23742 * the main library object.
23743 * The `videojs` function can be used to initialize or retrieve a player.
23745 * @param {string|Element} id
23746 * Video element or video element ID
23748 * @param {Object} [options]
23749 * Optional options object for config/settings
23751 * @param {Component~ReadyCallback} [ready]
23752 * Optional ready callback
23755 * A player instance
23759 function videojs(id, options, ready) {
23762 // Allow for element or ID to be passed in
23764 if (typeof id === 'string') {
23766 // Adjust for jQuery ID syntax
23767 if (id.indexOf('#') === 0) {
23771 // If a player instance has already been created for this ID return it.
23772 if (videojs.getPlayers()[id]) {
23774 // If options or ready funtion are passed, warn
23776 _log2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.');
23780 videojs.getPlayers()[id].ready(ready);
23783 return videojs.getPlayers()[id];
23786 // Otherwise get element for ID
23787 tag = Dom.getEl(id);
23789 // ID is a media element
23794 // Check for a useable element
23795 // re: nodeName, could be a box div also
23796 if (!tag || !tag.nodeName) {
23797 throw new TypeError('The element or ID supplied is not valid. (videojs)');
23800 // Element may have a player attr referring to an already created player instance.
23801 // If so return that otherwise set up a new player below
23802 if (tag.player || _player2['default'].players[tag.playerId]) {
23803 return tag.player || _player2['default'].players[tag.playerId];
23806 options = options || {};
23808 videojs.hooks('beforesetup').forEach(function (hookFunction) {
23809 var opts = hookFunction(tag, (0, _mergeOptions3['default'])(options));
23811 if (!(0, _obj.isObject)(opts) || Array.isArray(opts)) {
23812 _log2['default'].error('please return an object in beforesetup hooks');
23816 options = (0, _mergeOptions3['default'])(options, opts);
23819 var PlayerComponent = _component2['default'].getComponent('Player');
23820 // If not, set up a new player
23821 var player = new PlayerComponent(tag, options, ready);
23823 videojs.hooks('setup').forEach(function (hookFunction) {
23824 return hookFunction(player);
23831 * An Object that contains lifecycle hooks as keys which point to an array
23832 * of functions that are run when a lifecycle is triggered
23834 videojs.hooks_ = {};
23837 * Get a list of hooks for a specific lifecycle
23839 * @param {string} type
23840 * the lifecyle to get hooks from
23842 * @param {Function} [fn]
23843 * Optionally add a hook to the lifecycle that your are getting.
23846 * an array of hooks, or an empty array if there are none.
23848 videojs.hooks = function (type, fn) {
23849 videojs.hooks_[type] = videojs.hooks_[type] || [];
23851 videojs.hooks_[type] = videojs.hooks_[type].concat(fn);
23853 return videojs.hooks_[type];
23857 * Add a function hook to a specific videojs lifecycle.
23859 * @param {string} type
23860 * the lifecycle to hook the function to.
23862 * @param {Function|Function[]}
23863 * The function or array of functions to attach.
23865 videojs.hook = function (type, fn) {
23866 videojs.hooks(type, fn);
23870 * Remove a hook from a specific videojs lifecycle.
23872 * @param {string} type
23873 * the lifecycle that the function hooked to
23875 * @param {Function} fn
23876 * The hooked function to remove
23878 * @return {boolean}
23879 * The function that was removed or undef
23881 videojs.removeHook = function (type, fn) {
23882 var index = videojs.hooks(type).indexOf(fn);
23888 videojs.hooks_[type] = videojs.hooks_[type].slice();
23889 videojs.hooks_[type].splice(index, 1);
23894 // Add default styles
23895 if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true && Dom.isReal()) {
23896 var style = Dom.$('.vjs-styles-defaults');
23899 style = stylesheet.createStyleElement('vjs-styles-defaults');
23900 var head = Dom.$('head');
23903 head.insertBefore(style, head.firstChild);
23905 stylesheet.setTextContent(style, '\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n ');
23909 // Run Auto-load players
23910 // You have to wait at least once in case this script is loaded after your
23911 // video in the DOM (weird behavior only with minified version)
23912 setup.autoSetupTimeout(1, videojs);
23915 * Current software version. Follows semver.
23919 videojs.VERSION = '5.19.2';
23922 * The global options object. These are the settings that take effect
23923 * if no overrides are specified when the player is created.
23927 videojs.options = _player2['default'].prototype.options_;
23930 * Get an object with the currently created players, keyed by player ID
23933 * The created players
23935 videojs.getPlayers = function () {
23936 return _player2['default'].players;
23940 * Expose players object.
23942 * @memberOf videojs
23943 * @property {Object} players
23945 videojs.players = _player2['default'].players;
23948 * Get a component class object by name
23950 * @borrows Component.getComponent as videojs.getComponent
23952 videojs.getComponent = _component2['default'].getComponent;
23955 * Register a component so it can referred to by name. Used when adding to other
23956 * components, either through addChild `component.addChild('myComponent')` or through
23957 * default children options `{ children: ['myComponent'] }`.
23959 * > NOTE: You could also just initialize the component before adding.
23960 * `component.addChild(new MyComponent());`
23962 * @param {string} name
23963 * The class name of the component
23965 * @param {Component} comp
23966 * The component class
23968 * @return {Component}
23969 * The newly registered component
23971 videojs.registerComponent = function (name, comp) {
23972 if (_tech2['default'].isTech(comp)) {
23973 _log2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)');
23976 _component2['default'].registerComponent.call(_component2['default'], name, comp);
23980 * Get a Tech class object by name
23982 * @borrows Tech.getTech as videojs.getTech
23984 videojs.getTech = _tech2['default'].getTech;
23987 * Register a Tech so it can referred to by name.
23988 * This is used in the tech order for the player.
23990 * @borrows Tech.registerTech as videojs.registerTech
23992 videojs.registerTech = _tech2['default'].registerTech;
23995 * A suite of browser and device tests from {@link browser}.
24000 videojs.browser = browser;
24003 * Whether or not the browser supports touch events. Included for backward
24004 * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED`
24005 * instead going forward.
24007 * @deprecated since version 5.0
24010 videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED;
24013 * Subclass an existing class
24014 * Mimics ES6 subclassing with the `extend` keyword
24016 * @borrows extend:extendFn as videojs.extend
24018 videojs.extend = _extend2['default'];
24021 * Merge two options objects recursively
24022 * Performs a deep merge like lodash.merge but **only merges plain objects**
24023 * (not arrays, elements, anything else)
24024 * Other values will be copied directly from the second object.
24026 * @borrows merge-options:mergeOptions as videojs.mergeOptions
24028 videojs.mergeOptions = _mergeOptions3['default'];
24031 * Change the context (this) of a function
24033 * > NOTE: as of v5.0 we require an ES5 shim, so you should use the native
24034 * `function() {}.bind(newContext);` instead of this.
24036 * @borrows fn:bind as videojs.bind
24038 videojs.bind = Fn.bind;
24041 * Create a Video.js player plugin.
24042 * Plugins are only initialized when options for the plugin are included
24043 * in the player options, or the plugin function on the player instance is
24046 * @borrows plugin:plugin as videojs.plugin
24048 videojs.plugin = _plugins2['default'];
24051 * Adding languages so that they're available to all players.
24052 * Example: `videojs.addLanguage('es', { 'Hello': 'Hola' });`
24054 * @param {string} code
24055 * The language code or dictionary property
24057 * @param {Object} data
24058 * The data values to be translated
24061 * The resulting language dictionary object
24063 videojs.addLanguage = function (code, data) {
24066 code = ('' + code).toLowerCase();
24068 videojs.options.languages = (0, _mergeOptions3['default'])(videojs.options.languages, (_mergeOptions = {}, _mergeOptions[code] = data, _mergeOptions));
24070 return videojs.options.languages[code];
24076 * @borrows log:log as videojs.log
24078 videojs.log = _log2['default'];
24081 * Creates an emulated TimeRange object.
24083 * @borrows time-ranges:createTimeRanges as videojs.createTimeRange
24086 * @borrows time-ranges:createTimeRanges as videojs.createTimeRanges
24088 videojs.createTimeRange = videojs.createTimeRanges = _timeRanges.createTimeRanges;
24091 * Format seconds as a time string, H:MM:SS or M:SS
24092 * Supplying a guide (in seconds) will force a number of leading zeros
24093 * to cover the length of the guide
24095 * @borrows format-time:formatTime as videojs.formatTime
24097 videojs.formatTime = _formatTime2['default'];
24100 * Resolve and parse the elements of a URL
24102 * @borrows url:parseUrl as videojs.parseUrl
24104 videojs.parseUrl = Url.parseUrl;
24107 * Returns whether the url passed is a cross domain request or not.
24109 * @borrows url:isCrossOrigin as videojs.isCrossOrigin
24111 videojs.isCrossOrigin = Url.isCrossOrigin;
24114 * Event target class.
24116 * @borrows EventTarget as videojs.EventTarget
24118 videojs.EventTarget = _eventTarget2['default'];
24121 * Add an event listener to element
24122 * It stores the handler function in a separate cache object
24123 * and adds a generic handler to the element's event,
24124 * along with a unique id (guid) to the element.
24126 * @borrows events:on as videojs.on
24128 videojs.on = Events.on;
24131 * Trigger a listener only once for an event
24133 * @borrows events:one as videojs.one
24135 videojs.one = Events.one;
24138 * Removes event listeners from an element
24140 * @borrows events:off as videojs.off
24142 videojs.off = Events.off;
24145 * Trigger an event for an element
24147 * @borrows events:trigger as videojs.trigger
24149 videojs.trigger = Events.trigger;
24152 * A cross-browser XMLHttpRequest wrapper. Here's a simple example:
24154 * @param {Object} options
24155 * settings for the request.
24157 * @return {XMLHttpRequest|XDomainRequest}
24158 * The request object.
24160 * @see https://github.com/Raynos/xhr
24162 videojs.xhr = _xhr2['default'];
24167 * @borrows TextTrack as videojs.TextTrack
24169 videojs.TextTrack = _textTrack2['default'];
24172 * export the AudioTrack class so that source handlers can create
24173 * AudioTracks and then add them to the players AudioTrackList
24175 * @borrows AudioTrack as videojs.AudioTrack
24177 videojs.AudioTrack = _audioTrack2['default'];
24180 * export the VideoTrack class so that source handlers can create
24181 * VideoTracks and then add them to the players VideoTrackList
24183 * @borrows VideoTrack as videojs.VideoTrack
24185 videojs.VideoTrack = _videoTrack2['default'];
24188 * Determines, via duck typing, whether or not a value is a DOM element.
24190 * @borrows dom:isEl as videojs.isEl
24192 videojs.isEl = Dom.isEl;
24195 * Determines, via duck typing, whether or not a value is a text node.
24197 * @borrows dom:isTextNode as videojs.isTextNode
24199 videojs.isTextNode = Dom.isTextNode;
24202 * Creates an element and applies properties.
24204 * @borrows dom:createEl as videojs.createEl
24206 videojs.createEl = Dom.createEl;
24209 * Check if an element has a CSS class
24211 * @borrows dom:hasElClass as videojs.hasClass
24213 videojs.hasClass = Dom.hasElClass;
24216 * Add a CSS class name to an element
24218 * @borrows dom:addElClass as videojs.addClass
24220 videojs.addClass = Dom.addElClass;
24223 * Remove a CSS class name from an element
24225 * @borrows dom:removeElClass as videojs.removeClass
24227 videojs.removeClass = Dom.removeElClass;
24230 * Adds or removes a CSS class name on an element depending on an optional
24231 * condition or the presence/absence of the class name.
24233 * @borrows dom:toggleElClass as videojs.toggleClass
24235 videojs.toggleClass = Dom.toggleElClass;
24238 * Apply attributes to an HTML element.
24240 * @borrows dom:setElAttributes as videojs.setAttribute
24242 videojs.setAttributes = Dom.setElAttributes;
24245 * Get an element's attribute values, as defined on the HTML tag
24246 * Attributes are not the same as properties. They're defined on the tag
24247 * or with setAttribute (which shouldn't be used with HTML)
24248 * This will return true or false for boolean attributes.
24250 * @borrows dom:getElAttributes as videojs.getAttributes
24252 videojs.getAttributes = Dom.getElAttributes;
24255 * Empties the contents of an element.
24257 * @borrows dom:emptyEl as videojs.emptyEl
24259 videojs.emptyEl = Dom.emptyEl;
24262 * Normalizes and appends content to an element.
24264 * The content for an element can be passed in multiple types and
24265 * combinations, whose behavior is as follows:
24268 * Normalized into a text node.
24270 * - Element, TextNode
24274 * A one-dimensional array of strings, elements, nodes, or functions (which
24275 * return single strings, elements, or nodes).
24278 * If the sole argument, is expected to produce a string, element,
24281 * @borrows dom:appendContents as videojs.appendContet
24283 videojs.appendContent = Dom.appendContent;
24286 * Normalizes and inserts content into an element; this is identical to
24287 * `appendContent()`, except it empties the element first.
24289 * The content for an element can be passed in multiple types and
24290 * combinations, whose behavior is as follows:
24293 * Normalized into a text node.
24295 * - Element, TextNode
24299 * A one-dimensional array of strings, elements, nodes, or functions (which
24300 * return single strings, elements, or nodes).
24303 * If the sole argument, is expected to produce a string, element,
24306 * @borrows dom:insertContent as videojs.insertContent
24308 videojs.insertContent = Dom.insertContent;
24311 * A safe getComputedStyle with an IE8 fallback.
24313 * This is because in Firefox, if the player is loaded in an iframe with `display:none`,
24314 * then `getComputedStyle` returns `null`, so, we do a null-check to make sure
24315 * that the player doesn't break in these cases.
24316 * See https://bugzilla.mozilla.org/show_bug.cgi?id=548397 for more details.
24318 * @borrows computed-style:computedStyle as videojs.computedStyle
24320 videojs.computedStyle = _computedStyle2['default'];
24323 * Custom Universal Module Definition (UMD)
24325 * Video.js will never be a non-browser lib so we can simplify UMD a bunch and
24326 * still support requirejs and browserify. This also needs to be closure
24327 * compiler compatible, so string keys are used.
24329 if (typeof define === 'function' && define.amd) {
24330 define('videojs', [], function () {
24334 // checking that module is an object too because of umdjs/umd#35
24335 } else if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && (typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') {
24336 module.exports = videojs;
24339 exports['default'] = videojs;
24341 },{"42":42,"43":43,"5":5,"51":51,"52":52,"56":56,"62":62,"64":64,"72":72,"77":77,"78":78,"80":80,"81":81,"82":82,"83":83,"84":84,"86":86,"87":87,"88":88,"89":89,"90":90,"92":92,"94":94,"95":95,"99":99}],94:[function(_dereq_,module,exports){
24342 (function (global){
24343 var topLevel = typeof global !== 'undefined' ? global :
24344 typeof window !== 'undefined' ? window : {}
24345 var minDoc = _dereq_(96);
24347 if (typeof document !== 'undefined') {
24348 module.exports = document;
24350 var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];
24353 doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;
24356 module.exports = doccy;
24359 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
24360 },{"96":96}],95:[function(_dereq_,module,exports){
24361 (function (global){
24362 if (typeof window !== "undefined") {
24363 module.exports = window;
24364 } else if (typeof global !== "undefined") {
24365 module.exports = global;
24366 } else if (typeof self !== "undefined"){
24367 module.exports = self;
24369 module.exports = {};
24372 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
24373 },{}],96:[function(_dereq_,module,exports){
24375 },{}],97:[function(_dereq_,module,exports){
24376 module.exports = SafeParseTuple
24378 function SafeParseTuple(obj, reviver) {
24383 json = JSON.parse(obj, reviver)
24388 return [error, json]
24391 },{}],98:[function(_dereq_,module,exports){
24392 function clean (s) {
24393 return s.replace(/\n\r?\s*/g, '')
24397 module.exports = function tsml (sa) {
24401 for (; i < arguments.length; i++)
24402 s += clean(sa[i]) + (arguments[i + 1] || '')
24406 },{}],99:[function(_dereq_,module,exports){
24408 var window = _dereq_(95)
24409 var isFunction = _dereq_(100)
24410 var parseHeaders = _dereq_(103)
24411 var xtend = _dereq_(104)
24413 module.exports = createXHR
24414 createXHR.XMLHttpRequest = window.XMLHttpRequest || noop
24415 createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest
24417 forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) {
24418 createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) {
24419 options = initParams(uri, options, callback)
24420 options.method = method.toUpperCase()
24421 return _createXHR(options)
24425 function forEachArray(array, iterator) {
24426 for (var i = 0; i < array.length; i++) {
24431 function isEmpty(obj){
24433 if(obj.hasOwnProperty(i)) return false
24438 function initParams(uri, options, callback) {
24441 if (isFunction(options)) {
24443 if (typeof uri === "string") {
24447 params = xtend(options, {uri: uri})
24450 params.callback = callback
24454 function createXHR(uri, options, callback) {
24455 options = initParams(uri, options, callback)
24456 return _createXHR(options)
24459 function _createXHR(options) {
24460 if(typeof options.callback === "undefined"){
24461 throw new Error("callback argument missing")
24465 var callback = function cbOnce(err, response, body){
24468 options.callback(err, response, body)
24472 function readystatechange() {
24473 if (xhr.readyState === 4) {
24474 setTimeout(loadFunc, 0)
24478 function getBody() {
24479 // Chrome with requestType=blob throws errors arround when even testing access to responseText
24480 var body = undefined
24482 if (xhr.response) {
24483 body = xhr.response
24485 body = xhr.responseText || getXml(xhr)
24490 body = JSON.parse(body)
24497 function errorFunc(evt) {
24498 clearTimeout(timeoutTimer)
24499 if(!(evt instanceof Error)){
24500 evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") )
24503 return callback(evt, failureResponse)
24506 // will load the data & process the response in a special response object
24507 function loadFunc() {
24508 if (aborted) return
24510 clearTimeout(timeoutTimer)
24511 if(options.useXDR && xhr.status===undefined) {
24512 //IE8 CORS GET successful response doesn't have a status field, but body is fine
24515 status = (xhr.status === 1223 ? 204 : xhr.status)
24517 var response = failureResponse
24523 statusCode: status,
24529 if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
24530 response.headers = parseHeaders(xhr.getAllResponseHeaders())
24533 err = new Error("Internal XMLHttpRequest Error")
24535 return callback(err, response, response.body)
24538 var xhr = options.xhr || null
24541 if (options.cors || options.useXDR) {
24542 xhr = new createXHR.XDomainRequest()
24544 xhr = new createXHR.XMLHttpRequest()
24550 var uri = xhr.url = options.uri || options.url
24551 var method = xhr.method = options.method || "GET"
24552 var body = options.body || options.data
24553 var headers = xhr.headers = options.headers || {}
24554 var sync = !!options.sync
24557 var failureResponse = {
24566 if ("json" in options && options.json !== false) {
24568 headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user
24569 if (method !== "GET" && method !== "HEAD") {
24570 headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user
24571 body = JSON.stringify(options.json === true ? body : options.json)
24575 xhr.onreadystatechange = readystatechange
24576 xhr.onload = loadFunc
24577 xhr.onerror = errorFunc
24578 // IE9 must have onprogress be set to a unique function.
24579 xhr.onprogress = function () {
24582 xhr.onabort = function(){
24585 xhr.ontimeout = errorFunc
24586 xhr.open(method, uri, !sync, options.username, options.password)
24587 //has to be after open
24589 xhr.withCredentials = !!options.withCredentials
24591 // Cannot set timeout with sync request
24592 // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly
24593 // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent
24594 if (!sync && options.timeout > 0 ) {
24595 timeoutTimer = setTimeout(function(){
24596 if (aborted) return
24597 aborted = true//IE9 may still call readystatechange
24598 xhr.abort("timeout")
24599 var e = new Error("XMLHttpRequest timeout")
24600 e.code = "ETIMEDOUT"
24602 }, options.timeout )
24605 if (xhr.setRequestHeader) {
24606 for(key in headers){
24607 if(headers.hasOwnProperty(key)){
24608 xhr.setRequestHeader(key, headers[key])
24611 } else if (options.headers && !isEmpty(options.headers)) {
24612 throw new Error("Headers cannot be set on an XDomainRequest object")
24615 if ("responseType" in options) {
24616 xhr.responseType = options.responseType
24619 if ("beforeSend" in options &&
24620 typeof options.beforeSend === "function"
24622 options.beforeSend(xhr)
24625 // Microsoft Edge browser sends "undefined" when send is called with undefined value.
24626 // XMLHttpRequest spec says to pass null as body to indicate no body
24627 // See https://github.com/naugtur/xhr/issues/100.
24628 xhr.send(body || null)
24635 function getXml(xhr) {
24636 if (xhr.responseType === "document") {
24637 return xhr.responseXML
24639 var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror"
24640 if (xhr.responseType === "" && !firefoxBugTakenEffect) {
24641 return xhr.responseXML
24649 },{"100":100,"103":103,"104":104,"95":95}],100:[function(_dereq_,module,exports){
24650 module.exports = isFunction
24652 var toString = Object.prototype.toString
24654 function isFunction (fn) {
24655 var string = toString.call(fn)
24656 return string === '[object Function]' ||
24657 (typeof fn === 'function' && string !== '[object RegExp]') ||
24658 (typeof window !== 'undefined' &&
24660 (fn === window.setTimeout ||
24661 fn === window.alert ||
24662 fn === window.confirm ||
24663 fn === window.prompt))
24666 },{}],101:[function(_dereq_,module,exports){
24667 var isFunction = _dereq_(100)
24669 module.exports = forEach
24671 var toString = Object.prototype.toString
24672 var hasOwnProperty = Object.prototype.hasOwnProperty
24674 function forEach(list, iterator, context) {
24675 if (!isFunction(iterator)) {
24676 throw new TypeError('iterator must be a function')
24679 if (arguments.length < 3) {
24683 if (toString.call(list) === '[object Array]')
24684 forEachArray(list, iterator, context)
24685 else if (typeof list === 'string')
24686 forEachString(list, iterator, context)
24688 forEachObject(list, iterator, context)
24691 function forEachArray(array, iterator, context) {
24692 for (var i = 0, len = array.length; i < len; i++) {
24693 if (hasOwnProperty.call(array, i)) {
24694 iterator.call(context, array[i], i, array)
24699 function forEachString(string, iterator, context) {
24700 for (var i = 0, len = string.length; i < len; i++) {
24701 // no such thing as a sparse string.
24702 iterator.call(context, string.charAt(i), i, string)
24706 function forEachObject(object, iterator, context) {
24707 for (var k in object) {
24708 if (hasOwnProperty.call(object, k)) {
24709 iterator.call(context, object[k], k, object)
24714 },{"100":100}],102:[function(_dereq_,module,exports){
24716 exports = module.exports = trim;
24718 function trim(str){
24719 return str.replace(/^\s*|\s*$/g, '');
24722 exports.left = function(str){
24723 return str.replace(/^\s*/, '');
24726 exports.right = function(str){
24727 return str.replace(/\s*$/, '');
24730 },{}],103:[function(_dereq_,module,exports){
24731 var trim = _dereq_(102)
24732 , forEach = _dereq_(101)
24733 , isArray = function(arg) {
24734 return Object.prototype.toString.call(arg) === '[object Array]';
24737 module.exports = function (headers) {
24744 trim(headers).split('\n')
24746 var index = row.indexOf(':')
24747 , key = trim(row.slice(0, index)).toLowerCase()
24748 , value = trim(row.slice(index + 1))
24750 if (typeof(result[key]) === 'undefined') {
24751 result[key] = value
24752 } else if (isArray(result[key])) {
24753 result[key].push(value)
24755 result[key] = [ result[key], value ]
24762 },{"101":101,"102":102}],104:[function(_dereq_,module,exports){
24763 module.exports = extend
24765 var hasOwnProperty = Object.prototype.hasOwnProperty;
24767 function extend() {
24770 for (var i = 0; i < arguments.length; i++) {
24771 var source = arguments[i]
24773 for (var key in source) {
24774 if (hasOwnProperty.call(source, key)) {
24775 target[key] = source[key]
24783 },{}]},{},[93])(93)