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>
8 * Includes vtt.js <https://github.com/mozilla/vtt.js>
9 * Available under Apache License Version 2.0
10 * <https://github.com/mozilla/vtt.js/blob/master/LICENSE>
13 (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){
16 exports.__esModule = true;
18 var _button = _dereq_(2);
20 var _button2 = _interopRequireDefault(_button);
22 var _component = _dereq_(5);
24 var _component2 = _interopRequireDefault(_component);
26 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
28 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
30 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; }
32 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; } /**
33 * @file big-play-button.js
38 * The initial play button that shows before the video has played. The hiding of the
39 * `BigPlayButton` get done via CSS and `Player` states.
43 var BigPlayButton = function (_Button) {
44 _inherits(BigPlayButton, _Button);
46 function BigPlayButton() {
47 _classCallCheck(this, BigPlayButton);
49 return _possibleConstructorReturn(this, _Button.apply(this, arguments));
53 * Builds the default DOM `className`.
56 * The DOM `className` for this object. Always returns 'vjs-big-play-button'.
58 BigPlayButton.prototype.buildCSSClass = function buildCSSClass() {
59 return 'vjs-big-play-button';
63 * This gets called when a `BigPlayButton` "clicked". See {@link ClickableComponent}
64 * for more detailed information on what a click can be.
66 * @param {EventTarget~Event} event
67 * The `keydown`, `tap`, or `click` event that caused this function to be
75 BigPlayButton.prototype.handleClick = function handleClick(event) {
78 var cb = this.player_.getChild('controlBar');
79 var playToggle = cb && cb.getChild('playToggle');
86 this.setTimeout(function () {
92 }(_button2['default']);
95 * The text that should display over the `BigPlayButton`s controls. Added to for localization.
102 BigPlayButton.prototype.controlText_ = 'Play Video';
104 _component2['default'].registerComponent('BigPlayButton', BigPlayButton);
105 exports['default'] = BigPlayButton;
107 },{"2":2,"5":5}],2:[function(_dereq_,module,exports){
110 exports.__esModule = true;
112 var _clickableComponent = _dereq_(3);
114 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
116 var _component = _dereq_(5);
118 var _component2 = _interopRequireDefault(_component);
120 var _log = _dereq_(86);
122 var _log2 = _interopRequireDefault(_log);
124 var _obj = _dereq_(88);
126 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
128 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
130 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; }
132 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; } /**
138 * Base class for all buttons.
140 * @extends ClickableComponent
142 var Button = function (_ClickableComponent) {
143 _inherits(Button, _ClickableComponent);
146 _classCallCheck(this, Button);
148 return _possibleConstructorReturn(this, _ClickableComponent.apply(this, arguments));
152 * Create the `Button`s DOM element.
154 * @param {string} [tag=button]
155 * Element's node type. e.g. 'button'
157 * @param {Object} [props={}]
158 * An object of properties that should be set on the element.
160 * @param {Object} [attributes={}]
161 * An object of attributes that should be set on the element.
164 * The element that gets created.
166 Button.prototype.createEl = function createEl() {
167 var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'button';
168 var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
169 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
171 props = (0, _obj.assign)({
172 className: this.buildCSSClass()
175 if (tag !== 'button') {
176 _log2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.');
178 // Add properties for clickable element which is not a native HTML button
179 props = (0, _obj.assign)({
183 // Add ARIA attributes for clickable element which is not a native HTML button
184 attributes = (0, _obj.assign)({
189 // Add attributes for button element
190 attributes = (0, _obj.assign)({
192 // Necessary since the default button type is "submit"
195 // let the screen reader user know that the text of the button may change
196 'aria-live': 'polite'
199 var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes);
201 this.createControlTextEl(el);
207 * Add a child `Component` inside of this `Button`.
209 * @param {string|Component} child
210 * The name or instance of a child to add.
212 * @param {Object} [options={}]
213 * The key/value store of options that will get passed to children of
216 * @return {Component}
217 * The `Component` that gets added as a child. When using a string the
218 * `Component` will get created by this process.
220 * @deprecated since version 5
224 Button.prototype.addChild = function addChild(child) {
225 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
227 var className = this.constructor.name;
229 _log2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.');
231 // Avoid the error message generated by ClickableComponent's addChild method
232 return _component2['default'].prototype.addChild.call(this, child, options);
236 * Enable the `Button` element so that it can be activated or clicked. Use this with
237 * {@link Button#disable}.
241 Button.prototype.enable = function enable() {
242 _ClickableComponent.prototype.enable.call(this);
243 this.el_.removeAttribute('disabled');
247 * Enable the `Button` element so that it cannot be activated or clicked. Use this with
248 * {@link Button#enable}.
252 Button.prototype.disable = function disable() {
253 _ClickableComponent.prototype.disable.call(this);
254 this.el_.setAttribute('disabled', 'disabled');
258 * This gets called when a `Button` has focus and `keydown` is triggered via a key
261 * @param {EventTarget~Event} event
262 * The event that caused this function to get called.
268 Button.prototype.handleKeyPress = function handleKeyPress(event) {
270 // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button.
271 if (event.which === 32 || event.which === 13) {
275 // Pass keypress handling up for unsupported keys
276 _ClickableComponent.prototype.handleKeyPress.call(this, event);
280 }(_clickableComponent2['default']);
282 _component2['default'].registerComponent('Button', Button);
283 exports['default'] = Button;
285 },{"3":3,"5":5,"86":86,"88":88}],3:[function(_dereq_,module,exports){
288 exports.__esModule = true;
290 var _component = _dereq_(5);
292 var _component2 = _interopRequireDefault(_component);
294 var _dom = _dereq_(81);
296 var Dom = _interopRequireWildcard(_dom);
298 var _events = _dereq_(82);
300 var Events = _interopRequireWildcard(_events);
302 var _fn = _dereq_(83);
304 var Fn = _interopRequireWildcard(_fn);
306 var _log = _dereq_(86);
308 var _log2 = _interopRequireDefault(_log);
310 var _document = _dereq_(94);
312 var _document2 = _interopRequireDefault(_document);
314 var _obj = _dereq_(88);
316 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; } }
318 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
320 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
322 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; }
324 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; } /**
330 * Clickable Component which is clickable or keyboard actionable,
331 * but is not a native HTML button.
335 var ClickableComponent = function (_Component) {
336 _inherits(ClickableComponent, _Component);
339 * Creates an instance of this class.
341 * @param {Player} player
342 * The `Player` that this class should be attached to.
344 * @param {Object} [options]
345 * The key/value store of player options.
347 function ClickableComponent(player, options) {
348 _classCallCheck(this, ClickableComponent);
350 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
352 _this.emitTapEvents();
359 * Create the `Component`s DOM element.
361 * @param {string} [tag=div]
362 * The element's node type.
364 * @param {Object} [props={}]
365 * An object of properties that should be set on the element.
367 * @param {Object} [attributes={}]
368 * An object of attributes that should be set on the element.
371 * The element that gets created.
375 ClickableComponent.prototype.createEl = function createEl() {
376 var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
377 var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
378 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
380 props = (0, _obj.assign)({
381 className: this.buildCSSClass(),
385 if (tag === 'button') {
386 _log2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.');
389 // Add ARIA attributes for clickable element which is not a native HTML button
390 attributes = (0, _obj.assign)({
393 // let the screen reader user know that the text of the element may change
394 'aria-live': 'polite'
397 this.tabIndex_ = props.tabIndex;
399 var el = _Component.prototype.createEl.call(this, tag, props, attributes);
401 this.createControlTextEl(el);
407 * Create a control text element on this `Component`
409 * @param {Element} [el]
410 * Parent element for the control text.
413 * The control text element that gets created.
417 ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) {
418 this.controlTextEl_ = Dom.createEl('span', {
419 className: 'vjs-control-text'
423 el.appendChild(this.controlTextEl_);
426 this.controlText(this.controlText_, el);
428 return this.controlTextEl_;
432 * Get or set the localize text to use for the controls on the `Component`.
434 * @param {string} [text]
435 * Control text for element.
437 * @param {Element} [el=this.el()]
438 * Element to set the title on.
440 * @return {string|ClickableComponent}
441 * - The control text when getting
442 * - Returns itself when setting; method can be chained.
446 ClickableComponent.prototype.controlText = function controlText(text) {
447 var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.el();
450 return this.controlText_ || 'Need Text';
453 var localizedText = this.localize(text);
455 this.controlText_ = text;
456 this.controlTextEl_.innerHTML = localizedText;
458 if (!this.nonIconControl) {
459 // Set title attribute if only an icon is shown
460 el.setAttribute('title', localizedText);
467 * Builds the default DOM `className`.
470 * The DOM `className` for this object.
474 ClickableComponent.prototype.buildCSSClass = function buildCSSClass() {
475 return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this);
479 * Enable this `Component`s element.
481 * @return {ClickableComponent}
482 * Returns itself; method can be chained.
486 ClickableComponent.prototype.enable = function enable() {
487 this.removeClass('vjs-disabled');
488 this.el_.setAttribute('aria-disabled', 'false');
489 if (typeof this.tabIndex_ !== 'undefined') {
490 this.el_.setAttribute('tabIndex', this.tabIndex_);
492 this.on('tap', this.handleClick);
493 this.on('click', this.handleClick);
494 this.on('focus', this.handleFocus);
495 this.on('blur', this.handleBlur);
500 * Disable this `Component`s element.
502 * @return {ClickableComponent}
503 * Returns itself; method can be chained.
507 ClickableComponent.prototype.disable = function disable() {
508 this.addClass('vjs-disabled');
509 this.el_.setAttribute('aria-disabled', 'true');
510 if (typeof this.tabIndex_ !== 'undefined') {
511 this.el_.removeAttribute('tabIndex');
513 this.off('tap', this.handleClick);
514 this.off('click', this.handleClick);
515 this.off('focus', this.handleFocus);
516 this.off('blur', this.handleBlur);
521 * This gets called when a `ClickableComponent` gets:
522 * - Clicked (via the `click` event, listening starts in the constructor)
523 * - Tapped (via the `tap` event, listening starts in the constructor)
524 * - The following things happen in order:
525 * 1. {@link ClickableComponent#handleFocus} is called via a `focus` event on the
526 * `ClickableComponent`.
527 * 2. {@link ClickableComponent#handleFocus} adds a listener for `keydown` on using
528 * {@link ClickableComponent#handleKeyPress}.
529 * 3. `ClickableComponent` has not had a `blur` event (`blur` means that focus was lost). The user presses
530 * the space or enter key.
531 * 4. {@link ClickableComponent#handleKeyPress} calls this function with the `keydown`
532 * event as a parameter.
534 * @param {EventTarget~Event} event
535 * The `keydown`, `tap`, or `click` event that caused this function to be
544 ClickableComponent.prototype.handleClick = function handleClick(event) {};
547 * This gets called when a `ClickableComponent` gains focus via a `focus` event.
548 * Turns on listening for `keydown` events. When they happen it
549 * calls `this.handleKeyPress`.
551 * @param {EventTarget~Event} event
552 * The `focus` event that caused this function to be called.
558 ClickableComponent.prototype.handleFocus = function handleFocus(event) {
559 Events.on(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
563 * Called when this ClickableComponent has focus and a key gets pressed down. By
564 * default it will call `this.handleClick` when the key is space or enter.
566 * @param {EventTarget~Event} event
567 * The `keydown` event that caused this function to be called.
573 ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) {
575 // Support Space (32) or Enter (13) key operation to fire a click event
576 if (event.which === 32 || event.which === 13) {
577 event.preventDefault();
578 this.handleClick(event);
579 } else if (_Component.prototype.handleKeyPress) {
581 // Pass keypress handling up for unsupported keys
582 _Component.prototype.handleKeyPress.call(this, event);
587 * Called when a `ClickableComponent` loses focus. Turns off the listener for
588 * `keydown` events. Which Stops `this.handleKeyPress` from getting called.
590 * @param {EventTarget~Event} event
591 * The `blur` event that caused this function to be called.
597 ClickableComponent.prototype.handleBlur = function handleBlur(event) {
598 Events.off(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
601 return ClickableComponent;
602 }(_component2['default']);
604 _component2['default'].registerComponent('ClickableComponent', ClickableComponent);
605 exports['default'] = ClickableComponent;
607 },{"5":5,"81":81,"82":82,"83":83,"86":86,"88":88,"94":94}],4:[function(_dereq_,module,exports){
610 exports.__esModule = true;
612 var _button = _dereq_(2);
614 var _button2 = _interopRequireDefault(_button);
616 var _component = _dereq_(5);
618 var _component2 = _interopRequireDefault(_component);
620 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
622 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
624 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; }
626 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; } /**
627 * @file close-button.js
632 * The `CloseButton` is a `{@link Button}` that fires a `close` event when
637 var CloseButton = function (_Button) {
638 _inherits(CloseButton, _Button);
641 * Creates an instance of the this class.
643 * @param {Player} player
644 * The `Player` that this class should be attached to.
646 * @param {Object} [options]
647 * The key/value store of player options.
649 function CloseButton(player, options) {
650 _classCallCheck(this, CloseButton);
652 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
654 _this.controlText(options && options.controlText || _this.localize('Close'));
659 * Builds the default DOM `className`.
662 * The DOM `className` for this object.
666 CloseButton.prototype.buildCSSClass = function buildCSSClass() {
667 return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this);
671 * This gets called when a `CloseButton` gets clicked. See
672 * {@link ClickableComponent#handleClick} for more information on when this will be
675 * @param {EventTarget~Event} event
676 * The `keydown`, `tap`, or `click` event that caused this function to be
681 * @fires CloseButton#close
685 CloseButton.prototype.handleClick = function handleClick(event) {
688 * Triggered when the a `CloseButton` is clicked.
690 * @event CloseButton#close
691 * @type {EventTarget~Event}
693 * @property {boolean} [bubbles=false]
694 * set to false so that the close event does not
695 * bubble up to parents if there is no listener
697 this.trigger({ type: 'close', bubbles: false });
701 }(_button2['default']);
703 _component2['default'].registerComponent('CloseButton', CloseButton);
704 exports['default'] = CloseButton;
706 },{"2":2,"5":5}],5:[function(_dereq_,module,exports){
709 exports.__esModule = true;
711 var _window = _dereq_(95);
713 var _window2 = _interopRequireDefault(_window);
715 var _dom = _dereq_(81);
717 var Dom = _interopRequireWildcard(_dom);
719 var _fn = _dereq_(83);
721 var Fn = _interopRequireWildcard(_fn);
723 var _guid = _dereq_(85);
725 var Guid = _interopRequireWildcard(_guid);
727 var _events = _dereq_(82);
729 var Events = _interopRequireWildcard(_events);
731 var _log = _dereq_(86);
733 var _log2 = _interopRequireDefault(_log);
735 var _toTitleCase = _dereq_(91);
737 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
739 var _mergeOptions = _dereq_(87);
741 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
743 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; } }
745 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
747 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
748 * Player Component - Base class for all UI objects
755 * Base class for all UI Components.
756 * Components are UI objects which represent both a javascript object and an element
757 * in the DOM. They can be children of other components, and can have
758 * children themselves.
760 * Components can also use methods from {@link EventTarget}
762 var Component = function () {
765 * A callback that is called when a component is ready. Does not have any
766 * paramters and any callback value will be ignored.
768 * @callback Component~ReadyCallback
773 * Creates an instance of this class.
775 * @param {Player} player
776 * The `Player` that this class should be attached to.
778 * @param {Object} [options]
779 * The key/value store of player options.
781 * @param {Object[]} [options.children]
782 * An array of children objects to intialize this component with. Children objects have
783 * a name property that will be used if more than one component of the same type needs to be
786 * @param {Component~ReadyCallback} [ready]
787 * Function that gets called when the `Component` is ready.
789 function Component(player, options, ready) {
790 _classCallCheck(this, Component);
792 // The component might be the player itself and we can't pass `this` to super
793 if (!player && this.play) {
794 this.player_ = player = this; // eslint-disable-line
796 this.player_ = player;
799 // Make a copy of prototype.options_ to protect against overriding defaults
800 this.options_ = (0, _mergeOptions2['default'])({}, this.options_);
802 // Updated options with supplied options
803 options = this.options_ = (0, _mergeOptions2['default'])(this.options_, options);
805 // Get ID from options or options element if one is supplied
806 this.id_ = options.id || options.el && options.el.id;
808 // If there was no ID from the options, generate one
810 // Don't require the player ID function in the case of mock players
811 var id = player && player.id && player.id() || 'no_player';
813 this.id_ = id + '_component_' + Guid.newGUID();
816 this.name_ = options.name || null;
818 // Create element if one wasn't provided in options
820 this.el_ = options.el;
821 } else if (options.createEl !== false) {
822 this.el_ = this.createEl();
826 this.childIndex_ = {};
827 this.childNameIndex_ = {};
829 // Add any child components in options
830 if (options.initChildren !== false) {
835 // Don't want to trigger ready here or it will before init is actually
836 // finished for all children that run this constructor
838 if (options.reportTouchActivity !== false) {
839 this.enableTouchActivity();
844 * Dispose of the `Component` and all child components.
846 * @fires Component#dispose
850 Component.prototype.dispose = function dispose() {
853 * Triggered when a `Component` is disposed.
855 * @event Component#dispose
856 * @type {EventTarget~Event}
858 * @property {boolean} [bubbles=false]
859 * set to false so that the close event does not
862 this.trigger({ type: 'dispose', bubbles: false });
864 // Dispose all children.
865 if (this.children_) {
866 for (var i = this.children_.length - 1; i >= 0; i--) {
867 if (this.children_[i].dispose) {
868 this.children_[i].dispose();
873 // Delete child references
874 this.children_ = null;
875 this.childIndex_ = null;
876 this.childNameIndex_ = null;
878 // Remove all event listeners.
881 // Remove element from DOM
882 if (this.el_.parentNode) {
883 this.el_.parentNode.removeChild(this.el_);
886 Dom.removeElData(this.el_);
891 * Return the {@link Player} that the `Component` has attached to.
894 * The player that this `Component` has attached to.
898 Component.prototype.player = function player() {
903 * Deep merge of options objects with new options.
904 * > Note: When both `obj` and `options` contain properties whose values are objects.
905 * The two properties get merged using {@link module:mergeOptions}
907 * @param {Object} obj
908 * The object that contains new options.
911 * A new object of `this.options_` and `obj` merged together.
913 * @deprecated since version 5
917 Component.prototype.options = function options(obj) {
918 _log2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0');
921 return this.options_;
924 this.options_ = (0, _mergeOptions2['default'])(this.options_, obj);
925 return this.options_;
929 * Get the `Component`s DOM element
932 * The DOM element for this `Component`.
936 Component.prototype.el = function el() {
941 * Create the `Component`s DOM element.
943 * @param {string} [tagName]
944 * Element's DOM node type. e.g. 'div'
946 * @param {Object} [properties]
947 * An object of properties that should be set.
949 * @param {Object} [attributes]
950 * An object of attributes that should be set.
953 * The element that gets created.
957 Component.prototype.createEl = function createEl(tagName, properties, attributes) {
958 return Dom.createEl(tagName, properties, attributes);
962 * Localize a string given the string in english.
964 * @param {string} string
965 * The string to localize.
968 * The localized string or if no localization exists the english string.
972 Component.prototype.localize = function localize(string) {
973 var code = this.player_.language && this.player_.language();
974 var languages = this.player_.languages && this.player_.languages();
976 if (!code || !languages) {
980 var language = languages[code];
982 if (language && language[string]) {
983 return language[string];
986 var primaryCode = code.split('-')[0];
987 var primaryLang = languages[primaryCode];
989 if (primaryLang && primaryLang[string]) {
990 return primaryLang[string];
997 * Return the `Component`s DOM element. This is where children get inserted.
998 * This will usually be the the same as the element returned in {@link Component#el}.
1001 * The content element for this `Component`.
1005 Component.prototype.contentEl = function contentEl() {
1006 return this.contentEl_ || this.el_;
1010 * Get this `Component`s ID
1013 * The id of this `Component`
1017 Component.prototype.id = function id() {
1022 * Get the `Component`s name. The name gets used to reference the `Component`
1023 * and is set during registration.
1026 * The name of this `Component`.
1030 Component.prototype.name = function name() {
1035 * Get an array of all child components
1042 Component.prototype.children = function children() {
1043 return this.children_;
1047 * Returns the child `Component` with the given `id`.
1049 * @param {string} id
1050 * The id of the child `Component` to get.
1052 * @return {Component|undefined}
1053 * The child `Component` with the given `id` or undefined.
1057 Component.prototype.getChildById = function getChildById(id) {
1058 return this.childIndex_[id];
1062 * Returns the child `Component` with the given `name`.
1064 * @param {string} name
1065 * The name of the child `Component` to get.
1067 * @return {Component|undefined}
1068 * The child `Component` with the given `name` or undefined.
1072 Component.prototype.getChild = function getChild(name) {
1077 name = (0, _toTitleCase2['default'])(name);
1079 return this.childNameIndex_[name];
1083 * Add a child `Component` inside the current `Component`.
1086 * @param {string|Component} child
1087 * The name or instance of a child to add.
1089 * @param {Object} [options={}]
1090 * The key/value store of options that will get passed to children of
1093 * @param {number} [index=this.children_.length]
1094 * The index to attempt to add a child into.
1096 * @return {Component}
1097 * The `Component` that gets added as a child. When using a string the
1098 * `Component` will get created by this process.
1102 Component.prototype.addChild = function addChild(child) {
1103 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1104 var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.children_.length;
1106 var component = void 0;
1107 var componentName = void 0;
1109 // If child is a string, create component with options
1110 if (typeof child === 'string') {
1111 componentName = (0, _toTitleCase2['default'])(child);
1113 // Options can also be specified as a boolean,
1114 // so convert to an empty object if false.
1119 // Same as above, but true is deprecated so show a warning.
1120 if (options === true) {
1121 _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`.');
1125 var componentClassName = options.componentClass || componentName;
1127 // Set name through options
1128 options.name = componentName;
1130 // Create a new object & element for this controls set
1131 // If there's no .player_, this is a player
1132 var ComponentClass = Component.getComponent(componentClassName);
1134 if (!ComponentClass) {
1135 throw new Error('Component ' + componentClassName + ' does not exist');
1138 // data stored directly on the videojs object may be
1139 // misidentified as a component to retain
1140 // backwards-compatibility with 4.x. check to make sure the
1141 // component class can be instantiated.
1142 if (typeof ComponentClass !== 'function') {
1146 component = new ComponentClass(this.player_ || this, options);
1148 // child is a component instance
1153 this.children_.splice(index, 0, component);
1155 if (typeof component.id === 'function') {
1156 this.childIndex_[component.id()] = component;
1159 // If a name wasn't used to create the component, check if we can use the
1160 // name function of the component
1161 componentName = componentName || component.name && (0, _toTitleCase2['default'])(component.name());
1163 if (componentName) {
1164 this.childNameIndex_[componentName] = component;
1167 // Add the UI object's element to the container div (box)
1168 // Having an element is not required
1169 if (typeof component.el === 'function' && component.el()) {
1170 var childNodes = this.contentEl().children;
1171 var refNode = childNodes[index] || null;
1173 this.contentEl().insertBefore(component.el(), refNode);
1176 // Return so it can stored on parent object if desired.
1181 * Remove a child `Component` from this `Component`s list of children. Also removes
1182 * the child `Component`s element from this `Component`s element.
1184 * @param {Component} component
1185 * The child `Component` to remove.
1189 Component.prototype.removeChild = function removeChild(component) {
1190 if (typeof component === 'string') {
1191 component = this.getChild(component);
1194 if (!component || !this.children_) {
1198 var childFound = false;
1200 for (var i = this.children_.length - 1; i >= 0; i--) {
1201 if (this.children_[i] === component) {
1203 this.children_.splice(i, 1);
1212 this.childIndex_[component.id()] = null;
1213 this.childNameIndex_[component.name()] = null;
1215 var compEl = component.el();
1217 if (compEl && compEl.parentNode === this.contentEl()) {
1218 this.contentEl().removeChild(component.el());
1223 * Add and initialize default child `Component`s based upon options.
1227 Component.prototype.initChildren = function initChildren() {
1230 var children = this.options_.children;
1233 // `this` is `parent`
1234 var parentOptions = this.options_;
1236 var handleAdd = function handleAdd(child) {
1237 var name = child.name;
1238 var opts = child.opts;
1240 // Allow options for children to be set at the parent options
1241 // e.g. videojs(id, { controlBar: false });
1242 // instead of videojs(id, { children: { controlBar: false });
1243 if (parentOptions[name] !== undefined) {
1244 opts = parentOptions[name];
1247 // Allow for disabling default components
1248 // e.g. options['children']['posterImage'] = false
1249 if (opts === false) {
1253 // Allow options to be passed as a simple boolean if no configuration
1255 if (opts === true) {
1259 // We also want to pass the original player options
1260 // to each component as well so they don't need to
1261 // reach back into the player for options later.
1262 opts.playerOptions = _this.options_.playerOptions;
1264 // Create and add the child component.
1265 // Add a direct reference to the child by name on the parent instance.
1266 // If two of the same component are used, different names should be supplied
1268 var newChild = _this.addChild(name, opts);
1271 _this[name] = newChild;
1275 // Allow for an array of children details to passed in the options
1276 var workingChildren = void 0;
1277 var Tech = Component.getComponent('Tech');
1279 if (Array.isArray(children)) {
1280 workingChildren = children;
1282 workingChildren = Object.keys(children);
1286 // children that are in this.options_ but also in workingChildren would
1287 // give us extra children we do not want. So, we want to filter them out.
1288 .concat(Object.keys(this.options_).filter(function (child) {
1289 return !workingChildren.some(function (wchild) {
1290 if (typeof wchild === 'string') {
1291 return child === wchild;
1293 return child === wchild.name;
1295 })).map(function (child) {
1299 if (typeof child === 'string') {
1301 opts = children[name] || _this.options_[name] || {};
1307 return { name: name, opts: opts };
1308 }).filter(function (child) {
1309 // we have to make sure that child.name isn't in the techOrder since
1310 // techs are registerd as Components but can't aren't compatible
1311 // See https://github.com/videojs/video.js/issues/2772
1312 var c = Component.getComponent(child.opts.componentClass || (0, _toTitleCase2['default'])(child.name));
1314 return c && !Tech.isTech(c);
1315 }).forEach(handleAdd);
1320 * Builds the default DOM class name. Should be overriden by sub-components.
1323 * The DOM class name for this object.
1329 Component.prototype.buildCSSClass = function buildCSSClass() {
1330 // Child classes can include a function that does:
1331 // return 'CLASS NAME' + this._super();
1336 * Add an `event listener` to this `Component`s element.
1338 * The benefit of using this over the following:
1339 * - `VjsEvents.on(otherElement, 'eventName', myFunc)`
1340 * - `otherComponent.on('eventName', myFunc)`
1342 * 1. Is that the listeners will get cleaned up when either component gets disposed.
1343 * 1. It will also bind `myComponent` as the context of `myFunc`.
1344 * > NOTE: If you remove the element from the DOM that has used `on` you need to
1345 * clean up references using: `myComponent.trigger(el, 'dispose')`
1346 * This will also allow the browser to garbage collect it. In special
1347 * cases such as with `window` and `document`, which are both permanent,
1348 * this is not necessary.
1350 * @param {string|Component|string[]} [first]
1351 * The event name, and array of event names, or another `Component`.
1353 * @param {EventTarget~EventListener|string|string[]} [second]
1354 * The listener function, an event name, or an Array of events names.
1356 * @param {EventTarget~EventListener} [third]
1357 * The event handler if `first` is a `Component` and `second` is an event name
1358 * or an Array of event names.
1360 * @return {Component}
1361 * Returns itself; method can be chained.
1363 * @listens Component#dispose
1367 Component.prototype.on = function on(first, second, third) {
1370 if (typeof first === 'string' || Array.isArray(first)) {
1371 Events.on(this.el_, first, Fn.bind(this, second));
1373 // Targeting another component or element
1377 var fn = Fn.bind(this, third);
1379 // When this component is disposed, remove the listener from the other component
1380 var removeOnDispose = function removeOnDispose() {
1381 return _this2.off(target, type, fn);
1384 // Use the same function ID so we can remove it later it using the ID
1385 // of the original listener
1386 removeOnDispose.guid = fn.guid;
1387 this.on('dispose', removeOnDispose);
1389 // If the other component is disposed first we need to clean the reference
1390 // to the other component in this component's removeOnDispose listener
1391 // Otherwise we create a memory leak.
1392 var cleanRemover = function cleanRemover() {
1393 return _this2.off('dispose', removeOnDispose);
1396 // Add the same function ID so we can easily remove it later
1397 cleanRemover.guid = fn.guid;
1399 // Check if this is a DOM node
1400 if (first.nodeName) {
1401 // Add the listener to the other element
1402 Events.on(target, type, fn);
1403 Events.on(target, 'dispose', cleanRemover);
1405 // Should be a component
1406 // Not using `instanceof Component` because it makes mock players difficult
1407 } else if (typeof first.on === 'function') {
1408 // Add the listener to the other component
1409 target.on(type, fn);
1410 target.on('dispose', cleanRemover);
1418 * Remove an event listener from this `Component`s element. If the second argument is
1419 * exluded all listeners for the type passed in as the first argument will be removed.
1421 * @param {string|Component|string[]} [first]
1422 * The event name, and array of event names, or another `Component`.
1424 * @param {EventTarget~EventListener|string|string[]} [second]
1425 * The listener function, an event name, or an Array of events names.
1427 * @param {EventTarget~EventListener} [third]
1428 * The event handler if `first` is a `Component` and `second` is an event name
1429 * or an Array of event names.
1431 * @return {Component}
1432 * Returns itself; method can be chained.
1436 Component.prototype.off = function off(first, second, third) {
1437 if (!first || typeof first === 'string' || Array.isArray(first)) {
1438 Events.off(this.el_, first, second);
1442 // Ensure there's at least a guid, even if the function hasn't been used
1443 var fn = Fn.bind(this, third);
1445 // Remove the dispose listener on this component,
1446 // which was given the same guid as the event listener
1447 this.off('dispose', fn);
1449 if (first.nodeName) {
1450 // Remove the listener
1451 Events.off(target, type, fn);
1452 // Remove the listener for cleaning the dispose listener
1453 Events.off(target, 'dispose', fn);
1455 target.off(type, fn);
1456 target.off('dispose', fn);
1464 * Add an event listener that gets triggered only once and then gets removed.
1466 * @param {string|Component|string[]} [first]
1467 * The event name, and array of event names, or another `Component`.
1469 * @param {EventTarget~EventListener|string|string[]} [second]
1470 * The listener function, an event name, or an Array of events names.
1472 * @param {EventTarget~EventListener} [third]
1473 * The event handler if `first` is a `Component` and `second` is an event name
1474 * or an Array of event names.
1476 * @return {Component}
1477 * Returns itself; method can be chained.
1481 Component.prototype.one = function one(first, second, third) {
1483 _arguments = arguments;
1485 if (typeof first === 'string' || Array.isArray(first)) {
1486 Events.one(this.el_, first, Fn.bind(this, second));
1490 var fn = Fn.bind(this, third);
1492 var newFunc = function newFunc() {
1493 _this3.off(target, type, newFunc);
1494 fn.apply(null, _arguments);
1497 // Keep the same function ID so we can remove it later
1498 newFunc.guid = fn.guid;
1500 this.on(target, type, newFunc);
1507 * Trigger an event on an element.
1509 * @param {EventTarget~Event|Object|string} event
1510 * The event name, and Event, or an event-like object with a type attribute
1511 * set to the event name.
1513 * @param {Object} [hash]
1514 * Data hash to pass along with the event
1516 * @return {Component}
1517 * Returns itself; method can be chained.
1521 Component.prototype.trigger = function trigger(event, hash) {
1522 Events.trigger(this.el_, event, hash);
1527 * Bind a listener to the component's ready state. If the ready event has already
1528 * happened it will trigger the function immediately.
1530 * @param {Component~ReadyCallback} fn
1531 * A function to call when ready is triggered.
1533 * @param {boolean} [sync=false]
1534 * Execute the listener synchronously if `Component` is ready.
1536 * @return {Component}
1537 * Returns itself; method can be chained.
1541 Component.prototype.ready = function ready(fn) {
1542 var sync = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1545 if (this.isReady_) {
1549 // Call the function asynchronously by default for consistency
1550 this.setTimeout(fn, 1);
1553 this.readyQueue_ = this.readyQueue_ || [];
1554 this.readyQueue_.push(fn);
1561 * Trigger all the ready listeners for this `Component`.
1563 * @fires Component#ready
1567 Component.prototype.triggerReady = function triggerReady() {
1568 this.isReady_ = true;
1570 // Ensure ready is triggerd asynchronously
1571 this.setTimeout(function () {
1572 var readyQueue = this.readyQueue_;
1574 // Reset Ready Queue
1575 this.readyQueue_ = [];
1577 if (readyQueue && readyQueue.length > 0) {
1578 readyQueue.forEach(function (fn) {
1583 // Allow for using event listeners also
1585 * Triggered when a `Component` is ready.
1587 * @event Component#ready
1588 * @type {EventTarget~Event}
1590 this.trigger('ready');
1595 * Find a single DOM element matching a `selector`. This can be within the `Component`s
1596 * `contentEl()` or another custom context.
1598 * @param {string} selector
1599 * A valid CSS selector, which will be passed to `querySelector`.
1601 * @param {Element|string} [context=this.contentEl()]
1602 * A DOM element within which to query. Can also be a selector string in
1603 * which case the first matching element will get used as context. If
1604 * missing `this.contentEl()` gets used. If `this.contentEl()` returns
1605 * nothing it falls back to `document`.
1607 * @return {Element|null}
1608 * the dom element that was found, or null
1610 * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
1614 Component.prototype.$ = function $(selector, context) {
1615 return Dom.$(selector, context || this.contentEl());
1619 * Finds all DOM element matching a `selector`. This can be within the `Component`s
1620 * `contentEl()` or another custom context.
1622 * @param {string} selector
1623 * A valid CSS selector, which will be passed to `querySelectorAll`.
1625 * @param {Element|string} [context=this.contentEl()]
1626 * A DOM element within which to query. Can also be a selector string in
1627 * which case the first matching element will get used as context. If
1628 * missing `this.contentEl()` gets used. If `this.contentEl()` returns
1629 * nothing it falls back to `document`.
1631 * @return {NodeList}
1632 * a list of dom elements that were found
1634 * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
1638 Component.prototype.$$ = function $$(selector, context) {
1639 return Dom.$$(selector, context || this.contentEl());
1643 * Check if a component's element has a CSS class name.
1645 * @param {string} classToCheck
1646 * CSS class name to check.
1649 * - True if the `Component` has the class.
1650 * - False if the `Component` does not have the class`
1654 Component.prototype.hasClass = function hasClass(classToCheck) {
1655 return Dom.hasElClass(this.el_, classToCheck);
1659 * Add a CSS class name to the `Component`s element.
1661 * @param {string} classToAdd
1662 * CSS class name to add
1664 * @return {Component}
1665 * Returns itself; method can be chained.
1669 Component.prototype.addClass = function addClass(classToAdd) {
1670 Dom.addElClass(this.el_, classToAdd);
1675 * Remove a CSS class name from the `Component`s element.
1677 * @param {string} classToRemove
1678 * CSS class name to remove
1680 * @return {Component}
1681 * Returns itself; method can be chained.
1685 Component.prototype.removeClass = function removeClass(classToRemove) {
1686 Dom.removeElClass(this.el_, classToRemove);
1691 * Add or remove a CSS class name from the component's element.
1692 * - `classToToggle` gets added when {@link Component#hasClass} would return false.
1693 * - `classToToggle` gets removed when {@link Component#hasClass} would return true.
1695 * @param {string} classToToggle
1696 * The class to add or remove based on (@link Component#hasClass}
1698 * @param {boolean|Dom~predicate} [predicate]
1699 * An {@link Dom~predicate} function or a boolean
1701 * @return {Component}
1702 * Returns itself; method can be chained.
1706 Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) {
1707 Dom.toggleElClass(this.el_, classToToggle, predicate);
1712 * Show the `Component`s element if it is hidden by removing the
1713 * 'vjs-hidden' class name from it.
1715 * @return {Component}
1716 * Returns itself; method can be chained.
1720 Component.prototype.show = function show() {
1721 this.removeClass('vjs-hidden');
1726 * Hide the `Component`s element if it is currently showing by adding the
1727 * 'vjs-hidden` class name to it.
1729 * @return {Component}
1730 * Returns itself; method can be chained.
1734 Component.prototype.hide = function hide() {
1735 this.addClass('vjs-hidden');
1740 * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing'
1741 * class name to it. Used during fadeIn/fadeOut.
1743 * @return {Component}
1744 * Returns itself; method can be chained.
1750 Component.prototype.lockShowing = function lockShowing() {
1751 this.addClass('vjs-lock-showing');
1756 * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing'
1757 * class name from it. Used during fadeIn/fadeOut.
1759 * @return {Component}
1760 * Returns itself; method can be chained.
1766 Component.prototype.unlockShowing = function unlockShowing() {
1767 this.removeClass('vjs-lock-showing');
1772 * Get the value of an attribute on the `Component`s element.
1774 * @param {string} attribute
1775 * Name of the attribute to get the value from.
1777 * @return {string|null}
1778 * - The value of the attribute that was asked for.
1779 * - Can be an empty string on some browsers if the attribute does not exist
1781 * - Most browsers will return null if the attibute does not exist or has
1784 * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute}
1788 Component.prototype.getAttribute = function getAttribute(attribute) {
1789 return Dom.getAttribute(this.el_, attribute);
1793 * Set the value of an attribute on the `Component`'s element
1795 * @param {string} attribute
1796 * Name of the attribute to set.
1798 * @param {string} value
1799 * Value to set the attribute to.
1801 * @return {Component}
1802 * Returns itself; method can be chained.
1804 * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute}
1808 Component.prototype.setAttribute = function setAttribute(attribute, value) {
1809 Dom.setAttribute(this.el_, attribute, value);
1814 * Remove an attribute from the `Component`s element.
1816 * @param {string} attribute
1817 * Name of the attribute to remove.
1819 * @return {Component}
1820 * Returns itself; method can be chained.
1822 * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute}
1826 Component.prototype.removeAttribute = function removeAttribute(attribute) {
1827 Dom.removeAttribute(this.el_, attribute);
1832 * Get or set the width of the component based upon the CSS styles.
1833 * See {@link Component#dimension} for more detailed information.
1835 * @param {number|string} [num]
1836 * The width that you want to set postfixed with '%', 'px' or nothing.
1838 * @param {boolean} [skipListeners]
1839 * Skip the resize event trigger
1841 * @return {Component|number|string}
1842 * - The width when getting, zero if there is no width. Can be a string
1843 * postpixed with '%' or 'px'.
1844 * - Returns itself when setting; method can be chained.
1848 Component.prototype.width = function width(num, skipListeners) {
1849 return this.dimension('width', num, skipListeners);
1853 * Get or set the height of the component based upon the CSS styles.
1854 * See {@link Component#dimension} for more detailed information.
1856 * @param {number|string} [num]
1857 * The height that you want to set postfixed with '%', 'px' or nothing.
1859 * @param {boolean} [skipListeners]
1860 * Skip the resize event trigger
1862 * @return {Component|number|string}
1863 * - The width when getting, zero if there is no width. Can be a string
1864 * postpixed with '%' or 'px'.
1865 * - Returns itself when setting; method can be chained.
1869 Component.prototype.height = function height(num, skipListeners) {
1870 return this.dimension('height', num, skipListeners);
1874 * Set both the width and height of the `Component` element at the same time.
1876 * @param {number|string} width
1877 * Width to set the `Component`s element to.
1879 * @param {number|string} height
1880 * Height to set the `Component`s element to.
1882 * @return {Component}
1883 * Returns itself; method can be chained.
1887 Component.prototype.dimensions = function dimensions(width, height) {
1888 // Skip resize listeners on width for optimization
1889 return this.width(width, true).height(height);
1893 * Get or set width or height of the `Component` element. This is the shared code
1894 * for the {@link Component#width} and {@link Component#height}.
1897 * - If the width or height in an number this will return the number postfixed with 'px'.
1898 * - If the width/height is a percent this will return the percent postfixed with '%'
1899 * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function
1900 * defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`.
1901 * See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/}
1902 * for more information
1903 * - If you want the computed style of the component, use {@link Component#currentWidth}
1904 * and {@link {Component#currentHeight}
1906 * @fires Component#resize
1908 * @param {string} widthOrHeight
1909 8 'width' or 'height'
1911 * @param {number|string} [num]
1914 * @param {boolean} [skipListeners]
1915 * Skip resize event trigger
1917 * @return {Component}
1918 * - the dimension when getting or 0 if unset
1919 * - Returns itself when setting; method can be chained.
1923 Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) {
1924 if (num !== undefined) {
1925 // Set to zero if null or literally NaN (NaN !== NaN)
1926 if (num === null || num !== num) {
1930 // Check if using css width/height (% or px) and adjust
1931 if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) {
1932 this.el_.style[widthOrHeight] = num;
1933 } else if (num === 'auto') {
1934 this.el_.style[widthOrHeight] = '';
1936 this.el_.style[widthOrHeight] = num + 'px';
1939 // skipListeners allows us to avoid triggering the resize event when setting both width and height
1940 if (!skipListeners) {
1942 * Triggered when a component is resized.
1944 * @event Component#resize
1945 * @type {EventTarget~Event}
1947 this.trigger('resize');
1954 // Not setting a value, so getting it
1955 // Make sure element exists
1960 // Get dimension value from style
1961 var val = this.el_.style[widthOrHeight];
1962 var pxIndex = val.indexOf('px');
1964 if (pxIndex !== -1) {
1965 // Return the pixel value with no 'px'
1966 return parseInt(val.slice(0, pxIndex), 10);
1969 // No px so using % or no style was set, so falling back to offsetWidth/height
1970 // If component has display:none, offset will return 0
1971 // TODO: handle display:none and no dimension style using px
1972 return parseInt(this.el_['offset' + (0, _toTitleCase2['default'])(widthOrHeight)], 10);
1976 * Get the width or the height of the `Component` elements computed style. Uses
1977 * `window.getComputedStyle`.
1979 * @param {string} widthOrHeight
1980 * A string containing 'width' or 'height'. Whichever one you want to get.
1983 * The dimension that gets asked for or 0 if nothing was set
1984 * for that dimension.
1988 Component.prototype.currentDimension = function currentDimension(widthOrHeight) {
1989 var computedWidthOrHeight = 0;
1991 if (widthOrHeight !== 'width' && widthOrHeight !== 'height') {
1992 throw new Error('currentDimension only accepts width or height value');
1995 if (typeof _window2['default'].getComputedStyle === 'function') {
1996 var computedStyle = _window2['default'].getComputedStyle(this.el_);
1998 computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight];
2001 // remove 'px' from variable and parse as integer
2002 computedWidthOrHeight = parseFloat(computedWidthOrHeight);
2004 // if the computed value is still 0, it's possible that the browser is lying
2005 // and we want to check the offset values.
2006 // This code also runs on IE8 and wherever getComputedStyle doesn't exist.
2007 if (computedWidthOrHeight === 0) {
2008 var rule = 'offset' + (0, _toTitleCase2['default'])(widthOrHeight);
2010 computedWidthOrHeight = this.el_[rule];
2013 return computedWidthOrHeight;
2017 * An object that contains width and height values of the `Component`s
2018 * computed style. Uses `window.getComputedStyle`.
2020 * @typedef {Object} Component~DimensionObject
2022 * @property {number} width
2023 * The width of the `Component`s computed style.
2025 * @property {number} height
2026 * The height of the `Component`s computed style.
2030 * Get an object that contains width and height values of the `Component`s
2033 * @return {Component~DimensionObject}
2034 * The dimensions of the components element
2038 Component.prototype.currentDimensions = function currentDimensions() {
2040 width: this.currentDimension('width'),
2041 height: this.currentDimension('height')
2046 * Get the width of the `Component`s computed style. Uses `window.getComputedStyle`.
2048 * @return {number} width
2049 * The width of the `Component`s computed style.
2053 Component.prototype.currentWidth = function currentWidth() {
2054 return this.currentDimension('width');
2058 * Get the height of the `Component`s computed style. Uses `window.getComputedStyle`.
2060 * @return {number} height
2061 * The height of the `Component`s computed style.
2065 Component.prototype.currentHeight = function currentHeight() {
2066 return this.currentDimension('height');
2070 * Set the focus to this component
2074 Component.prototype.focus = function focus() {
2079 * Remove the focus from this component
2083 Component.prototype.blur = function blur() {
2088 * Emit a 'tap' events when touch event support gets detected. This gets used to
2089 * support toggling the controls through a tap on the video. They get enabled
2090 * because every sub-component would have extra overhead otherwise.
2093 * @fires Component#tap
2094 * @listens Component#touchstart
2095 * @listens Component#touchmove
2096 * @listens Component#touchleave
2097 * @listens Component#touchcancel
2098 * @listens Component#touchend
2102 Component.prototype.emitTapEvents = function emitTapEvents() {
2103 // Track the start time so we can determine how long the touch lasted
2105 var firstTouch = null;
2107 // Maximum movement allowed during a touch event to still be considered a tap
2108 // Other popular libs use anywhere from 2 (hammer.js) to 15,
2109 // so 10 seems like a nice, round number.
2110 var tapMovementThreshold = 10;
2112 // The maximum length a touch can be while still being considered a tap
2113 var touchTimeThreshold = 200;
2115 var couldBeTap = void 0;
2117 this.on('touchstart', function (event) {
2118 // If more than one finger, don't consider treating this as a click
2119 if (event.touches.length === 1) {
2120 // Copy pageX/pageY from the object
2122 pageX: event.touches[0].pageX,
2123 pageY: event.touches[0].pageY
2125 // Record start time so we can detect a tap vs. "touch and hold"
2126 touchStart = new Date().getTime();
2127 // Reset couldBeTap tracking
2132 this.on('touchmove', function (event) {
2133 // If more than one finger, don't consider treating this as a click
2134 if (event.touches.length > 1) {
2136 } else if (firstTouch) {
2137 // Some devices will throw touchmoves for all but the slightest of taps.
2138 // So, if we moved only a small distance, this could still be a tap
2139 var xdiff = event.touches[0].pageX - firstTouch.pageX;
2140 var ydiff = event.touches[0].pageY - firstTouch.pageY;
2141 var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
2143 if (touchDistance > tapMovementThreshold) {
2149 var noTap = function noTap() {
2153 // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s
2154 this.on('touchleave', noTap);
2155 this.on('touchcancel', noTap);
2157 // When the touch ends, measure how long it took and trigger the appropriate
2159 this.on('touchend', function (event) {
2161 // Proceed only if the touchmove/leave/cancel event didn't happen
2162 if (couldBeTap === true) {
2163 // Measure how long the touch lasted
2164 var touchTime = new Date().getTime() - touchStart;
2166 // Make sure the touch was less than the threshold to be considered a tap
2167 if (touchTime < touchTimeThreshold) {
2168 // Don't let browser turn this into a click
2169 event.preventDefault();
2171 * Triggered when a `Component` is tapped.
2173 * @event Component#tap
2174 * @type {EventTarget~Event}
2176 this.trigger('tap');
2177 // It may be good to copy the touchend event object and change the
2178 // type to tap, if the other event properties aren't exact after
2179 // Events.fixEvent runs (e.g. event.target)
2186 * This function reports user activity whenever touch events happen. This can get
2187 * turned off by any sub-components that wants touch events to act another way.
2189 * Report user touch activity when touch events occur. User activity gets used to
2190 * determine when controls should show/hide. It is simple when it comes to mouse
2191 * events, because any mouse event should show the controls. So we capture mouse
2192 * events that bubble up to the player and report activity when that happens.
2193 * With touch events it isn't as easy as `touchstart` and `touchend` toggle player
2194 * controls. So touch events can't help us at the player level either.
2196 * User activity gets checked asynchronously. So what could happen is a tap event
2197 * on the video turns the controls off. Then the `touchend` event bubbles up to
2198 * the player. Which, if it reported user activity, would turn the controls right
2199 * back on. We also don't want to completely block touch events from bubbling up.
2200 * Furthermore a `touchmove` event and anything other than a tap, should not turn
2203 * @listens Component#touchstart
2204 * @listens Component#touchmove
2205 * @listens Component#touchend
2206 * @listens Component#touchcancel
2210 Component.prototype.enableTouchActivity = function enableTouchActivity() {
2211 // Don't continue if the root player doesn't support reporting user activity
2212 if (!this.player() || !this.player().reportUserActivity) {
2216 // listener for reporting that the user is active
2217 var report = Fn.bind(this.player(), this.player().reportUserActivity);
2219 var touchHolding = void 0;
2221 this.on('touchstart', function () {
2223 // For as long as the they are touching the device or have their mouse down,
2224 // we consider them active even if they're not moving their finger or mouse.
2225 // So we want to continue to update that they are active
2226 this.clearInterval(touchHolding);
2227 // report at the same interval as activityCheck
2228 touchHolding = this.setInterval(report, 250);
2231 var touchEnd = function touchEnd(event) {
2233 // stop the interval that maintains activity if the touch is holding
2234 this.clearInterval(touchHolding);
2237 this.on('touchmove', report);
2238 this.on('touchend', touchEnd);
2239 this.on('touchcancel', touchEnd);
2243 * A callback that has no parameters and is bound into `Component`s context.
2245 * @callback Component~GenericCallback
2250 * Creates a function that runs after an `x` millisecond timeout. This function is a
2251 * wrapper around `window.setTimeout`. There are a few reasons to use this one
2253 * 1. It gets cleared via {@link Component#clearTimeout} when
2254 * {@link Component#dispose} gets called.
2255 * 2. The function callback will gets turned into a {@link Component~GenericCallback}
2257 * > Note: You can use `window.clearTimeout` on the id returned by this function. This
2258 * will cause its dispose listener not to get cleaned up! Please use
2259 * {@link Component#clearTimeout} or {@link Component#dispose}.
2261 * @param {Component~GenericCallback} fn
2262 * The function that will be run after `timeout`.
2264 * @param {number} timeout
2265 * Timeout in milliseconds to delay before executing the specified function.
2268 * Returns a timeout ID that gets used to identify the timeout. It can also
2269 * get used in {@link Component#clearTimeout} to clear the timeout that
2272 * @listens Component#dispose
2273 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout}
2277 Component.prototype.setTimeout = function setTimeout(fn, timeout) {
2278 fn = Fn.bind(this, fn);
2280 var timeoutId = _window2['default'].setTimeout(fn, timeout);
2281 var disposeFn = function disposeFn() {
2282 this.clearTimeout(timeoutId);
2285 disposeFn.guid = 'vjs-timeout-' + timeoutId;
2287 this.on('dispose', disposeFn);
2293 * Clears a timeout that gets created via `window.setTimeout` or
2294 * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout}
2295 * use this function instead of `window.clearTimout`. If you don't your dispose
2296 * listener will not get cleaned up until {@link Component#dispose}!
2298 * @param {number} timeoutId
2299 * The id of the timeout to clear. The return value of
2300 * {@link Component#setTimeout} or `window.setTimeout`.
2303 * Returns the timeout id that was cleared.
2305 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout}
2309 Component.prototype.clearTimeout = function clearTimeout(timeoutId) {
2310 _window2['default'].clearTimeout(timeoutId);
2312 var disposeFn = function disposeFn() {};
2314 disposeFn.guid = 'vjs-timeout-' + timeoutId;
2316 this.off('dispose', disposeFn);
2322 * Creates a function that gets run every `x` milliseconds. This function is a wrapper
2323 * around `window.setInterval`. There are a few reasons to use this one instead though.
2324 * 1. It gets cleared via {@link Component#clearInterval} when
2325 * {@link Component#dispose} gets called.
2326 * 2. The function callback will be a {@link Component~GenericCallback}
2328 * @param {Component~GenericCallback} fn
2329 * The function to run every `x` seconds.
2331 * @param {number} interval
2332 * Execute the specified function every `x` milliseconds.
2335 * Returns an id that can be used to identify the interval. It can also be be used in
2336 * {@link Component#clearInterval} to clear the interval.
2338 * @listens Component#dispose
2339 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval}
2343 Component.prototype.setInterval = function setInterval(fn, interval) {
2344 fn = Fn.bind(this, fn);
2346 var intervalId = _window2['default'].setInterval(fn, interval);
2348 var disposeFn = function disposeFn() {
2349 this.clearInterval(intervalId);
2352 disposeFn.guid = 'vjs-interval-' + intervalId;
2354 this.on('dispose', disposeFn);
2360 * Clears an interval that gets created via `window.setInterval` or
2361 * {@link Component#setInterval}. If you set an inteval via {@link Component#setInterval}
2362 * use this function instead of `window.clearInterval`. If you don't your dispose
2363 * listener will not get cleaned up until {@link Component#dispose}!
2365 * @param {number} intervalId
2366 * The id of the interval to clear. The return value of
2367 * {@link Component#setInterval} or `window.setInterval`.
2370 * Returns the interval id that was cleared.
2372 * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval}
2376 Component.prototype.clearInterval = function clearInterval(intervalId) {
2377 _window2['default'].clearInterval(intervalId);
2379 var disposeFn = function disposeFn() {};
2381 disposeFn.guid = 'vjs-interval-' + intervalId;
2383 this.off('dispose', disposeFn);
2389 * Register a `Component` with `videojs` given the name and the component.
2391 * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s
2392 * should be registered using {@link Tech.registerTech} or
2393 * {@link videojs:videojs.registerTech}.
2395 * > NOTE: This function can also be seen on videojs as
2396 * {@link videojs:videojs.registerComponent}.
2398 * @param {string} name
2399 * The name of the `Component` to register.
2401 * @param {Component} comp
2402 * The `Component` class to register.
2404 * @return {Component}
2405 * The `Component` that was registered.
2409 Component.registerComponent = function registerComponent(name, comp) {
2414 name = (0, _toTitleCase2['default'])(name);
2416 if (!Component.components_) {
2417 Component.components_ = {};
2420 if (name === 'Player' && Component.components_[name]) {
2421 var Player = Component.components_[name];
2423 // If we have players that were disposed, then their name will still be
2424 // in Players.players. So, we must loop through and verify that the value
2425 // for each item is not null. This allows registration of the Player component
2426 // after all players have been disposed or before any were created.
2427 if (Player.players && Object.keys(Player.players).length > 0 && Object.keys(Player.players).map(function (playerName) {
2428 return Player.players[playerName];
2429 }).every(Boolean)) {
2430 throw new Error('Can not register Player component after player has been created');
2434 Component.components_[name] = comp;
2440 * Get a `Component` based on the name it was registered with.
2442 * @param {string} name
2443 * The Name of the component to get.
2445 * @return {Component}
2446 * The `Component` that got registered under the given name.
2448 * @deprecated In `videojs` 6 this will not return `Component`s that were not
2449 * registered using {@link Component.registerComponent}. Currently we
2450 * check the global `videojs` object for a `Component` name and
2451 * return that if it exists.
2455 Component.getComponent = function getComponent(name) {
2460 name = (0, _toTitleCase2['default'])(name);
2462 if (Component.components_ && Component.components_[name]) {
2463 return Component.components_[name];
2466 if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) {
2467 _log2['default'].warn('The ' + name + ' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)');
2469 return _window2['default'].videojs[name];
2474 * Sets up the constructor using the supplied init method or uses the init of the
2477 * @param {Object} [props={}]
2478 * An object of properties.
2481 * the extended object.
2483 * @deprecated since version 5
2487 Component.extend = function extend(props) {
2488 props = props || {};
2490 _log2['default'].warn('Component.extend({}) has been deprecated, ' + ' use videojs.extend(Component, {}) instead');
2492 // Set up the constructor using the supplied init method
2493 // or using the init of the parent object
2494 // Make sure to check the unobfuscated version for external libs
2495 var init = props.init || props.init || this.prototype.init || this.prototype.init || function () {};
2496 // In Resig's simple class inheritance (previously used) the constructor
2497 // is a function that calls `this.init.apply(arguments)`
2498 // However that would prevent us from using `ParentObject.call(this);`
2499 // in a Child constructor because the `this` in `this.init`
2500 // would still refer to the Child and cause an infinite loop.
2501 // We would instead have to do
2502 // `ParentObject.prototype.init.apply(this, arguments);`
2503 // Bleh. We're not creating a _super() function, so it's good to keep
2504 // the parent constructor reference simple.
2505 var subObj = function subObj() {
2506 init.apply(this, arguments);
2509 // Inherit from this object's prototype
2510 subObj.prototype = Object.create(this.prototype);
2511 // Reset the constructor property for subObj otherwise
2512 // instances of subObj would have the constructor of the parent Object
2513 subObj.prototype.constructor = subObj;
2515 // Make the class extendable
2516 subObj.extend = Component.extend;
2518 // Extend subObj's prototype with functions and other properties from props
2519 for (var name in props) {
2520 if (props.hasOwnProperty(name)) {
2521 subObj.prototype[name] = props[name];
2531 Component.registerComponent('Component', Component);
2532 exports['default'] = Component;
2534 },{"81":81,"82":82,"83":83,"85":85,"86":86,"87":87,"91":91,"95":95}],6:[function(_dereq_,module,exports){
2537 exports.__esModule = true;
2539 var _trackButton = _dereq_(36);
2541 var _trackButton2 = _interopRequireDefault(_trackButton);
2543 var _component = _dereq_(5);
2545 var _component2 = _interopRequireDefault(_component);
2547 var _audioTrackMenuItem = _dereq_(7);
2549 var _audioTrackMenuItem2 = _interopRequireDefault(_audioTrackMenuItem);
2551 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2553 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2555 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; }
2557 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; } /**
2558 * @file audio-track-button.js
2563 * The base class for buttons that toggle specific {@link AudioTrack} types.
2565 * @extends TrackButton
2567 var AudioTrackButton = function (_TrackButton) {
2568 _inherits(AudioTrackButton, _TrackButton);
2571 * Creates an instance of this class.
2573 * @param {Player} player
2574 * The `Player` that this class should be attached to.
2576 * @param {Object} [options={}]
2577 * The key/value store of player options.
2579 function AudioTrackButton(player) {
2580 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2582 _classCallCheck(this, AudioTrackButton);
2584 options.tracks = player.audioTracks && player.audioTracks();
2586 var _this = _possibleConstructorReturn(this, _TrackButton.call(this, player, options));
2588 _this.el_.setAttribute('aria-label', 'Audio Menu');
2593 * Builds the default DOM `className`.
2596 * The DOM `className` for this object.
2600 AudioTrackButton.prototype.buildCSSClass = function buildCSSClass() {
2601 return 'vjs-audio-button ' + _TrackButton.prototype.buildCSSClass.call(this);
2605 * Create a menu item for each audio track
2607 * @param {AudioTrackMenuItem[]} [items=[]]
2608 * An array of existing menu items to use.
2610 * @return {AudioTrackMenuItem[]}
2611 * An array of menu items
2615 AudioTrackButton.prototype.createItems = function createItems() {
2616 var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
2618 // if there's only one audio track, there no point in showing it
2619 this.hideThreshold_ = 1;
2621 var tracks = this.player_.audioTracks && this.player_.audioTracks();
2627 for (var i = 0; i < tracks.length; i++) {
2628 var track = tracks[i];
2630 items.push(new _audioTrackMenuItem2['default'](this.player_, {
2632 // MenuItem is selectable
2640 return AudioTrackButton;
2641 }(_trackButton2['default']);
2644 * The text that should display over the `AudioTrackButton`s controls. Added for localization.
2651 AudioTrackButton.prototype.controlText_ = 'Audio Track';
2652 _component2['default'].registerComponent('AudioTrackButton', AudioTrackButton);
2653 exports['default'] = AudioTrackButton;
2655 },{"36":36,"5":5,"7":7}],7:[function(_dereq_,module,exports){
2658 exports.__esModule = true;
2660 var _menuItem = _dereq_(48);
2662 var _menuItem2 = _interopRequireDefault(_menuItem);
2664 var _component = _dereq_(5);
2666 var _component2 = _interopRequireDefault(_component);
2668 var _fn = _dereq_(83);
2670 var Fn = _interopRequireWildcard(_fn);
2672 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; } }
2674 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2676 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2678 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; }
2680 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; } /**
2681 * @file audio-track-menu-item.js
2686 * An {@link AudioTrack} {@link MenuItem}
2690 var AudioTrackMenuItem = function (_MenuItem) {
2691 _inherits(AudioTrackMenuItem, _MenuItem);
2694 * Creates an instance of this class.
2696 * @param {Player} player
2697 * The `Player` that this class should be attached to.
2699 * @param {Object} [options]
2700 * The key/value store of player options.
2702 function AudioTrackMenuItem(player, options) {
2703 _classCallCheck(this, AudioTrackMenuItem);
2705 var track = options.track;
2706 var tracks = player.audioTracks();
2708 // Modify options for parent MenuItem class's init.
2709 options.label = track.label || track.language || 'Unknown';
2710 options.selected = track.enabled;
2712 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
2714 _this.track = track;
2717 var changeHandler = Fn.bind(_this, _this.handleTracksChange);
2719 tracks.addEventListener('change', changeHandler);
2720 _this.on('dispose', function () {
2721 tracks.removeEventListener('change', changeHandler);
2728 * This gets called when an `AudioTrackMenuItem is "clicked". See {@link ClickableComponent}
2729 * for more detailed information on what a click can be.
2731 * @param {EventTarget~Event} [event]
2732 * The `keydown`, `tap`, or `click` event that caused this function to be
2740 AudioTrackMenuItem.prototype.handleClick = function handleClick(event) {
2741 var tracks = this.player_.audioTracks();
2743 _MenuItem.prototype.handleClick.call(this, event);
2749 for (var i = 0; i < tracks.length; i++) {
2750 var track = tracks[i];
2752 track.enabled = track === this.track;
2757 * Handle any {@link AudioTrack} change.
2759 * @param {EventTarget~Event} [event]
2760 * The {@link AudioTrackList#change} event that caused this to run.
2762 * @listens AudioTrackList#change
2766 AudioTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
2767 this.selected(this.track.enabled);
2770 return AudioTrackMenuItem;
2771 }(_menuItem2['default']);
2773 _component2['default'].registerComponent('AudioTrackMenuItem', AudioTrackMenuItem);
2774 exports['default'] = AudioTrackMenuItem;
2776 },{"48":48,"5":5,"83":83}],8:[function(_dereq_,module,exports){
2779 exports.__esModule = true;
2781 var _component = _dereq_(5);
2783 var _component2 = _interopRequireDefault(_component);
2821 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2823 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2825 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; }
2827 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; } /**
2828 * @file control-bar.js
2832 // Required children
2836 * Container of main controls.
2838 * @extends Component
2840 var ControlBar = function (_Component) {
2841 _inherits(ControlBar, _Component);
2843 function ControlBar() {
2844 _classCallCheck(this, ControlBar);
2846 return _possibleConstructorReturn(this, _Component.apply(this, arguments));
2850 * Create the `Component`'s DOM element
2853 * The element that was created.
2855 ControlBar.prototype.createEl = function createEl() {
2856 return _Component.prototype.createEl.call(this, 'div', {
2857 className: 'vjs-control-bar',
2860 // The control bar is a group, so it can contain menuitems
2866 }(_component2['default']);
2869 * Default options for `ControlBar`
2876 ControlBar.prototype.options_ = {
2877 children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subtitlesButton', 'captionsButton', 'audioTrackButton', 'fullscreenToggle']
2880 _component2['default'].registerComponent('ControlBar', ControlBar);
2881 exports['default'] = ControlBar;
2883 },{"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){
2886 exports.__esModule = true;
2888 var _button = _dereq_(2);
2890 var _button2 = _interopRequireDefault(_button);
2892 var _component = _dereq_(5);
2894 var _component2 = _interopRequireDefault(_component);
2896 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
2898 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2900 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; }
2902 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; } /**
2903 * @file fullscreen-toggle.js
2908 * Toggle fullscreen video
2912 var FullscreenToggle = function (_Button) {
2913 _inherits(FullscreenToggle, _Button);
2916 * Creates an instance of this class.
2918 * @param {Player} player
2919 * The `Player` that this class should be attached to.
2921 * @param {Object} [options]
2922 * The key/value store of player options.
2924 function FullscreenToggle(player, options) {
2925 _classCallCheck(this, FullscreenToggle);
2927 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
2929 _this.on(player, 'fullscreenchange', _this.handleFullscreenChange);
2934 * Builds the default DOM `className`.
2937 * The DOM `className` for this object.
2941 FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() {
2942 return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this);
2946 * Handles fullscreenchange on the player and change control text accordingly.
2948 * @param {EventTarget~Event} [event]
2949 * The {@link Player#fullscreenchange} event that caused this function to be
2952 * @listens Player#fullscreenchange
2956 FullscreenToggle.prototype.handleFullscreenChange = function handleFullscreenChange(event) {
2957 if (this.player_.isFullscreen()) {
2958 this.controlText('Non-Fullscreen');
2960 this.controlText('Fullscreen');
2965 * This gets called when an `FullscreenToggle` is "clicked". See
2966 * {@link ClickableComponent} for more detailed information on what a click can be.
2968 * @param {EventTarget~Event} [event]
2969 * The `keydown`, `tap`, or `click` event that caused this function to be
2977 FullscreenToggle.prototype.handleClick = function handleClick(event) {
2978 if (!this.player_.isFullscreen()) {
2979 this.player_.requestFullscreen();
2981 this.player_.exitFullscreen();
2985 return FullscreenToggle;
2986 }(_button2['default']);
2989 * The text that should display over the `FullscreenToggle`s controls. Added for localization.
2996 FullscreenToggle.prototype.controlText_ = 'Fullscreen';
2998 _component2['default'].registerComponent('FullscreenToggle', FullscreenToggle);
2999 exports['default'] = FullscreenToggle;
3001 },{"2":2,"5":5}],10:[function(_dereq_,module,exports){
3004 exports.__esModule = true;
3006 var _component = _dereq_(5);
3008 var _component2 = _interopRequireDefault(_component);
3010 var _dom = _dereq_(81);
3012 var Dom = _interopRequireWildcard(_dom);
3014 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; } }
3016 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3018 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3020 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; }
3022 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; } /**
3023 * @file live-display.js
3027 // TODO - Future make it click to snap to live
3030 * Displays the live indicator when duration is Infinity.
3032 * @extends Component
3034 var LiveDisplay = function (_Component) {
3035 _inherits(LiveDisplay, _Component);
3038 * Creates an instance of this class.
3040 * @param {Player} player
3041 * The `Player` that this class should be attached to.
3043 * @param {Object} [options]
3044 * The key/value store of player options.
3046 function LiveDisplay(player, options) {
3047 _classCallCheck(this, LiveDisplay);
3049 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
3051 _this.updateShowing();
3052 _this.on(_this.player(), 'durationchange', _this.updateShowing);
3057 * Create the `Component`'s DOM element
3060 * The element that was created.
3064 LiveDisplay.prototype.createEl = function createEl() {
3065 var el = _Component.prototype.createEl.call(this, 'div', {
3066 className: 'vjs-live-control vjs-control'
3069 this.contentEl_ = Dom.createEl('div', {
3070 className: 'vjs-live-display',
3071 innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE')
3076 el.appendChild(this.contentEl_);
3081 * Check the duration to see if the LiveDisplay should be showing or not. Then show/hide
3084 * @param {EventTarget~Event} [event]
3085 * The {@link Player#durationchange} event that caused this function to run.
3087 * @listens Player#durationchange
3091 LiveDisplay.prototype.updateShowing = function updateShowing(event) {
3092 if (this.player().duration() === Infinity) {
3100 }(_component2['default']);
3102 _component2['default'].registerComponent('LiveDisplay', LiveDisplay);
3103 exports['default'] = LiveDisplay;
3105 },{"5":5,"81":81}],11:[function(_dereq_,module,exports){
3108 exports.__esModule = true;
3110 var _button = _dereq_(2);
3112 var _button2 = _interopRequireDefault(_button);
3114 var _component = _dereq_(5);
3116 var _component2 = _interopRequireDefault(_component);
3118 var _dom = _dereq_(81);
3120 var Dom = _interopRequireWildcard(_dom);
3122 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; } }
3124 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3126 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3128 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; }
3130 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; } /**
3131 * @file mute-toggle.js
3136 * A button component for muting the audio.
3140 var MuteToggle = function (_Button) {
3141 _inherits(MuteToggle, _Button);
3144 * Creates an instance of this class.
3146 * @param {Player} player
3147 * The `Player` that this class should be attached to.
3149 * @param {Object} [options]
3150 * The key/value store of player options.
3152 function MuteToggle(player, options) {
3153 _classCallCheck(this, MuteToggle);
3155 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
3157 _this.on(player, 'volumechange', _this.update);
3159 // hide mute toggle if the current tech doesn't support volume control
3160 if (player.tech_ && player.tech_.featuresVolumeControl === false) {
3161 _this.addClass('vjs-hidden');
3164 _this.on(player, 'loadstart', function () {
3165 // We need to update the button to account for a default muted state.
3168 if (player.tech_.featuresVolumeControl === false) {
3169 this.addClass('vjs-hidden');
3171 this.removeClass('vjs-hidden');
3178 * Builds the default DOM `className`.
3181 * The DOM `className` for this object.
3185 MuteToggle.prototype.buildCSSClass = function buildCSSClass() {
3186 return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this);
3190 * This gets called when an `MuteToggle` is "clicked". See
3191 * {@link ClickableComponent} for more detailed information on what a click can be.
3193 * @param {EventTarget~Event} [event]
3194 * The `keydown`, `tap`, or `click` event that caused this function to be
3202 MuteToggle.prototype.handleClick = function handleClick(event) {
3203 this.player_.muted(this.player_.muted() ? false : true);
3207 * Update the state of volume.
3209 * @param {EventTarget~Event} [event]
3210 * The {@link Player#loadstart} event if this function was called through an
3213 * @listens Player#loadstart
3217 MuteToggle.prototype.update = function update(event) {
3218 var vol = this.player_.volume();
3221 if (vol === 0 || this.player_.muted()) {
3223 } else if (vol < 0.33) {
3225 } else if (vol < 0.67) {
3229 // Don't rewrite the button text if the actual text doesn't change.
3230 // This causes unnecessary and confusing information for screen reader users.
3231 // This check is needed because this function gets called every time the volume level is changed.
3232 var toMute = this.player_.muted() ? 'Unmute' : 'Mute';
3234 if (this.controlText() !== toMute) {
3235 this.controlText(toMute);
3238 // TODO improve muted icon classes
3239 for (var i = 0; i < 4; i++) {
3240 Dom.removeElClass(this.el_, 'vjs-vol-' + i);
3242 Dom.addElClass(this.el_, 'vjs-vol-' + level);
3246 }(_button2['default']);
3249 * The text that should display over the `MuteToggle`s controls. Added for localization.
3256 MuteToggle.prototype.controlText_ = 'Mute';
3258 _component2['default'].registerComponent('MuteToggle', MuteToggle);
3259 exports['default'] = MuteToggle;
3261 },{"2":2,"5":5,"81":81}],12:[function(_dereq_,module,exports){
3264 exports.__esModule = true;
3266 var _button = _dereq_(2);
3268 var _button2 = _interopRequireDefault(_button);
3270 var _component = _dereq_(5);
3272 var _component2 = _interopRequireDefault(_component);
3274 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3276 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3278 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; }
3280 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; } /**
3281 * @file play-toggle.js
3286 * Button to toggle between play and pause.
3290 var PlayToggle = function (_Button) {
3291 _inherits(PlayToggle, _Button);
3294 * Creates an instance of this class.
3296 * @param {Player} player
3297 * The `Player` that this class should be attached to.
3299 * @param {Object} [options]
3300 * The key/value store of player options.
3302 function PlayToggle(player, options) {
3303 _classCallCheck(this, PlayToggle);
3305 var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
3307 _this.on(player, 'play', _this.handlePlay);
3308 _this.on(player, 'pause', _this.handlePause);
3313 * Builds the default DOM `className`.
3316 * The DOM `className` for this object.
3320 PlayToggle.prototype.buildCSSClass = function buildCSSClass() {
3321 return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this);
3325 * This gets called when an `PlayToggle` is "clicked". See
3326 * {@link ClickableComponent} for more detailed information on what a click can be.
3328 * @param {EventTarget~Event} [event]
3329 * The `keydown`, `tap`, or `click` event that caused this function to be
3337 PlayToggle.prototype.handleClick = function handleClick(event) {
3338 if (this.player_.paused()) {
3339 this.player_.play();
3341 this.player_.pause();
3346 * Add the vjs-playing class to the element so it can change appearance.
3348 * @param {EventTarget~Event} [event]
3349 * The event that caused this function to run.
3351 * @listens Player#play
3355 PlayToggle.prototype.handlePlay = function handlePlay(event) {
3356 this.removeClass('vjs-paused');
3357 this.addClass('vjs-playing');
3358 // change the button text to "Pause"
3359 this.controlText('Pause');
3363 * Add the vjs-paused class to the element so it can change appearance.
3365 * @param {EventTarget~Event} [event]
3366 * The event that caused this function to run.
3368 * @listens Player#pause
3372 PlayToggle.prototype.handlePause = function handlePause(event) {
3373 this.removeClass('vjs-playing');
3374 this.addClass('vjs-paused');
3375 // change the button text to "Play"
3376 this.controlText('Play');
3380 }(_button2['default']);
3383 * The text that should display over the `PlayToggle`s controls. Added for localization.
3390 PlayToggle.prototype.controlText_ = 'Play';
3392 _component2['default'].registerComponent('PlayToggle', PlayToggle);
3393 exports['default'] = PlayToggle;
3395 },{"2":2,"5":5}],13:[function(_dereq_,module,exports){
3398 exports.__esModule = true;
3400 var _menuButton = _dereq_(47);
3402 var _menuButton2 = _interopRequireDefault(_menuButton);
3404 var _menu = _dereq_(49);
3406 var _menu2 = _interopRequireDefault(_menu);
3408 var _playbackRateMenuItem = _dereq_(14);
3410 var _playbackRateMenuItem2 = _interopRequireDefault(_playbackRateMenuItem);
3412 var _component = _dereq_(5);
3414 var _component2 = _interopRequireDefault(_component);
3416 var _dom = _dereq_(81);
3418 var Dom = _interopRequireWildcard(_dom);
3420 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; } }
3422 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3424 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3426 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; }
3428 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; } /**
3429 * @file playback-rate-menu-button.js
3434 * The component for controlling the playback rate.
3436 * @extends MenuButton
3438 var PlaybackRateMenuButton = function (_MenuButton) {
3439 _inherits(PlaybackRateMenuButton, _MenuButton);
3442 * Creates an instance of this class.
3444 * @param {Player} player
3445 * The `Player` that this class should be attached to.
3447 * @param {Object} [options]
3448 * The key/value store of player options.
3450 function PlaybackRateMenuButton(player, options) {
3451 _classCallCheck(this, PlaybackRateMenuButton);
3453 var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options));
3455 _this.updateVisibility();
3456 _this.updateLabel();
3458 _this.on(player, 'loadstart', _this.updateVisibility);
3459 _this.on(player, 'ratechange', _this.updateLabel);
3464 * Create the `Component`'s DOM element
3467 * The element that was created.
3471 PlaybackRateMenuButton.prototype.createEl = function createEl() {
3472 var el = _MenuButton.prototype.createEl.call(this);
3474 this.labelEl_ = Dom.createEl('div', {
3475 className: 'vjs-playback-rate-value',
3479 el.appendChild(this.labelEl_);
3485 * Builds the default DOM `className`.
3488 * The DOM `className` for this object.
3492 PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() {
3493 return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this);
3497 * Create the playback rate menu
3500 * Menu object populated with {@link PlaybackRateMenuItem}s
3504 PlaybackRateMenuButton.prototype.createMenu = function createMenu() {
3505 var menu = new _menu2['default'](this.player());
3506 var rates = this.playbackRates();
3509 for (var i = rates.length - 1; i >= 0; i--) {
3510 menu.addChild(new _playbackRateMenuItem2['default'](this.player(), { rate: rates[i] + 'x' }));
3518 * Updates ARIA accessibility attributes
3522 PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() {
3523 // Current playback rate
3524 this.el().setAttribute('aria-valuenow', this.player().playbackRate());
3528 * This gets called when an `PlaybackRateMenuButton` is "clicked". See
3529 * {@link ClickableComponent} for more detailed information on what a click can be.
3531 * @param {EventTarget~Event} [event]
3532 * The `keydown`, `tap`, or `click` event that caused this function to be
3540 PlaybackRateMenuButton.prototype.handleClick = function handleClick(event) {
3541 // select next rate option
3542 var currentRate = this.player().playbackRate();
3543 var rates = this.playbackRates();
3545 // this will select first one if the last one currently selected
3546 var newRate = rates[0];
3548 for (var i = 0; i < rates.length; i++) {
3549 if (rates[i] > currentRate) {
3554 this.player().playbackRate(newRate);
3558 * Get possible playback rates
3561 * All possible playback rates
3565 PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() {
3566 return this.options_.playbackRates || this.options_.playerOptions && this.options_.playerOptions.playbackRates;
3570 * Get whether playback rates is supported by the tech
3571 * and an array of playback rates exists
3574 * Whether changing playback rate is supported
3578 PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() {
3579 return this.player().tech_ && this.player().tech_.featuresPlaybackRate && this.playbackRates() && this.playbackRates().length > 0;
3583 * Hide playback rate controls when they're no playback rate options to select
3585 * @param {EventTarget~Event} [event]
3586 * The event that caused this function to run.
3588 * @listens Player#loadstart
3592 PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility(event) {
3593 if (this.playbackRateSupported()) {
3594 this.removeClass('vjs-hidden');
3596 this.addClass('vjs-hidden');
3601 * Update button label when rate changed
3603 * @param {EventTarget~Event} [event]
3604 * The event that caused this function to run.
3606 * @listens Player#ratechange
3610 PlaybackRateMenuButton.prototype.updateLabel = function updateLabel(event) {
3611 if (this.playbackRateSupported()) {
3612 this.labelEl_.innerHTML = this.player().playbackRate() + 'x';
3616 return PlaybackRateMenuButton;
3617 }(_menuButton2['default']);
3620 * The text that should display over the `FullscreenToggle`s controls. Added for localization.
3627 PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate';
3629 _component2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton);
3630 exports['default'] = PlaybackRateMenuButton;
3632 },{"14":14,"47":47,"49":49,"5":5,"81":81}],14:[function(_dereq_,module,exports){
3635 exports.__esModule = true;
3637 var _menuItem = _dereq_(48);
3639 var _menuItem2 = _interopRequireDefault(_menuItem);
3641 var _component = _dereq_(5);
3643 var _component2 = _interopRequireDefault(_component);
3645 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3647 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3649 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; }
3651 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; } /**
3652 * @file playback-rate-menu-item.js
3657 * The specific menu item type for selecting a playback rate.
3661 var PlaybackRateMenuItem = function (_MenuItem) {
3662 _inherits(PlaybackRateMenuItem, _MenuItem);
3665 * Creates an instance of this class.
3667 * @param {Player} player
3668 * The `Player` that this class should be attached to.
3670 * @param {Object} [options]
3671 * The key/value store of player options.
3673 function PlaybackRateMenuItem(player, options) {
3674 _classCallCheck(this, PlaybackRateMenuItem);
3676 var label = options.rate;
3677 var rate = parseFloat(label, 10);
3679 // Modify options for parent MenuItem class's init.
3680 options.label = label;
3681 options.selected = rate === 1;
3682 options.selectable = true;
3684 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
3686 _this.label = label;
3689 _this.on(player, 'ratechange', _this.update);
3694 * This gets called when an `PlaybackRateMenuItem` is "clicked". See
3695 * {@link ClickableComponent} for more detailed information on what a click can be.
3697 * @param {EventTarget~Event} [event]
3698 * The `keydown`, `tap`, or `click` event that caused this function to be
3706 PlaybackRateMenuItem.prototype.handleClick = function handleClick(event) {
3707 _MenuItem.prototype.handleClick.call(this);
3708 this.player().playbackRate(this.rate);
3712 * Update the PlaybackRateMenuItem when the playbackrate changes.
3714 * @param {EventTarget~Event} [event]
3715 * The `ratechange` event that caused this function to run.
3717 * @listens Player#ratechange
3721 PlaybackRateMenuItem.prototype.update = function update(event) {
3722 this.selected(this.player().playbackRate() === this.rate);
3725 return PlaybackRateMenuItem;
3726 }(_menuItem2['default']);
3729 * The text that should display over the `PlaybackRateMenuItem`s controls. Added for localization.
3736 PlaybackRateMenuItem.prototype.contentElType = 'button';
3738 _component2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem);
3739 exports['default'] = PlaybackRateMenuItem;
3741 },{"48":48,"5":5}],15:[function(_dereq_,module,exports){
3744 exports.__esModule = true;
3746 var _component = _dereq_(5);
3748 var _component2 = _interopRequireDefault(_component);
3750 var _dom = _dereq_(81);
3752 var Dom = _interopRequireWildcard(_dom);
3754 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; } }
3756 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3758 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3760 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; }
3762 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; } /**
3763 * @file load-progress-bar.js
3768 * Shows loading progress
3770 * @extends Component
3772 var LoadProgressBar = function (_Component) {
3773 _inherits(LoadProgressBar, _Component);
3776 * Creates an instance of this class.
3778 * @param {Player} player
3779 * The `Player` that this class should be attached to.
3781 * @param {Object} [options]
3782 * The key/value store of player options.
3784 function LoadProgressBar(player, options) {
3785 _classCallCheck(this, LoadProgressBar);
3787 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
3789 _this.partEls_ = [];
3790 _this.on(player, 'progress', _this.update);
3795 * Create the `Component`'s DOM element
3798 * The element that was created.
3802 LoadProgressBar.prototype.createEl = function createEl() {
3803 return _Component.prototype.createEl.call(this, 'div', {
3804 className: 'vjs-load-progress',
3805 innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>'
3810 * Update progress bar
3812 * @param {EventTarget~Event} [event]
3813 * The `progress` event that caused this function to run.
3815 * @listens Player#progress
3819 LoadProgressBar.prototype.update = function update(event) {
3820 var buffered = this.player_.buffered();
3821 var duration = this.player_.duration();
3822 var bufferedEnd = this.player_.bufferedEnd();
3823 var children = this.partEls_;
3825 // get the percent width of a time compared to the total end
3826 var percentify = function percentify(time, end) {
3828 var percent = time / end || 0;
3830 return (percent >= 1 ? 1 : percent) * 100 + '%';
3833 // update the width of the progress bar
3834 this.el_.style.width = percentify(bufferedEnd, duration);
3836 // add child elements to represent the individual buffered time ranges
3837 for (var i = 0; i < buffered.length; i++) {
3838 var start = buffered.start(i);
3839 var end = buffered.end(i);
3840 var part = children[i];
3843 part = this.el_.appendChild(Dom.createEl());
3847 // set the percent based on the width of the progress bar (bufferedEnd)
3848 part.style.left = percentify(start, bufferedEnd);
3849 part.style.width = percentify(end - start, bufferedEnd);
3852 // remove unused buffered range elements
3853 for (var _i = children.length; _i > buffered.length; _i--) {
3854 this.el_.removeChild(children[_i - 1]);
3856 children.length = buffered.length;
3859 return LoadProgressBar;
3860 }(_component2['default']);
3862 _component2['default'].registerComponent('LoadProgressBar', LoadProgressBar);
3863 exports['default'] = LoadProgressBar;
3865 },{"5":5,"81":81}],16:[function(_dereq_,module,exports){
3868 exports.__esModule = true;
3870 var _component = _dereq_(5);
3872 var _component2 = _interopRequireDefault(_component);
3874 var _dom = _dereq_(81);
3876 var Dom = _interopRequireWildcard(_dom);
3878 var _fn = _dereq_(83);
3880 var Fn = _interopRequireWildcard(_fn);
3882 var _formatTime = _dereq_(84);
3884 var _formatTime2 = _interopRequireDefault(_formatTime);
3886 var _computedStyle = _dereq_(80);
3888 var _computedStyle2 = _interopRequireDefault(_computedStyle);
3890 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; } }
3892 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
3894 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3896 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; }
3898 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; } /**
3899 * @file mouse-time-display.js
3904 * The Mouse Time Display component shows the time you will seek to
3905 * when hovering over the progress bar
3907 * @extends Component
3909 var MouseTimeDisplay = function (_Component) {
3910 _inherits(MouseTimeDisplay, _Component);
3913 * Creates an instance of this class.
3915 * @param {Player} player
3916 * The `Player` that this class should be attached to.
3918 * @param {Object} [options]
3919 * The key/value store of player options.
3921 function MouseTimeDisplay(player, options) {
3922 _classCallCheck(this, MouseTimeDisplay);
3924 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
3926 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
3927 _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
3930 if (_this.keepTooltipsInside) {
3931 _this.tooltip = Dom.createEl('div', { className: 'vjs-time-tooltip' });
3932 _this.el().appendChild(_this.tooltip);
3933 _this.addClass('vjs-keep-tooltips-inside');
3938 player.on('ready', function () {
3939 _this.on(player.controlBar.progressControl.el(), 'mousemove', Fn.throttle(Fn.bind(_this, _this.handleMouseMove), 25));
3945 * Create the `Component`'s DOM element
3948 * The element that was created.
3952 MouseTimeDisplay.prototype.createEl = function createEl() {
3953 return _Component.prototype.createEl.call(this, 'div', {
3954 className: 'vjs-mouse-display'
3959 * Handle the mouse move event on the `MouseTimeDisplay`.
3961 * @param {EventTarget~Event} event
3962 * The `mousemove` event that caused this to event to run.
3968 MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) {
3969 var duration = this.player_.duration();
3970 var newTime = this.calculateDistance(event) * duration;
3971 var position = event.pageX - Dom.findElPosition(this.el().parentNode).left;
3973 this.update(newTime, position);
3977 * Update the time and posistion of the `MouseTimeDisplay`.
3979 * @param {number} newTime
3980 * Time to change the `MouseTimeDisplay` to.
3982 * @param {nubmer} position
3983 * Postion from the left of the in pixels.
3987 MouseTimeDisplay.prototype.update = function update(newTime, position) {
3988 var time = (0, _formatTime2['default'])(newTime, this.player_.duration());
3990 this.el().style.left = position + 'px';
3991 this.el().setAttribute('data-current-time', time);
3993 if (this.keepTooltipsInside) {
3994 var clampedPosition = this.clampPosition_(position);
3995 var difference = position - clampedPosition + 1;
3996 var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width'));
3997 var tooltipWidthHalf = tooltipWidth / 2;
3999 this.tooltip.innerHTML = time;
4000 this.tooltip.style.right = '-' + (tooltipWidthHalf - difference) + 'px';
4005 * Get the mouse pointers x coordinate in pixels.
4007 * @param {EventTarget~Event} [event]
4008 * The `mousemove` event that was passed to this function by
4009 * {@link MouseTimeDisplay#handleMouseMove}
4012 * THe x position in pixels of the mouse pointer.
4016 MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) {
4017 return Dom.getPointerPosition(this.el().parentNode, event).x;
4021 * This takes in a horizontal position for the bar and returns a clamped position.
4022 * Clamped position means that it will keep the position greater than half the width
4023 * of the tooltip and smaller than the player width minus half the width o the tooltip.
4024 * It will only clamp the position if `keepTooltipsInside` option is set.
4026 * @param {number} position
4027 * The position the bar wants to be
4030 * The (potentially) new clamped position.
4036 MouseTimeDisplay.prototype.clampPosition_ = function clampPosition_(position) {
4037 if (!this.keepTooltipsInside) {
4041 var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width'));
4042 var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width'));
4043 var tooltipWidthHalf = tooltipWidth / 2;
4044 var actualPosition = position;
4046 if (position < tooltipWidthHalf) {
4047 actualPosition = Math.ceil(tooltipWidthHalf);
4048 } else if (position > playerWidth - tooltipWidthHalf) {
4049 actualPosition = Math.floor(playerWidth - tooltipWidthHalf);
4052 return actualPosition;
4055 return MouseTimeDisplay;
4056 }(_component2['default']);
4058 _component2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay);
4059 exports['default'] = MouseTimeDisplay;
4061 },{"5":5,"80":80,"81":81,"83":83,"84":84}],17:[function(_dereq_,module,exports){
4064 exports.__esModule = true;
4066 var _component = _dereq_(5);
4068 var _component2 = _interopRequireDefault(_component);
4070 var _fn = _dereq_(83);
4072 var Fn = _interopRequireWildcard(_fn);
4074 var _formatTime = _dereq_(84);
4076 var _formatTime2 = _interopRequireDefault(_formatTime);
4078 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; } }
4080 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4082 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4084 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; }
4086 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; } /**
4087 * @file play-progress-bar.js
4092 * Shows play progress
4094 * @extends Component
4096 var PlayProgressBar = function (_Component) {
4097 _inherits(PlayProgressBar, _Component);
4100 * Creates an instance of this class.
4102 * @param {Player} player
4103 * The `Player` that this class should be attached to.
4105 * @param {Object} [options]
4106 * The key/value store of player options.
4108 function PlayProgressBar(player, options) {
4109 _classCallCheck(this, PlayProgressBar);
4111 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
4113 _this.updateDataAttr();
4114 _this.on(player, 'timeupdate', _this.updateDataAttr);
4115 player.ready(Fn.bind(_this, _this.updateDataAttr));
4117 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
4118 _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
4121 if (_this.keepTooltipsInside) {
4122 _this.addClass('vjs-keep-tooltips-inside');
4128 * Create the `Component`'s DOM element
4131 * The element that was created.
4135 PlayProgressBar.prototype.createEl = function createEl() {
4136 return _Component.prototype.createEl.call(this, 'div', {
4137 className: 'vjs-play-progress vjs-slider-bar',
4138 innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
4143 * Update the data-current-time attribute on the `PlayProgressBar`.
4145 * @param {EventTarget~Event} [event]
4146 * The `timeupdate` event that caused this to run.
4148 * @listens Player#timeupdate
4152 PlayProgressBar.prototype.updateDataAttr = function updateDataAttr(event) {
4153 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
4155 this.el_.setAttribute('data-current-time', (0, _formatTime2['default'])(time, this.player_.duration()));
4158 return PlayProgressBar;
4159 }(_component2['default']);
4161 _component2['default'].registerComponent('PlayProgressBar', PlayProgressBar);
4162 exports['default'] = PlayProgressBar;
4164 },{"5":5,"83":83,"84":84}],18:[function(_dereq_,module,exports){
4167 exports.__esModule = true;
4169 var _component = _dereq_(5);
4171 var _component2 = _interopRequireDefault(_component);
4177 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4179 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4181 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; }
4183 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; } /**
4184 * @file progress-control.js
4189 * The Progress Control component contains the seek bar, load progress,
4190 * and play progress.
4192 * @extends Component
4194 var ProgressControl = function (_Component) {
4195 _inherits(ProgressControl, _Component);
4197 function ProgressControl() {
4198 _classCallCheck(this, ProgressControl);
4200 return _possibleConstructorReturn(this, _Component.apply(this, arguments));
4204 * Create the `Component`'s DOM element
4207 * The element that was created.
4209 ProgressControl.prototype.createEl = function createEl() {
4210 return _Component.prototype.createEl.call(this, 'div', {
4211 className: 'vjs-progress-control vjs-control'
4215 return ProgressControl;
4216 }(_component2['default']);
4219 * Default options for `ProgressControl`
4226 ProgressControl.prototype.options_ = {
4227 children: ['seekBar']
4230 _component2['default'].registerComponent('ProgressControl', ProgressControl);
4231 exports['default'] = ProgressControl;
4233 },{"16":16,"19":19,"5":5}],19:[function(_dereq_,module,exports){
4236 exports.__esModule = true;
4238 var _slider = _dereq_(57);
4240 var _slider2 = _interopRequireDefault(_slider);
4242 var _component = _dereq_(5);
4244 var _component2 = _interopRequireDefault(_component);
4246 var _fn = _dereq_(83);
4248 var Fn = _interopRequireWildcard(_fn);
4250 var _formatTime = _dereq_(84);
4252 var _formatTime2 = _interopRequireDefault(_formatTime);
4254 var _computedStyle = _dereq_(80);
4256 var _computedStyle2 = _interopRequireDefault(_computedStyle);
4264 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; } }
4266 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4268 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4270 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; }
4272 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; } /**
4278 * Seek Bar and holder for the progress bars
4282 var SeekBar = function (_Slider) {
4283 _inherits(SeekBar, _Slider);
4286 * Creates an instance of this class.
4288 * @param {Player} player
4289 * The `Player` that this class should be attached to.
4291 * @param {Object} [options]
4292 * The key/value store of player options.
4294 function SeekBar(player, options) {
4295 _classCallCheck(this, SeekBar);
4297 var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options));
4299 _this.on(player, 'timeupdate', _this.updateProgress);
4300 _this.on(player, 'ended', _this.updateProgress);
4301 player.ready(Fn.bind(_this, _this.updateProgress));
4303 if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
4304 _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
4307 if (_this.keepTooltipsInside) {
4308 _this.tooltipProgressBar = _this.addChild('TooltipProgressBar');
4314 * Create the `Component`'s DOM element
4317 * The element that was created.
4321 SeekBar.prototype.createEl = function createEl() {
4322 return _Slider.prototype.createEl.call(this, 'div', {
4323 className: 'vjs-progress-holder'
4325 'aria-label': 'progress bar'
4330 * Update the seek bars tooltip and width.
4332 * @param {EventTarget~Event} [event]
4333 * The `timeupdate` or `ended` event that caused this to run.
4335 * @listens Player#timeupdate
4336 * @listens Player#ended
4340 SeekBar.prototype.updateProgress = function updateProgress(event) {
4341 this.updateAriaAttributes(this.el_);
4343 if (this.keepTooltipsInside) {
4344 this.updateAriaAttributes(this.tooltipProgressBar.el_);
4345 this.tooltipProgressBar.el_.style.width = this.bar.el_.style.width;
4347 var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width'));
4348 var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltipProgressBar.tooltip, 'width'));
4349 var tooltipStyle = this.tooltipProgressBar.el().style;
4351 tooltipStyle.maxWidth = Math.floor(playerWidth - tooltipWidth / 2) + 'px';
4352 tooltipStyle.minWidth = Math.ceil(tooltipWidth / 2) + 'px';
4353 tooltipStyle.right = '-' + tooltipWidth / 2 + 'px';
4358 * Update ARIA accessibility attributes
4360 * @param {Element} el
4361 * The element to update with aria accessibility attributes.
4365 SeekBar.prototype.updateAriaAttributes = function updateAriaAttributes(el) {
4366 // Allows for smooth scrubbing, when player can't keep up.
4367 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
4369 // machine readable value of progress bar (percentage complete)
4370 el.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2));
4371 // human readable value of progress bar (time complete)
4372 el.setAttribute('aria-valuetext', (0, _formatTime2['default'])(time, this.player_.duration()));
4376 * Get percentage of video played
4379 * The percentage played
4383 SeekBar.prototype.getPercent = function getPercent() {
4384 var percent = this.player_.currentTime() / this.player_.duration();
4386 return percent >= 1 ? 1 : percent;
4390 * Handle mouse down on seek bar
4392 * @param {EventTarget~Event} event
4393 * The `mousedown` event that caused this to run.
4395 * @listens mousedown
4399 SeekBar.prototype.handleMouseDown = function handleMouseDown(event) {
4400 this.player_.scrubbing(true);
4402 this.videoWasPlaying = !this.player_.paused();
4403 this.player_.pause();
4405 _Slider.prototype.handleMouseDown.call(this, event);
4409 * Handle mouse move on seek bar
4411 * @param {EventTarget~Event} event
4412 * The `mousemove` event that caused this to run.
4414 * @listens mousemove
4418 SeekBar.prototype.handleMouseMove = function handleMouseMove(event) {
4419 var newTime = this.calculateDistance(event) * this.player_.duration();
4421 // Don't let video end while scrubbing.
4422 if (newTime === this.player_.duration()) {
4423 newTime = newTime - 0.1;
4426 // Set new time (tell player to seek to new time)
4427 this.player_.currentTime(newTime);
4431 * Handle mouse up on seek bar
4433 * @param {EventTarget~Event} event
4434 * The `mouseup` event that caused this to run.
4440 SeekBar.prototype.handleMouseUp = function handleMouseUp(event) {
4441 _Slider.prototype.handleMouseUp.call(this, event);
4443 this.player_.scrubbing(false);
4444 if (this.videoWasPlaying) {
4445 this.player_.play();
4450 * Move more quickly fast forward for keyboard-only users
4454 SeekBar.prototype.stepForward = function stepForward() {
4455 // more quickly fast forward for keyboard-only users
4456 this.player_.currentTime(this.player_.currentTime() + 5);
4460 * Move more quickly rewind for keyboard-only users
4464 SeekBar.prototype.stepBack = function stepBack() {
4465 // more quickly rewind for keyboard-only users
4466 this.player_.currentTime(this.player_.currentTime() - 5);
4470 }(_slider2['default']);
4473 * Default options for the `SeekBar`
4480 SeekBar.prototype.options_ = {
4481 children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'],
4482 barName: 'playProgressBar'
4486 * Call the update event for this Slider when this event happens on the player.
4490 SeekBar.prototype.playerEvent = 'timeupdate';
4492 _component2['default'].registerComponent('SeekBar', SeekBar);
4493 exports['default'] = SeekBar;
4495 },{"15":15,"17":17,"20":20,"5":5,"57":57,"80":80,"83":83,"84":84}],20:[function(_dereq_,module,exports){
4498 exports.__esModule = true;
4500 var _component = _dereq_(5);
4502 var _component2 = _interopRequireDefault(_component);
4504 var _fn = _dereq_(83);
4506 var Fn = _interopRequireWildcard(_fn);
4508 var _formatTime = _dereq_(84);
4510 var _formatTime2 = _interopRequireDefault(_formatTime);
4512 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; } }
4514 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4516 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4518 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; }
4520 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; } /**
4521 * @file play-progress-bar.js
4526 * Shows play progress
4528 * @extends Component
4530 var TooltipProgressBar = function (_Component) {
4531 _inherits(TooltipProgressBar, _Component);
4534 * Creates an instance of this class.
4536 * @param {Player} player
4537 * The `Player` that this class should be attached to.
4539 * @param {Object} [options]
4540 * The key/value store of player options.
4542 function TooltipProgressBar(player, options) {
4543 _classCallCheck(this, TooltipProgressBar);
4545 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
4547 _this.updateDataAttr();
4548 _this.on(player, 'timeupdate', _this.updateDataAttr);
4549 player.ready(Fn.bind(_this, _this.updateDataAttr));
4554 * Create the `Component`'s DOM element
4557 * The element that was created.
4561 TooltipProgressBar.prototype.createEl = function createEl() {
4562 var el = _Component.prototype.createEl.call(this, 'div', {
4563 className: 'vjs-tooltip-progress-bar vjs-slider-bar',
4564 innerHTML: '<div class="vjs-time-tooltip"></div>\n <span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
4567 this.tooltip = el.querySelector('.vjs-time-tooltip');
4573 * Updatet the data-current-time attribute for TooltipProgressBar
4575 * @param {EventTarget~Event} [event]
4576 * The `timeupdate` event that caused this function to run.
4578 * @listens Player#timeupdate
4582 TooltipProgressBar.prototype.updateDataAttr = function updateDataAttr(event) {
4583 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
4584 var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration());
4586 this.el_.setAttribute('data-current-time', formattedTime);
4587 this.tooltip.innerHTML = formattedTime;
4590 return TooltipProgressBar;
4591 }(_component2['default']);
4593 _component2['default'].registerComponent('TooltipProgressBar', TooltipProgressBar);
4594 exports['default'] = TooltipProgressBar;
4596 },{"5":5,"83":83,"84":84}],21:[function(_dereq_,module,exports){
4599 exports.__esModule = true;
4601 var _spacer = _dereq_(22);
4603 var _spacer2 = _interopRequireDefault(_spacer);
4605 var _component = _dereq_(5);
4607 var _component2 = _interopRequireDefault(_component);
4609 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4611 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4613 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; }
4615 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; } /**
4616 * @file custom-control-spacer.js
4621 * Spacer specifically meant to be used as an insertion point for new plugins, etc.
4625 var CustomControlSpacer = function (_Spacer) {
4626 _inherits(CustomControlSpacer, _Spacer);
4628 function CustomControlSpacer() {
4629 _classCallCheck(this, CustomControlSpacer);
4631 return _possibleConstructorReturn(this, _Spacer.apply(this, arguments));
4635 * Builds the default DOM `className`.
4638 * The DOM `className` for this object.
4640 CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() {
4641 return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this);
4645 * Create the `Component`'s DOM element
4648 * The element that was created.
4652 CustomControlSpacer.prototype.createEl = function createEl() {
4653 var el = _Spacer.prototype.createEl.call(this, {
4654 className: this.buildCSSClass()
4657 // No-flex/table-cell mode requires there be some content
4658 // in the cell to fill the remaining space of the table.
4659 el.innerHTML = ' ';
4663 return CustomControlSpacer;
4664 }(_spacer2['default']);
4666 _component2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer);
4667 exports['default'] = CustomControlSpacer;
4669 },{"22":22,"5":5}],22:[function(_dereq_,module,exports){
4672 exports.__esModule = true;
4674 var _component = _dereq_(5);
4676 var _component2 = _interopRequireDefault(_component);
4678 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4680 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4682 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; }
4684 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; } /**
4690 * Just an empty spacer element that can be used as an append point for plugins, etc.
4691 * Also can be used to create space between elements when necessary.
4693 * @extends Component
4695 var Spacer = function (_Component) {
4696 _inherits(Spacer, _Component);
4699 _classCallCheck(this, Spacer);
4701 return _possibleConstructorReturn(this, _Component.apply(this, arguments));
4705 * Builds the default DOM `className`.
4708 * The DOM `className` for this object.
4710 Spacer.prototype.buildCSSClass = function buildCSSClass() {
4711 return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this);
4715 * Create the `Component`'s DOM element
4718 * The element that was created.
4722 Spacer.prototype.createEl = function createEl() {
4723 return _Component.prototype.createEl.call(this, 'div', {
4724 className: this.buildCSSClass()
4729 }(_component2['default']);
4731 _component2['default'].registerComponent('Spacer', Spacer);
4733 exports['default'] = Spacer;
4735 },{"5":5}],23:[function(_dereq_,module,exports){
4738 exports.__esModule = true;
4740 var _textTrackMenuItem = _dereq_(31);
4742 var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
4744 var _component = _dereq_(5);
4746 var _component2 = _interopRequireDefault(_component);
4748 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4750 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4752 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; }
4754 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; } /**
4755 * @file caption-settings-menu-item.js
4760 * The menu item for caption track settings menu
4762 * @extends TextTrackMenuItem
4764 var CaptionSettingsMenuItem = function (_TextTrackMenuItem) {
4765 _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem);
4768 * Creates an instance of this class.
4770 * @param {Player} player
4771 * The `Player` that this class should be attached to.
4773 * @param {Object} [options]
4774 * The key/value store of player options.
4776 function CaptionSettingsMenuItem(player, options) {
4777 _classCallCheck(this, CaptionSettingsMenuItem);
4782 label: options.kind + ' settings',
4788 // CaptionSettingsMenuItem has no concept of 'selected'
4789 options.selectable = false;
4791 var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
4793 _this.addClass('vjs-texttrack-settings');
4794 _this.controlText(', opens ' + options.kind + ' settings dialog');
4799 * This gets called when an `CaptionSettingsMenuItem` is "clicked". See
4800 * {@link ClickableComponent} for more detailed information on what a click can be.
4802 * @param {EventTarget~Event} [event]
4803 * The `keydown`, `tap`, or `click` event that caused this function to be
4811 CaptionSettingsMenuItem.prototype.handleClick = function handleClick(event) {
4812 this.player().getChild('textTrackSettings').show();
4813 this.player().getChild('textTrackSettings').el_.focus();
4816 return CaptionSettingsMenuItem;
4817 }(_textTrackMenuItem2['default']);
4819 _component2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem);
4820 exports['default'] = CaptionSettingsMenuItem;
4822 },{"31":31,"5":5}],24:[function(_dereq_,module,exports){
4825 exports.__esModule = true;
4827 var _textTrackButton = _dereq_(30);
4829 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
4831 var _component = _dereq_(5);
4833 var _component2 = _interopRequireDefault(_component);
4835 var _captionSettingsMenuItem = _dereq_(23);
4837 var _captionSettingsMenuItem2 = _interopRequireDefault(_captionSettingsMenuItem);
4839 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4841 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4843 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; }
4845 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; } /**
4846 * @file captions-button.js
4851 * The button component for toggling and selecting captions
4853 * @extends TextTrackButton
4855 var CaptionsButton = function (_TextTrackButton) {
4856 _inherits(CaptionsButton, _TextTrackButton);
4859 * Creates an instance of this class.
4861 * @param {Player} player
4862 * The `Player` that this class should be attached to.
4864 * @param {Object} [options]
4865 * The key/value store of player options.
4867 * @param {Component~ReadyCallback} [ready]
4868 * The function to call when this component is ready.
4870 function CaptionsButton(player, options, ready) {
4871 _classCallCheck(this, CaptionsButton);
4873 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
4875 _this.el_.setAttribute('aria-label', 'Captions Menu');
4880 * Builds the default DOM `className`.
4883 * The DOM `className` for this object.
4887 CaptionsButton.prototype.buildCSSClass = function buildCSSClass() {
4888 return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
4892 * Create caption menu items
4894 * @return {CaptionSettingsMenuItem[]}
4895 * The array of current menu items.
4899 CaptionsButton.prototype.createItems = function createItems() {
4902 if (!(this.player().tech_ && this.player().tech_.featuresNativeTextTracks)) {
4903 items.push(new _captionSettingsMenuItem2['default'](this.player_, { kind: this.kind_ }));
4905 this.hideThreshold_ += 1;
4908 return _TextTrackButton.prototype.createItems.call(this, items);
4911 return CaptionsButton;
4912 }(_textTrackButton2['default']);
4915 * `kind` of TextTrack to look for to associate it with this menu.
4922 CaptionsButton.prototype.kind_ = 'captions';
4925 * The text that should display over the `CaptionsButton`s controls. Added for localization.
4930 CaptionsButton.prototype.controlText_ = 'Captions';
4932 _component2['default'].registerComponent('CaptionsButton', CaptionsButton);
4933 exports['default'] = CaptionsButton;
4935 },{"23":23,"30":30,"5":5}],25:[function(_dereq_,module,exports){
4938 exports.__esModule = true;
4940 var _textTrackButton = _dereq_(30);
4942 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
4944 var _component = _dereq_(5);
4946 var _component2 = _interopRequireDefault(_component);
4948 var _chaptersTrackMenuItem = _dereq_(26);
4950 var _chaptersTrackMenuItem2 = _interopRequireDefault(_chaptersTrackMenuItem);
4952 var _toTitleCase = _dereq_(91);
4954 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
4956 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
4958 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4960 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; }
4962 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; } /**
4963 * @file chapters-button.js
4968 * The button component for toggling and selecting chapters
4969 * Chapters act much differently than other text tracks
4970 * Cues are navigation vs. other tracks of alternative languages
4972 * @extends TextTrackButton
4974 var ChaptersButton = function (_TextTrackButton) {
4975 _inherits(ChaptersButton, _TextTrackButton);
4978 * Creates an instance of this class.
4980 * @param {Player} player
4981 * The `Player` that this class should be attached to.
4983 * @param {Object} [options]
4984 * The key/value store of player options.
4986 * @param {Component~ReadyCallback} [ready]
4987 * The function to call when this function is ready.
4989 function ChaptersButton(player, options, ready) {
4990 _classCallCheck(this, ChaptersButton);
4992 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
4994 _this.el_.setAttribute('aria-label', 'Chapters Menu');
4999 * Builds the default DOM `className`.
5002 * The DOM `className` for this object.
5006 ChaptersButton.prototype.buildCSSClass = function buildCSSClass() {
5007 return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
5011 * Update the menu based on the current state of its items.
5013 * @param {EventTarget~Event} [event]
5014 * An event that triggered this function to run.
5016 * @listens TextTrackList#addtrack
5017 * @listens TextTrackList#removetrack
5018 * @listens TextTrackList#change
5022 ChaptersButton.prototype.update = function update(event) {
5023 if (!this.track_ || event && (event.type === 'addtrack' || event.type === 'removetrack')) {
5024 this.setTrack(this.findChaptersTrack());
5026 _TextTrackButton.prototype.update.call(this);
5030 * Set the currently selected track for the chapters button.
5032 * @param {TextTrack} track
5033 * The new track to select. Nothing will change if this is the currently selected
5038 ChaptersButton.prototype.setTrack = function setTrack(track) {
5039 if (this.track_ === track) {
5043 if (!this.updateHandler_) {
5044 this.updateHandler_ = this.update.bind(this);
5047 // here this.track_ refers to the old track instance
5049 var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
5051 if (remoteTextTrackEl) {
5052 remoteTextTrackEl.removeEventListener('load', this.updateHandler_);
5058 this.track_ = track;
5060 // here this.track_ refers to the new track instance
5062 this.track_.mode = 'hidden';
5064 var _remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
5066 if (_remoteTextTrackEl) {
5067 _remoteTextTrackEl.addEventListener('load', this.updateHandler_);
5073 * Find the track object that is currently in use by this ChaptersButton
5075 * @return {TextTrack|undefined}
5076 * The current track or undefined if none was found.
5080 ChaptersButton.prototype.findChaptersTrack = function findChaptersTrack() {
5081 var tracks = this.player_.textTracks() || [];
5083 for (var i = tracks.length - 1; i >= 0; i--) {
5084 // We will always choose the last track as our chaptersTrack
5085 var track = tracks[i];
5087 if (track.kind === this.kind_) {
5094 * Get the caption for the ChaptersButton based on the track label. This will also
5095 * use the current tracks localized kind as a fallback if a label does not exist.
5098 * The tracks current label or the localized track kind.
5102 ChaptersButton.prototype.getMenuCaption = function getMenuCaption() {
5103 if (this.track_ && this.track_.label) {
5104 return this.track_.label;
5106 return this.localize((0, _toTitleCase2['default'])(this.kind_));
5110 * Create menu from chapter track
5113 * New menu for the chapter buttons
5117 ChaptersButton.prototype.createMenu = function createMenu() {
5118 this.options_.title = this.getMenuCaption();
5119 return _TextTrackButton.prototype.createMenu.call(this);
5123 * Create a menu item for each text track
5125 * @return {TextTrackMenuItem[]}
5126 * Array of menu items
5130 ChaptersButton.prototype.createItems = function createItems() {
5137 var cues = this.track_.cues;
5143 for (var i = 0, l = cues.length; i < l; i++) {
5145 var mi = new _chaptersTrackMenuItem2['default'](this.player_, { track: this.track_, cue: cue });
5153 return ChaptersButton;
5154 }(_textTrackButton2['default']);
5157 * `kind` of TextTrack to look for to associate it with this menu.
5164 ChaptersButton.prototype.kind_ = 'chapters';
5167 * The text that should display over the `ChaptersButton`s controls. Added for localization.
5172 ChaptersButton.prototype.controlText_ = 'Chapters';
5174 _component2['default'].registerComponent('ChaptersButton', ChaptersButton);
5175 exports['default'] = ChaptersButton;
5177 },{"26":26,"30":30,"5":5,"91":91}],26:[function(_dereq_,module,exports){
5180 exports.__esModule = true;
5182 var _menuItem = _dereq_(48);
5184 var _menuItem2 = _interopRequireDefault(_menuItem);
5186 var _component = _dereq_(5);
5188 var _component2 = _interopRequireDefault(_component);
5190 var _fn = _dereq_(83);
5192 var Fn = _interopRequireWildcard(_fn);
5194 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; } }
5196 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5198 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5200 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; }
5202 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; } /**
5203 * @file chapters-track-menu-item.js
5208 * The chapter track menu item
5212 var ChaptersTrackMenuItem = function (_MenuItem) {
5213 _inherits(ChaptersTrackMenuItem, _MenuItem);
5216 * Creates an instance of this class.
5218 * @param {Player} player
5219 * The `Player` that this class should be attached to.
5221 * @param {Object} [options]
5222 * The key/value store of player options.
5224 function ChaptersTrackMenuItem(player, options) {
5225 _classCallCheck(this, ChaptersTrackMenuItem);
5227 var track = options.track;
5228 var cue = options.cue;
5229 var currentTime = player.currentTime();
5231 // Modify options for parent MenuItem class's init.
5232 options.selectable = true;
5233 options.label = cue.text;
5234 options.selected = cue.startTime <= currentTime && currentTime < cue.endTime;
5236 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
5238 _this.track = track;
5240 track.addEventListener('cuechange', Fn.bind(_this, _this.update));
5245 * This gets called when an `ChaptersTrackMenuItem` is "clicked". See
5246 * {@link ClickableComponent} for more detailed information on what a click can be.
5248 * @param {EventTarget~Event} [event]
5249 * The `keydown`, `tap`, or `click` event that caused this function to be
5257 ChaptersTrackMenuItem.prototype.handleClick = function handleClick(event) {
5258 _MenuItem.prototype.handleClick.call(this);
5259 this.player_.currentTime(this.cue.startTime);
5260 this.update(this.cue.startTime);
5264 * Update chapter menu item
5266 * @param {EventTarget~Event} [event]
5267 * The `cuechange` event that caused this function to run.
5269 * @listens TextTrack#cuechange
5273 ChaptersTrackMenuItem.prototype.update = function update(event) {
5275 var currentTime = this.player_.currentTime();
5277 // vjs.log(currentTime, cue.startTime);
5278 this.selected(cue.startTime <= currentTime && currentTime < cue.endTime);
5281 return ChaptersTrackMenuItem;
5282 }(_menuItem2['default']);
5284 _component2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem);
5285 exports['default'] = ChaptersTrackMenuItem;
5287 },{"48":48,"5":5,"83":83}],27:[function(_dereq_,module,exports){
5290 exports.__esModule = true;
5292 var _textTrackButton = _dereq_(30);
5294 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
5296 var _component = _dereq_(5);
5298 var _component2 = _interopRequireDefault(_component);
5300 var _fn = _dereq_(83);
5302 var Fn = _interopRequireWildcard(_fn);
5304 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; } }
5306 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5308 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5310 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; }
5312 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; } /**
5313 * @file descriptions-button.js
5318 * The button component for toggling and selecting descriptions
5320 * @extends TextTrackButton
5322 var DescriptionsButton = function (_TextTrackButton) {
5323 _inherits(DescriptionsButton, _TextTrackButton);
5326 * Creates an instance of this class.
5328 * @param {Player} player
5329 * The `Player` that this class should be attached to.
5331 * @param {Object} [options]
5332 * The key/value store of player options.
5334 * @param {Component~ReadyCallback} [ready]
5335 * The function to call when this component is ready.
5337 function DescriptionsButton(player, options, ready) {
5338 _classCallCheck(this, DescriptionsButton);
5340 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
5342 _this.el_.setAttribute('aria-label', 'Descriptions Menu');
5344 var tracks = player.textTracks();
5347 var changeHandler = Fn.bind(_this, _this.handleTracksChange);
5349 tracks.addEventListener('change', changeHandler);
5350 _this.on('dispose', function () {
5351 tracks.removeEventListener('change', changeHandler);
5358 * Handle text track change
5360 * @param {EventTarget~Event} event
5361 * The event that caused this function to run
5363 * @listens TextTrackList#change
5367 DescriptionsButton.prototype.handleTracksChange = function handleTracksChange(event) {
5368 var tracks = this.player().textTracks();
5369 var disabled = false;
5371 // Check whether a track of a different kind is showing
5372 for (var i = 0, l = tracks.length; i < l; i++) {
5373 var track = tracks[i];
5375 if (track.kind !== this.kind_ && track.mode === 'showing') {
5381 // If another track is showing, disable this menu button
5390 * Builds the default DOM `className`.
5393 * The DOM `className` for this object.
5397 DescriptionsButton.prototype.buildCSSClass = function buildCSSClass() {
5398 return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
5401 return DescriptionsButton;
5402 }(_textTrackButton2['default']);
5405 * `kind` of TextTrack to look for to associate it with this menu.
5412 DescriptionsButton.prototype.kind_ = 'descriptions';
5415 * The text that should display over the `DescriptionsButton`s controls. Added for localization.
5420 DescriptionsButton.prototype.controlText_ = 'Descriptions';
5422 _component2['default'].registerComponent('DescriptionsButton', DescriptionsButton);
5423 exports['default'] = DescriptionsButton;
5425 },{"30":30,"5":5,"83":83}],28:[function(_dereq_,module,exports){
5428 exports.__esModule = true;
5430 var _textTrackMenuItem = _dereq_(31);
5432 var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
5434 var _component = _dereq_(5);
5436 var _component2 = _interopRequireDefault(_component);
5438 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5440 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5442 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; }
5444 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; } /**
5445 * @file off-text-track-menu-item.js
5450 * A special menu item for turning of a specific type of text track
5452 * @extends TextTrackMenuItem
5454 var OffTextTrackMenuItem = function (_TextTrackMenuItem) {
5455 _inherits(OffTextTrackMenuItem, _TextTrackMenuItem);
5458 * Creates an instance of this class.
5460 * @param {Player} player
5461 * The `Player` that this class should be attached to.
5463 * @param {Object} [options]
5464 * The key/value store of player options.
5466 function OffTextTrackMenuItem(player, options) {
5467 _classCallCheck(this, OffTextTrackMenuItem);
5469 // Create pseudo track info
5470 // Requires options['kind']
5474 label: options.kind + ' off',
5479 // MenuItem is selectable
5480 options.selectable = true;
5482 var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
5484 _this.selected(true);
5489 * Handle text track change
5491 * @param {EventTarget~Event} event
5492 * The event that caused this function to run
5496 OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
5497 var tracks = this.player().textTracks();
5498 var selected = true;
5500 for (var i = 0, l = tracks.length; i < l; i++) {
5501 var track = tracks[i];
5503 if (track.kind === this.track.kind && track.mode === 'showing') {
5509 this.selected(selected);
5512 return OffTextTrackMenuItem;
5513 }(_textTrackMenuItem2['default']);
5515 _component2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem);
5516 exports['default'] = OffTextTrackMenuItem;
5518 },{"31":31,"5":5}],29:[function(_dereq_,module,exports){
5521 exports.__esModule = true;
5523 var _textTrackButton = _dereq_(30);
5525 var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
5527 var _component = _dereq_(5);
5529 var _component2 = _interopRequireDefault(_component);
5531 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5533 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5535 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; }
5537 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; } /**
5538 * @file subtitles-button.js
5543 * The button component for toggling and selecting subtitles
5545 * @extends TextTrackButton
5547 var SubtitlesButton = function (_TextTrackButton) {
5548 _inherits(SubtitlesButton, _TextTrackButton);
5551 * Creates an instance of this class.
5553 * @param {Player} player
5554 * The `Player` that this class should be attached to.
5556 * @param {Object} [options]
5557 * The key/value store of player options.
5559 * @param {Component~ReadyCallback} [ready]
5560 * The function to call when this component is ready.
5562 function SubtitlesButton(player, options, ready) {
5563 _classCallCheck(this, SubtitlesButton);
5565 var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
5567 _this.el_.setAttribute('aria-label', 'Subtitles Menu');
5572 * Builds the default DOM `className`.
5575 * The DOM `className` for this object.
5579 SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() {
5580 return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
5583 return SubtitlesButton;
5584 }(_textTrackButton2['default']);
5587 * `kind` of TextTrack to look for to associate it with this menu.
5594 SubtitlesButton.prototype.kind_ = 'subtitles';
5597 * The text that should display over the `SubtitlesButton`s controls. Added for localization.
5602 SubtitlesButton.prototype.controlText_ = 'Subtitles';
5604 _component2['default'].registerComponent('SubtitlesButton', SubtitlesButton);
5605 exports['default'] = SubtitlesButton;
5607 },{"30":30,"5":5}],30:[function(_dereq_,module,exports){
5610 exports.__esModule = true;
5612 var _trackButton = _dereq_(36);
5614 var _trackButton2 = _interopRequireDefault(_trackButton);
5616 var _component = _dereq_(5);
5618 var _component2 = _interopRequireDefault(_component);
5620 var _textTrackMenuItem = _dereq_(31);
5622 var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
5624 var _offTextTrackMenuItem = _dereq_(28);
5626 var _offTextTrackMenuItem2 = _interopRequireDefault(_offTextTrackMenuItem);
5628 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5630 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5632 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; }
5634 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; } /**
5635 * @file text-track-button.js
5640 * The base class for buttons that toggle specific text track types (e.g. subtitles)
5642 * @extends MenuButton
5644 var TextTrackButton = function (_TrackButton) {
5645 _inherits(TextTrackButton, _TrackButton);
5648 * Creates an instance of this class.
5650 * @param {Player} player
5651 * The `Player` that this class should be attached to.
5653 * @param {Object} [options={}]
5654 * The key/value store of player options.
5656 function TextTrackButton(player) {
5657 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
5659 _classCallCheck(this, TextTrackButton);
5661 options.tracks = player.textTracks();
5663 return _possibleConstructorReturn(this, _TrackButton.call(this, player, options));
5667 * Create a menu item for each text track
5669 * @param {TextTrackMenuItem[]} [items=[]]
5670 * Existing array of items to use during creation
5672 * @return {TextTrackMenuItem[]}
5673 * Array of menu items that were created
5677 TextTrackButton.prototype.createItems = function createItems() {
5678 var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
5680 // Add an OFF menu item to turn all tracks off
5681 items.push(new _offTextTrackMenuItem2['default'](this.player_, { kind: this.kind_ }));
5682 this.hideThreshold_ += 1;
5684 var tracks = this.player_.textTracks();
5690 for (var i = 0; i < tracks.length; i++) {
5691 var track = tracks[i];
5693 // only add tracks that are of the appropriate kind and have a label
5694 if (track.kind === this.kind_) {
5695 items.push(new _textTrackMenuItem2['default'](this.player_, {
5697 // MenuItem is selectable
5706 return TextTrackButton;
5707 }(_trackButton2['default']);
5709 _component2['default'].registerComponent('TextTrackButton', TextTrackButton);
5710 exports['default'] = TextTrackButton;
5712 },{"28":28,"31":31,"36":36,"5":5}],31:[function(_dereq_,module,exports){
5715 exports.__esModule = true;
5717 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; };
5719 var _menuItem = _dereq_(48);
5721 var _menuItem2 = _interopRequireDefault(_menuItem);
5723 var _component = _dereq_(5);
5725 var _component2 = _interopRequireDefault(_component);
5727 var _fn = _dereq_(83);
5729 var Fn = _interopRequireWildcard(_fn);
5731 var _window = _dereq_(95);
5733 var _window2 = _interopRequireDefault(_window);
5735 var _document = _dereq_(94);
5737 var _document2 = _interopRequireDefault(_document);
5739 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; } }
5741 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5743 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5745 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; }
5747 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; } /**
5748 * @file text-track-menu-item.js
5753 * The specific menu item type for selecting a language within a text track kind
5757 var TextTrackMenuItem = function (_MenuItem) {
5758 _inherits(TextTrackMenuItem, _MenuItem);
5761 * Creates an instance of this class.
5763 * @param {Player} player
5764 * The `Player` that this class should be attached to.
5766 * @param {Object} [options]
5767 * The key/value store of player options.
5769 function TextTrackMenuItem(player, options) {
5770 _classCallCheck(this, TextTrackMenuItem);
5772 var track = options.track;
5773 var tracks = player.textTracks();
5775 // Modify options for parent MenuItem class's init.
5776 options.label = track.label || track.language || 'Unknown';
5777 options.selected = track['default'] || track.mode === 'showing';
5779 var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
5781 _this.track = track;
5784 var changeHandler = Fn.bind(_this, _this.handleTracksChange);
5786 player.on(['loadstart', 'texttrackchange'], changeHandler);
5787 tracks.addEventListener('change', changeHandler);
5788 _this.on('dispose', function () {
5789 tracks.removeEventListener('change', changeHandler);
5793 // iOS7 doesn't dispatch change events to TextTrackLists when an
5794 // associated track's mode changes. Without something like
5795 // Object.observe() (also not present on iOS7), it's not
5796 // possible to detect changes to the mode attribute and polyfill
5797 // the change event. As a poor substitute, we manually dispatch
5798 // change events whenever the controls modify the mode.
5799 if (tracks && tracks.onchange === undefined) {
5802 _this.on(['tap', 'click'], function () {
5803 if (_typeof(_window2['default'].Event) !== 'object') {
5804 // Android 2.3 throws an Illegal Constructor error for window.Event
5806 event = new _window2['default'].Event('change');
5808 // continue regardless of error
5813 event = _document2['default'].createEvent('Event');
5814 event.initEvent('change', true, true);
5817 tracks.dispatchEvent(event);
5824 * This gets called when an `TextTrackMenuItem` is "clicked". See
5825 * {@link ClickableComponent} for more detailed information on what a click can be.
5827 * @param {EventTarget~Event} event
5828 * The `keydown`, `tap`, or `click` event that caused this function to be
5836 TextTrackMenuItem.prototype.handleClick = function handleClick(event) {
5837 var kind = this.track.kind;
5838 var tracks = this.player_.textTracks();
5840 _MenuItem.prototype.handleClick.call(this, event);
5846 for (var i = 0; i < tracks.length; i++) {
5847 var track = tracks[i];
5849 if (track.kind !== kind) {
5853 if (track === this.track) {
5854 track.mode = 'showing';
5856 track.mode = 'disabled';
5862 * Handle text track list change
5864 * @param {EventTarget~Event} event
5865 * The `change` event that caused this function to be called.
5867 * @listens TextTrackList#change
5871 TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
5872 this.selected(this.track.mode === 'showing');
5875 return TextTrackMenuItem;
5876 }(_menuItem2['default']);
5878 _component2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem);
5879 exports['default'] = TextTrackMenuItem;
5881 },{"48":48,"5":5,"83":83,"94":94,"95":95}],32:[function(_dereq_,module,exports){
5884 exports.__esModule = true;
5886 var _component = _dereq_(5);
5888 var _component2 = _interopRequireDefault(_component);
5890 var _dom = _dereq_(81);
5892 var Dom = _interopRequireWildcard(_dom);
5894 var _formatTime = _dereq_(84);
5896 var _formatTime2 = _interopRequireDefault(_formatTime);
5898 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; } }
5900 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
5902 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5904 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; }
5906 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; } /**
5907 * @file current-time-display.js
5912 * Displays the current time
5914 * @extends Component
5916 var CurrentTimeDisplay = function (_Component) {
5917 _inherits(CurrentTimeDisplay, _Component);
5920 * Creates an instance of this class.
5922 * @param {Player} player
5923 * The `Player` that this class should be attached to.
5925 * @param {Object} [options]
5926 * The key/value store of player options.
5928 function CurrentTimeDisplay(player, options) {
5929 _classCallCheck(this, CurrentTimeDisplay);
5931 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
5933 _this.on(player, 'timeupdate', _this.updateContent);
5938 * Create the `Component`'s DOM element
5941 * The element that was created.
5945 CurrentTimeDisplay.prototype.createEl = function createEl() {
5946 var el = _Component.prototype.createEl.call(this, 'div', {
5947 className: 'vjs-current-time vjs-time-control vjs-control'
5950 this.contentEl_ = Dom.createEl('div', {
5951 className: 'vjs-current-time-display',
5952 // label the current time for screen reader users
5953 innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00'
5955 // tell screen readers not to automatically read the time as it changes
5959 el.appendChild(this.contentEl_);
5964 * Update current time display
5966 * @param {EventTarget~Event} [event]
5967 * The `timeupdate` event that caused this function to run.
5969 * @listens Player#timeupdate
5973 CurrentTimeDisplay.prototype.updateContent = function updateContent(event) {
5974 // Allows for smooth scrubbing, when player can't keep up.
5975 var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
5976 var localizedText = this.localize('Current Time');
5977 var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration());
5979 if (formattedTime !== this.formattedTime_) {
5980 this.formattedTime_ = formattedTime;
5981 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
5985 return CurrentTimeDisplay;
5986 }(_component2['default']);
5988 _component2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
5989 exports['default'] = CurrentTimeDisplay;
5991 },{"5":5,"81":81,"84":84}],33:[function(_dereq_,module,exports){
5994 exports.__esModule = true;
5996 var _component = _dereq_(5);
5998 var _component2 = _interopRequireDefault(_component);
6000 var _dom = _dereq_(81);
6002 var Dom = _interopRequireWildcard(_dom);
6004 var _formatTime = _dereq_(84);
6006 var _formatTime2 = _interopRequireDefault(_formatTime);
6008 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; } }
6010 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6012 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6014 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; }
6016 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; } /**
6017 * @file duration-display.js
6022 * Displays the duration
6024 * @extends Component
6026 var DurationDisplay = function (_Component) {
6027 _inherits(DurationDisplay, _Component);
6030 * Creates an instance of this class.
6032 * @param {Player} player
6033 * The `Player` that this class should be attached to.
6035 * @param {Object} [options]
6036 * The key/value store of player options.
6038 function DurationDisplay(player, options) {
6039 _classCallCheck(this, DurationDisplay);
6041 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
6043 _this.on(player, 'durationchange', _this.updateContent);
6045 // Also listen for timeupdate and loadedmetadata because removing those
6046 // listeners could have broken dependent applications/libraries. These
6047 // can likely be removed for 6.0.
6048 _this.on(player, 'timeupdate', _this.updateContent);
6049 _this.on(player, 'loadedmetadata', _this.updateContent);
6054 * Create the `Component`'s DOM element
6057 * The element that was created.
6061 DurationDisplay.prototype.createEl = function createEl() {
6062 var el = _Component.prototype.createEl.call(this, 'div', {
6063 className: 'vjs-duration vjs-time-control vjs-control'
6066 this.contentEl_ = Dom.createEl('div', {
6067 className: 'vjs-duration-display',
6068 // label the duration time for screen reader users
6069 innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00'
6071 // tell screen readers not to automatically read the time as it changes
6075 el.appendChild(this.contentEl_);
6080 * Update duration time display.
6082 * @param {EventTarget~Event} [event]
6083 * The `durationchange`, `timeupdate`, or `loadedmetadata` event that caused
6084 * this function to be called.
6086 * @listens Player#durationchange
6087 * @listens Player#timeupdate
6088 * @listens Player#loadedmetadata
6092 DurationDisplay.prototype.updateContent = function updateContent(event) {
6093 var duration = this.player_.duration();
6095 if (duration && this.duration_ !== duration) {
6096 this.duration_ = duration;
6097 var localizedText = this.localize('Duration Time');
6098 var formattedTime = (0, _formatTime2['default'])(duration);
6100 // label the duration time for screen reader users
6101 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
6105 return DurationDisplay;
6106 }(_component2['default']);
6108 _component2['default'].registerComponent('DurationDisplay', DurationDisplay);
6109 exports['default'] = DurationDisplay;
6111 },{"5":5,"81":81,"84":84}],34:[function(_dereq_,module,exports){
6114 exports.__esModule = true;
6116 var _component = _dereq_(5);
6118 var _component2 = _interopRequireDefault(_component);
6120 var _dom = _dereq_(81);
6122 var Dom = _interopRequireWildcard(_dom);
6124 var _formatTime = _dereq_(84);
6126 var _formatTime2 = _interopRequireDefault(_formatTime);
6128 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; } }
6130 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6132 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6134 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; }
6136 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; } /**
6137 * @file remaining-time-display.js
6142 * Displays the time left in the video
6144 * @extends Component
6146 var RemainingTimeDisplay = function (_Component) {
6147 _inherits(RemainingTimeDisplay, _Component);
6150 * Creates an instance of this class.
6152 * @param {Player} player
6153 * The `Player` that this class should be attached to.
6155 * @param {Object} [options]
6156 * The key/value store of player options.
6158 function RemainingTimeDisplay(player, options) {
6159 _classCallCheck(this, RemainingTimeDisplay);
6161 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
6163 _this.on(player, 'timeupdate', _this.updateContent);
6164 _this.on(player, 'durationchange', _this.updateContent);
6169 * Create the `Component`'s DOM element
6172 * The element that was created.
6176 RemainingTimeDisplay.prototype.createEl = function createEl() {
6177 var el = _Component.prototype.createEl.call(this, 'div', {
6178 className: 'vjs-remaining-time vjs-time-control vjs-control'
6181 this.contentEl_ = Dom.createEl('div', {
6182 className: 'vjs-remaining-time-display',
6183 // label the remaining time for screen reader users
6184 innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00'
6186 // tell screen readers not to automatically read the time as it changes
6190 el.appendChild(this.contentEl_);
6195 * Update remaining time display.
6197 * @param {EventTarget~Event} [event]
6198 * The `timeupdate` or `durationchange` event that caused this to run.
6200 * @listens Player#timeupdate
6201 * @listens Player#durationchange
6205 RemainingTimeDisplay.prototype.updateContent = function updateContent(event) {
6206 if (this.player_.duration()) {
6207 var localizedText = this.localize('Remaining Time');
6208 var formattedTime = (0, _formatTime2['default'])(this.player_.remainingTime());
6210 if (formattedTime !== this.formattedTime_) {
6211 this.formattedTime_ = formattedTime;
6212 this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime;
6216 // Allows for smooth scrubbing, when player can't keep up.
6217 // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
6218 // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration());
6221 return RemainingTimeDisplay;
6222 }(_component2['default']);
6224 _component2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
6225 exports['default'] = RemainingTimeDisplay;
6227 },{"5":5,"81":81,"84":84}],35:[function(_dereq_,module,exports){
6230 exports.__esModule = true;
6232 var _component = _dereq_(5);
6234 var _component2 = _interopRequireDefault(_component);
6236 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6238 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6240 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; }
6242 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; } /**
6243 * @file time-divider.js
6248 * The separator between the current time and duration.
6249 * Can be hidden if it's not needed in the design.
6251 * @extends Component
6253 var TimeDivider = function (_Component) {
6254 _inherits(TimeDivider, _Component);
6256 function TimeDivider() {
6257 _classCallCheck(this, TimeDivider);
6259 return _possibleConstructorReturn(this, _Component.apply(this, arguments));
6263 * Create the component's DOM element
6266 * The element that was created.
6268 TimeDivider.prototype.createEl = function createEl() {
6269 return _Component.prototype.createEl.call(this, 'div', {
6270 className: 'vjs-time-control vjs-time-divider',
6271 innerHTML: '<div><span>/</span></div>'
6276 }(_component2['default']);
6278 _component2['default'].registerComponent('TimeDivider', TimeDivider);
6279 exports['default'] = TimeDivider;
6281 },{"5":5}],36:[function(_dereq_,module,exports){
6284 exports.__esModule = true;
6286 var _menuButton = _dereq_(47);
6288 var _menuButton2 = _interopRequireDefault(_menuButton);
6290 var _component = _dereq_(5);
6292 var _component2 = _interopRequireDefault(_component);
6294 var _fn = _dereq_(83);
6296 var Fn = _interopRequireWildcard(_fn);
6298 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; } }
6300 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6302 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6304 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; }
6306 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; } /**
6307 * @file track-button.js
6312 * The base class for buttons that toggle specific track types (e.g. subtitles).
6314 * @extends MenuButton
6316 var TrackButton = function (_MenuButton) {
6317 _inherits(TrackButton, _MenuButton);
6320 * Creates an instance of this class.
6322 * @param {Player} player
6323 * The `Player` that this class should be attached to.
6325 * @param {Object} [options]
6326 * The key/value store of player options.
6328 function TrackButton(player, options) {
6329 _classCallCheck(this, TrackButton);
6331 var tracks = options.tracks;
6333 var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options));
6335 if (_this.items.length <= 1) {
6340 return _possibleConstructorReturn(_this);
6343 var updateHandler = Fn.bind(_this, _this.update);
6345 tracks.addEventListener('removetrack', updateHandler);
6346 tracks.addEventListener('addtrack', updateHandler);
6348 _this.player_.on('dispose', function () {
6349 tracks.removeEventListener('removetrack', updateHandler);
6350 tracks.removeEventListener('addtrack', updateHandler);
6356 }(_menuButton2['default']);
6358 _component2['default'].registerComponent('TrackButton', TrackButton);
6359 exports['default'] = TrackButton;
6361 },{"47":47,"5":5,"83":83}],37:[function(_dereq_,module,exports){
6364 exports.__esModule = true;
6366 var _slider = _dereq_(57);
6368 var _slider2 = _interopRequireDefault(_slider);
6370 var _component = _dereq_(5);
6372 var _component2 = _interopRequireDefault(_component);
6374 var _fn = _dereq_(83);
6376 var Fn = _interopRequireWildcard(_fn);
6380 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; } }
6382 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6384 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6386 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; }
6388 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; } /**
6389 * @file volume-bar.js
6393 // Required children
6397 * The bar that contains the volume level and can be clicked on to adjust the level
6401 var VolumeBar = function (_Slider) {
6402 _inherits(VolumeBar, _Slider);
6405 * Creates an instance of this class.
6407 * @param {Player} player
6408 * The `Player` that this class should be attached to.
6410 * @param {Object} [options]
6411 * The key/value store of player options.
6413 function VolumeBar(player, options) {
6414 _classCallCheck(this, VolumeBar);
6416 var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options));
6418 _this.on(player, 'volumechange', _this.updateARIAAttributes);
6419 player.ready(Fn.bind(_this, _this.updateARIAAttributes));
6424 * Create the `Component`'s DOM element
6427 * The element that was created.
6431 VolumeBar.prototype.createEl = function createEl() {
6432 return _Slider.prototype.createEl.call(this, 'div', {
6433 className: 'vjs-volume-bar vjs-slider-bar'
6435 'aria-label': 'volume level'
6440 * Handle movement events on the {@link VolumeMenuButton}.
6442 * @param {EventTarget~Event} event
6443 * The event that caused this function to run.
6445 * @listens mousemove
6449 VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) {
6451 this.player_.volume(this.calculateDistance(event));
6455 * If the player is muted unmute it.
6459 VolumeBar.prototype.checkMuted = function checkMuted() {
6460 if (this.player_.muted()) {
6461 this.player_.muted(false);
6466 * Get percent of volume level
6469 * Volume level percent as a decimal number.
6473 VolumeBar.prototype.getPercent = function getPercent() {
6474 if (this.player_.muted()) {
6477 return this.player_.volume();
6481 * Increase volume level for keyboard users
6485 VolumeBar.prototype.stepForward = function stepForward() {
6487 this.player_.volume(this.player_.volume() + 0.1);
6491 * Decrease volume level for keyboard users
6495 VolumeBar.prototype.stepBack = function stepBack() {
6497 this.player_.volume(this.player_.volume() - 0.1);
6501 * Update ARIA accessibility attributes
6503 * @param {EventTarget~Event} [event]
6504 * The `volumechange` event that caused this function to run.
6506 * @listens Player#volumechange
6510 VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes(event) {
6511 // Current value of volume bar as a percentage
6512 var volume = (this.player_.volume() * 100).toFixed(2);
6514 this.el_.setAttribute('aria-valuenow', volume);
6515 this.el_.setAttribute('aria-valuetext', volume + '%');
6519 }(_slider2['default']);
6522 * Default options for the `VolumeBar`
6529 VolumeBar.prototype.options_ = {
6530 children: ['volumeLevel'],
6531 barName: 'volumeLevel'
6535 * Call the update event for this Slider when this event happens on the player.
6539 VolumeBar.prototype.playerEvent = 'volumechange';
6541 _component2['default'].registerComponent('VolumeBar', VolumeBar);
6542 exports['default'] = VolumeBar;
6544 },{"39":39,"5":5,"57":57,"83":83}],38:[function(_dereq_,module,exports){
6547 exports.__esModule = true;
6549 var _component = _dereq_(5);
6551 var _component2 = _interopRequireDefault(_component);
6555 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6557 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6559 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; }
6561 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; } /**
6562 * @file volume-control.js
6566 // Required children
6570 * The component for controlling the volume level
6572 * @extends Component
6574 var VolumeControl = function (_Component) {
6575 _inherits(VolumeControl, _Component);
6578 * Creates an instance of this class.
6580 * @param {Player} player
6581 * The `Player` that this class should be attached to.
6583 * @param {Object} [options={}]
6584 * The key/value store of player options.
6586 function VolumeControl(player, options) {
6587 _classCallCheck(this, VolumeControl);
6589 // hide volume controls when they're not supported by the current tech
6590 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
6592 if (player.tech_ && player.tech_.featuresVolumeControl === false) {
6593 _this.addClass('vjs-hidden');
6595 _this.on(player, 'loadstart', function () {
6596 if (player.tech_.featuresVolumeControl === false) {
6597 this.addClass('vjs-hidden');
6599 this.removeClass('vjs-hidden');
6606 * Create the `Component`'s DOM element
6609 * The element that was created.
6613 VolumeControl.prototype.createEl = function createEl() {
6614 return _Component.prototype.createEl.call(this, 'div', {
6615 className: 'vjs-volume-control vjs-control'
6619 return VolumeControl;
6620 }(_component2['default']);
6623 * Default options for the `VolumeControl`
6630 VolumeControl.prototype.options_ = {
6631 children: ['volumeBar']
6634 _component2['default'].registerComponent('VolumeControl', VolumeControl);
6635 exports['default'] = VolumeControl;
6637 },{"37":37,"5":5}],39:[function(_dereq_,module,exports){
6640 exports.__esModule = true;
6642 var _component = _dereq_(5);
6644 var _component2 = _interopRequireDefault(_component);
6646 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6648 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6650 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; }
6652 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; } /**
6653 * @file volume-level.js
6658 * Shows volume level
6660 * @extends Component
6662 var VolumeLevel = function (_Component) {
6663 _inherits(VolumeLevel, _Component);
6665 function VolumeLevel() {
6666 _classCallCheck(this, VolumeLevel);
6668 return _possibleConstructorReturn(this, _Component.apply(this, arguments));
6672 * Create the `Component`'s DOM element
6675 * The element that was created.
6677 VolumeLevel.prototype.createEl = function createEl() {
6678 return _Component.prototype.createEl.call(this, 'div', {
6679 className: 'vjs-volume-level',
6680 innerHTML: '<span class="vjs-control-text"></span>'
6685 }(_component2['default']);
6687 _component2['default'].registerComponent('VolumeLevel', VolumeLevel);
6688 exports['default'] = VolumeLevel;
6690 },{"5":5}],40:[function(_dereq_,module,exports){
6693 exports.__esModule = true;
6695 var _fn = _dereq_(83);
6697 var Fn = _interopRequireWildcard(_fn);
6699 var _component = _dereq_(5);
6701 var _component2 = _interopRequireDefault(_component);
6703 var _popup = _dereq_(54);
6705 var _popup2 = _interopRequireDefault(_popup);
6707 var _popupButton = _dereq_(53);
6709 var _popupButton2 = _interopRequireDefault(_popupButton);
6711 var _muteToggle = _dereq_(11);
6713 var _muteToggle2 = _interopRequireDefault(_muteToggle);
6715 var _volumeBar = _dereq_(37);
6717 var _volumeBar2 = _interopRequireDefault(_volumeBar);
6719 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6721 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; } }
6723 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6725 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; }
6727 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; } /**
6728 * @file volume-menu-button.js
6733 * Button for volume popup
6735 * @extends PopupButton
6737 var VolumeMenuButton = function (_PopupButton) {
6738 _inherits(VolumeMenuButton, _PopupButton);
6741 * Creates an instance of this class.
6743 * @param {Player} player
6744 * The `Player` that this class should be attached to.
6746 * @param {Object} [options={}]
6747 * The key/value store of player options.
6749 function VolumeMenuButton(player) {
6750 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
6752 _classCallCheck(this, VolumeMenuButton);
6754 // Default to inline
6755 if (options.inline === undefined) {
6756 options.inline = true;
6759 // If the vertical option isn't passed at all, default to true.
6760 if (options.vertical === undefined) {
6761 // If an inline volumeMenuButton is used, we should default to using
6762 // a horizontal slider for obvious reasons.
6763 if (options.inline) {
6764 options.vertical = false;
6766 options.vertical = true;
6770 // The vertical option needs to be set on the volumeBar as well,
6771 // since that will need to be passed along to the VolumeBar constructor
6772 options.volumeBar = options.volumeBar || {};
6773 options.volumeBar.vertical = !!options.vertical;
6775 // Same listeners as MuteToggle
6776 var _this = _possibleConstructorReturn(this, _PopupButton.call(this, player, options));
6778 _this.on(player, 'volumechange', _this.volumeUpdate);
6779 _this.on(player, 'loadstart', _this.volumeUpdate);
6781 // hide mute toggle if the current tech doesn't support volume control
6782 function updateVisibility() {
6783 if (player.tech_ && player.tech_.featuresVolumeControl === false) {
6784 this.addClass('vjs-hidden');
6786 this.removeClass('vjs-hidden');
6790 updateVisibility.call(_this);
6791 _this.on(player, 'loadstart', updateVisibility);
6793 _this.on(_this.volumeBar, ['slideractive', 'focus'], function () {
6794 this.addClass('vjs-slider-active');
6797 _this.on(_this.volumeBar, ['sliderinactive', 'blur'], function () {
6798 this.removeClass('vjs-slider-active');
6801 _this.on(_this.volumeBar, ['focus'], function () {
6802 this.addClass('vjs-lock-showing');
6805 _this.on(_this.volumeBar, ['blur'], function () {
6806 this.removeClass('vjs-lock-showing');
6812 * Builds the default DOM `className`.
6815 * The DOM `className` for this object.
6819 VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() {
6820 var orientationClass = '';
6822 if (this.options_.vertical) {
6823 orientationClass = 'vjs-volume-menu-button-vertical';
6825 orientationClass = 'vjs-volume-menu-button-horizontal';
6828 return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass;
6832 * Create the VolumeMenuButton popup
6835 * The popup that was created
6839 VolumeMenuButton.prototype.createPopup = function createPopup() {
6840 var popup = new _popup2['default'](this.player_, {
6841 contentElType: 'div'
6844 var vb = new _volumeBar2['default'](this.player_, this.options_.volumeBar);
6848 this.menuContent = popup;
6849 this.volumeBar = vb;
6851 this.attachVolumeBarEvents();
6857 * This gets called when an `VolumeMenuButton` is "clicked". See
6858 * {@link ClickableComponent} for more detailed information on what a click can be.
6860 * @param {EventTarget~Event} [event]
6861 * The `keydown`, `tap`, or `click` event that caused this function to be
6869 VolumeMenuButton.prototype.handleClick = function handleClick(event) {
6870 _muteToggle2['default'].prototype.handleClick.call(this);
6871 _PopupButton.prototype.handleClick.call(this);
6875 * Add events listeners to the created `VolumeBar`.
6879 VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() {
6880 this.menuContent.on(['mousedown', 'touchdown'], Fn.bind(this, this.handleMouseDown));
6884 * Handle the `mousedown` and `touchdown` events on the `VolumeBar`
6886 * @param {EventTarget~Event} [event]
6887 * The `mousedown` or `touchdown` event that caused this to run.
6889 * @listens mousedown
6890 * @listens touchdown
6894 VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) {
6895 this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
6896 this.on(this.el_.ownerDocument, ['mouseup', 'touchend'], this.handleMouseUp);
6900 * Handle the `mouseup` and `touchend` events on the `VolumeBar`
6902 * @param {EventTarget~Event} [event]
6903 * The `mouseup` or `touchend` event that caused this to run.
6910 VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) {
6911 this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
6914 return VolumeMenuButton;
6915 }(_popupButton2['default']);
6918 * @borrows MuteToggle#update as VolumeMenuButton#volumeUpdate
6922 VolumeMenuButton.prototype.volumeUpdate = _muteToggle2['default'].prototype.update;
6925 * The text that should display over the `VolumeMenuButton`s controls. Added for localization.
6930 VolumeMenuButton.prototype.controlText_ = 'Mute';
6932 _component2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton);
6933 exports['default'] = VolumeMenuButton;
6935 },{"11":11,"37":37,"5":5,"53":53,"54":54,"83":83}],41:[function(_dereq_,module,exports){
6938 exports.__esModule = true;
6940 var _component = _dereq_(5);
6942 var _component2 = _interopRequireDefault(_component);
6944 var _modalDialog = _dereq_(50);
6946 var _modalDialog2 = _interopRequireDefault(_modalDialog);
6948 var _mergeOptions = _dereq_(87);
6950 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
6952 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
6954 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6956 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; }
6958 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; } /**
6959 * @file error-display.js
6964 * A display that indicates an error has occurred. This means that the video
6967 * @extends ModalDialog
6969 var ErrorDisplay = function (_ModalDialog) {
6970 _inherits(ErrorDisplay, _ModalDialog);
6973 * Creates an instance of this class.
6975 * @param {Player} player
6976 * The `Player` that this class should be attached to.
6978 * @param {Object} [options]
6979 * The key/value store of player options.
6981 function ErrorDisplay(player, options) {
6982 _classCallCheck(this, ErrorDisplay);
6984 var _this = _possibleConstructorReturn(this, _ModalDialog.call(this, player, options));
6986 _this.on(player, 'error', _this.open);
6991 * Builds the default DOM `className`.
6994 * The DOM `className` for this object.
6996 * @deprecated Since version 5.
7000 ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() {
7001 return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this);
7005 * Gets the localized error message based on the `Player`s error.
7008 * The `Player`s error message localized or an empty string.
7012 ErrorDisplay.prototype.content = function content() {
7013 var error = this.player().error();
7015 return error ? this.localize(error.message) : '';
7018 return ErrorDisplay;
7019 }(_modalDialog2['default']);
7022 * The default options for an `ErrorDisplay`.
7028 ErrorDisplay.prototype.options_ = (0, _mergeOptions2['default'])(_modalDialog2['default'].prototype.options_, {
7035 _component2['default'].registerComponent('ErrorDisplay', ErrorDisplay);
7036 exports['default'] = ErrorDisplay;
7038 },{"5":5,"50":50,"87":87}],42:[function(_dereq_,module,exports){
7041 exports.__esModule = true;
7043 var _events = _dereq_(82);
7045 var Events = _interopRequireWildcard(_events);
7047 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; } }
7050 * `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It
7051 * adds shorthand functions that wrap around lengthy functions. For example:
7052 * the `on` function is a wrapper around `addEventListener`.
7054 * @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget}
7055 * @class EventTarget
7057 var EventTarget = function EventTarget() {};
7060 * A Custom DOM event.
7062 * @typedef {Object} EventTarget~Event
7063 * @see [Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
7067 * All event listeners should follow the following format.
7069 * @callback EventTarget~EventListener
7070 * @this {EventTarget}
7072 * @param {EventTarget~Event} event
7073 * the event that triggered this function
7075 * @param {Object} [hash]
7076 * hash of data sent during the event
7080 * An object containing event names as keys and booleans as values.
7082 * > NOTE: If an event name is set to a true value here {@link EventTarget#trigger}
7083 * will have extra functionality. See that function for more information.
7085 * @property EventTarget.prototype.allowedEvents_
7089 * @file src/js/event-target.js
7091 EventTarget.prototype.allowedEvents_ = {};
7094 * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a
7095 * function that will get called when an event with a certain name gets triggered.
7097 * @param {string|string[]} type
7098 * An event name or an array of event names.
7100 * @param {EventTarget~EventListener} fn
7101 * The function to call with `EventTarget`s
7103 EventTarget.prototype.on = function (type, fn) {
7104 // Remove the addEventListener alias before calling Events.on
7105 // so we don't get into an infinite type loop
7106 var ael = this.addEventListener;
7108 this.addEventListener = function () {};
7109 Events.on(this, type, fn);
7110 this.addEventListener = ael;
7114 * An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic
7115 * the standard DOM API.
7118 * @see {@link EventTarget#on}
7120 EventTarget.prototype.addEventListener = EventTarget.prototype.on;
7123 * Removes an `event listener` for a specific event from an instance of `EventTarget`.
7124 * This makes it so that the `event listener` will no longer get called when the
7125 * named event happens.
7127 * @param {string|string[]} type
7128 * An event name or an array of event names.
7130 * @param {EventTarget~EventListener} fn
7131 * The function to remove.
7133 EventTarget.prototype.off = function (type, fn) {
7134 Events.off(this, type, fn);
7138 * An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic
7139 * the standard DOM API.
7142 * @see {@link EventTarget#off}
7144 EventTarget.prototype.removeEventListener = EventTarget.prototype.off;
7147 * This function will add an `event listener` that gets triggered only once. After the
7148 * first trigger it will get removed. This is like adding an `event listener`
7149 * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself.
7151 * @param {string|string[]} type
7152 * An event name or an array of event names.
7154 * @param {EventTarget~EventListener} fn
7155 * The function to be called once for each event name.
7157 EventTarget.prototype.one = function (type, fn) {
7158 // Remove the addEventListener alialing Events.on
7159 // so we don't get into an infinite type loop
7160 var ael = this.addEventListener;
7162 this.addEventListener = function () {};
7163 Events.one(this, type, fn);
7164 this.addEventListener = ael;
7168 * This function causes an event to happen. This will then cause any `event listeners`
7169 * that are waiting for that event, to get called. If there are no `event listeners`
7170 * for an event then nothing will happen.
7172 * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`.
7173 * Trigger will also call the `on` + `uppercaseEventName` function.
7176 * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call
7177 * `onClick` if it exists.
7179 * @param {string|EventTarget~Event|Object} event
7180 * The name of the event, an `Event`, or an object with a key of type set to
7183 EventTarget.prototype.trigger = function (event) {
7184 var type = event.type || event;
7186 if (typeof event === 'string') {
7187 event = { type: type };
7189 event = Events.fixEvent(event);
7191 if (this.allowedEvents_[type] && this['on' + type]) {
7192 this['on' + type](event);
7195 Events.trigger(this, event);
7199 * An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic
7200 * the standard DOM API.
7203 * @see {@link EventTarget#trigger}
7205 EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;
7207 exports['default'] = EventTarget;
7209 },{"82":82}],43:[function(_dereq_,module,exports){
7212 exports.__esModule = true;
7214 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; };
7216 var _log = _dereq_(86);
7218 var _log2 = _interopRequireDefault(_log);
7220 var _obj = _dereq_(88);
7222 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7230 * A combination of node inherits and babel's inherits (after transpile).
7231 * Both work the same but node adds `super_` to the subClass
7232 * and Bable adds the superClass as __proto__. Both seem useful.
7234 * @param {Object} subClass
7235 * The class to inherit to
7237 * @param {Object} superClass
7238 * The class to inherit from
7242 var _inherits = function _inherits(subClass, superClass) {
7243 if (typeof superClass !== 'function' && superClass !== null) {
7244 throw new TypeError('Super expression must either be null or a function, not ' + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass)));
7247 subClass.prototype = Object.create(superClass && superClass.prototype, {
7258 subClass.super_ = superClass;
7263 * Function for subclassing using the same inheritance that
7264 * videojs uses internally
7266 * @param {Object} superClass
7267 * The class to inherit from
7269 * @param {Object} [subClassMethods={}]
7270 * The class to inherit to
7273 * The new object with subClassMethods that inherited superClass.
7275 var extendFn = function extendFn(superClass) {
7276 var subClassMethods = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7278 var subClass = function subClass() {
7279 superClass.apply(this, arguments);
7284 if ((0, _obj.isObject)(subClassMethods)) {
7285 if (typeof subClassMethods.init === 'function') {
7286 _log2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.');
7287 subClassMethods.constructor = subClassMethods.init;
7289 if (subClassMethods.constructor !== Object.prototype.constructor) {
7290 subClass = subClassMethods.constructor;
7292 methods = subClassMethods;
7293 } else if (typeof subClassMethods === 'function') {
7294 subClass = subClassMethods;
7297 _inherits(subClass, superClass);
7299 // Extend subObj's prototype with functions and other properties from props
7300 for (var name in methods) {
7301 if (methods.hasOwnProperty(name)) {
7302 subClass.prototype[name] = methods[name];
7309 exports['default'] = extendFn;
7311 },{"86":86,"88":88}],44:[function(_dereq_,module,exports){
7314 exports.__esModule = true;
7316 var _document = _dereq_(94);
7318 var _document2 = _interopRequireDefault(_document);
7320 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7323 * Store the browser-specific methods for the fullscreen API.
7326 * @see [Specification]{@link https://fullscreen.spec.whatwg.org}
7327 * @see [Map Approach From Screenfull.js]{@link https://github.com/sindresorhus/screenfull.js}
7329 var FullscreenApi = {};
7331 // browser API methods
7333 * @file fullscreen-api.js
7334 * @module fullscreen-api
7337 var apiMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'],
7339 ['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'],
7340 // Old WebKit (Safari 5.1)
7341 ['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'],
7343 ['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'],
7345 ['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']];
7347 var specApi = apiMap[0];
7348 var browserApi = void 0;
7350 // determine the supported set of functions
7351 for (var i = 0; i < apiMap.length; i++) {
7352 // check for exitFullscreen function
7353 if (apiMap[i][1] in _document2['default']) {
7354 browserApi = apiMap[i];
7359 // map the browser API names to the spec API names
7361 for (var _i = 0; _i < browserApi.length; _i++) {
7362 FullscreenApi[specApi[_i]] = browserApi[_i];
7366 exports['default'] = FullscreenApi;
7368 },{"94":94}],45:[function(_dereq_,module,exports){
7371 exports.__esModule = true;
7373 var _component = _dereq_(5);
7375 var _component2 = _interopRequireDefault(_component);
7377 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7379 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7381 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; }
7383 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; } /**
7384 * @file loading-spinner.js
7389 * A loading spinner for use during waiting/loading events.
7391 * @extends Component
7393 var LoadingSpinner = function (_Component) {
7394 _inherits(LoadingSpinner, _Component);
7396 function LoadingSpinner() {
7397 _classCallCheck(this, LoadingSpinner);
7399 return _possibleConstructorReturn(this, _Component.apply(this, arguments));
7403 * Create the `LoadingSpinner`s DOM element.
7406 * The dom element that gets created.
7408 LoadingSpinner.prototype.createEl = function createEl() {
7409 return _Component.prototype.createEl.call(this, 'div', {
7410 className: 'vjs-loading-spinner',
7415 return LoadingSpinner;
7416 }(_component2['default']);
7418 _component2['default'].registerComponent('LoadingSpinner', LoadingSpinner);
7419 exports['default'] = LoadingSpinner;
7421 },{"5":5}],46:[function(_dereq_,module,exports){
7424 exports.__esModule = true;
7426 var _obj = _dereq_(88);
7429 * A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class.
7431 * @param {number|string|Object|MediaError} value
7432 * This can be of multiple types:
7433 * - number: should be a standard error code
7434 * - string: an error message (the code will be 0)
7435 * - Object: arbitrary properties
7436 * - `MediaError` (native): used to populate a video.js `MediaError` object
7437 * - `MediaError` (video.js): will return itself if it's already a
7438 * video.js `MediaError` object.
7440 * @see [MediaError Spec]{@link https://dev.w3.org/html5/spec-author-view/video.html#mediaerror}
7441 * @see [Encrypted MediaError Spec]{@link https://www.w3.org/TR/2013/WD-encrypted-media-20130510/#error-codes}
7445 function MediaError(value) {
7447 // Allow redundant calls to this constructor to avoid having `instanceof`
7448 // checks peppered around the code.
7449 if (value instanceof MediaError) {
7453 if (typeof value === 'number') {
7455 } else if (typeof value === 'string') {
7456 // default code is zero, so this is a custom error
7457 this.message = value;
7458 } else if ((0, _obj.isObject)(value)) {
7460 // We assign the `code` property manually because native `MediaError` objects
7461 // do not expose it as an own/enumerable property of the object.
7462 if (typeof value.code === 'number') {
7463 this.code = value.code;
7466 (0, _obj.assign)(this, value);
7469 if (!this.message) {
7470 this.message = MediaError.defaultMessages[this.code] || '';
7475 * The error code that refers two one of the defined `MediaError` types
7480 * @file media-error.js
7482 MediaError.prototype.code = 0;
7485 * An optional message that to show with the error. Message is not part of the HTML5
7486 * video spec but allows for more informative custom errors.
7490 MediaError.prototype.message = '';
7493 * An optional status code that can be set by plugins to allow even more detail about
7494 * the error. For example a plugin might provide a specific HTTP status code and an
7495 * error message for that code. Then when the plugin gets that error this class will
7496 * know how to display an error message for it. This allows a custom message to show
7497 * up on the `Player` error overlay.
7501 MediaError.prototype.status = null;
7504 * Errors indexed by the W3C standard. The order **CANNOT CHANGE**! See the
7505 * specification listed under {@link MediaError} for more information.
7509 * @property {string} 0 - MEDIA_ERR_CUSTOM
7510 * @property {string} 1 - MEDIA_ERR_CUSTOM
7511 * @property {string} 2 - MEDIA_ERR_ABORTED
7512 * @property {string} 3 - MEDIA_ERR_NETWORK
7513 * @property {string} 4 - MEDIA_ERR_SRC_NOT_SUPPORTED
7514 * @property {string} 5 - MEDIA_ERR_ENCRYPTED
7516 MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED'];
7519 * The default `MediaError` messages based on the {@link MediaError.errorTypes}.
7524 MediaError.defaultMessages = {
7525 1: 'You aborted the media playback',
7526 2: 'A network error caused the media download to fail part-way.',
7527 3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.',
7528 4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.',
7529 5: 'The media is encrypted and we do not have the keys to decrypt it.'
7532 // Add types as properties on MediaError
7533 // e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
7534 for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) {
7535 MediaError[MediaError.errorTypes[errNum]] = errNum;
7536 // values should be accessible on both the class and instance
7537 MediaError.prototype[MediaError.errorTypes[errNum]] = errNum;
7540 // jsdocs for instance/static members added above
7541 // instance methods use `#` and static methods use `.`
7543 * W3C error code for any custom error.
7545 * @member MediaError#MEDIA_ERR_CUSTOM
7546 * @constant {number}
7550 * W3C error code for any custom error.
7552 * @member MediaError.MEDIA_ERR_CUSTOM
7553 * @constant {number}
7558 * W3C error code for media error aborted.
7560 * @member MediaError#MEDIA_ERR_ABORTED
7561 * @constant {number}
7565 * W3C error code for media error aborted.
7567 * @member MediaError.MEDIA_ERR_ABORTED
7568 * @constant {number}
7573 * W3C error code for any network error.
7575 * @member MediaError#MEDIA_ERR_NETWORK
7576 * @constant {number}
7580 * W3C error code for any network error.
7582 * @member MediaError.MEDIA_ERR_NETWORK
7583 * @constant {number}
7588 * W3C error code for any decoding error.
7590 * @member MediaError#MEDIA_ERR_DECODE
7591 * @constant {number}
7595 * W3C error code for any decoding error.
7597 * @member MediaError.MEDIA_ERR_DECODE
7598 * @constant {number}
7603 * W3C error code for any time that a source is not supported.
7605 * @member MediaError#MEDIA_ERR_SRC_NOT_SUPPORTED
7606 * @constant {number}
7610 * W3C error code for any time that a source is not supported.
7612 * @member MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED
7613 * @constant {number}
7618 * W3C error code for any time that a source is encrypted.
7620 * @member MediaError#MEDIA_ERR_ENCRYPTED
7621 * @constant {number}
7625 * W3C error code for any time that a source is encrypted.
7627 * @member MediaError.MEDIA_ERR_ENCRYPTED
7628 * @constant {number}
7632 exports['default'] = MediaError;
7634 },{"88":88}],47:[function(_dereq_,module,exports){
7637 exports.__esModule = true;
7639 var _clickableComponent = _dereq_(3);
7641 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
7643 var _component = _dereq_(5);
7645 var _component2 = _interopRequireDefault(_component);
7647 var _menu = _dereq_(49);
7649 var _menu2 = _interopRequireDefault(_menu);
7651 var _dom = _dereq_(81);
7653 var Dom = _interopRequireWildcard(_dom);
7655 var _fn = _dereq_(83);
7657 var Fn = _interopRequireWildcard(_fn);
7659 var _toTitleCase = _dereq_(91);
7661 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
7663 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; } }
7665 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
7667 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7669 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; }
7671 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; } /**
7672 * @file menu-button.js
7677 * A `MenuButton` class for any popup {@link Menu}.
7679 * @extends ClickableComponent
7681 var MenuButton = function (_ClickableComponent) {
7682 _inherits(MenuButton, _ClickableComponent);
7685 * Creates an instance of this class.
7687 * @param {Player} player
7688 * The `Player` that this class should be attached to.
7690 * @param {Object} [options={}]
7691 * The key/value store of player options.
7693 function MenuButton(player) {
7694 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7696 _classCallCheck(this, MenuButton);
7698 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
7702 _this.enabled_ = true;
7704 _this.el_.setAttribute('aria-haspopup', 'true');
7705 _this.el_.setAttribute('role', 'menuitem');
7706 _this.on('keydown', _this.handleSubmenuKeyPress);
7711 * Update the menu based on the current state of its items.
7715 MenuButton.prototype.update = function update() {
7716 var menu = this.createMenu();
7719 this.removeChild(this.menu);
7723 this.addChild(menu);
7726 * Track the state of the menu button
7731 this.buttonPressed_ = false;
7732 this.el_.setAttribute('aria-expanded', 'false');
7734 if (this.items && this.items.length <= this.hideThreshold_) {
7742 * Create the menu and add all items to it.
7745 * The constructed menu
7749 MenuButton.prototype.createMenu = function createMenu() {
7750 var menu = new _menu2['default'](this.player_);
7753 * Hide the menu if the number of items is less than or equal to this threshold. This defaults
7754 * to 0 and whenever we add items which can be hidden to the menu we'll increment it. We list
7755 * it here because every time we run `createMenu` we need to reset the value.
7760 this.hideThreshold_ = 0;
7762 // Add a title list item to the top
7763 if (this.options_.title) {
7764 var title = Dom.createEl('li', {
7765 className: 'vjs-menu-title',
7766 innerHTML: (0, _toTitleCase2['default'])(this.options_.title),
7770 this.hideThreshold_ += 1;
7772 menu.children_.unshift(title);
7773 Dom.insertElFirst(title, menu.contentEl());
7776 this.items = this.createItems();
7779 // Add menu items to the menu
7780 for (var i = 0; i < this.items.length; i++) {
7781 menu.addItem(this.items[i]);
7789 * Create the list of menu items. Specific to each subclass.
7795 MenuButton.prototype.createItems = function createItems() {};
7798 * Create the `MenuButtons`s DOM element.
7801 * The element that gets created.
7805 MenuButton.prototype.createEl = function createEl() {
7806 return _ClickableComponent.prototype.createEl.call(this, 'div', {
7807 className: this.buildCSSClass()
7812 * Builds the default DOM `className`.
7815 * The DOM `className` for this object.
7819 MenuButton.prototype.buildCSSClass = function buildCSSClass() {
7820 var menuButtonClass = 'vjs-menu-button';
7822 // If the inline option is passed, we want to use different styles altogether.
7823 if (this.options_.inline === true) {
7824 menuButtonClass += '-inline';
7826 menuButtonClass += '-popup';
7829 return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
7833 * Handle a click on a `MenuButton`.
7834 * See {@link ClickableComponent#handleClick} for instances where this is called.
7836 * @param {EventTarget~Event} event
7837 * The `keydown`, `tap`, or `click` event that caused this function to be
7845 MenuButton.prototype.handleClick = function handleClick(event) {
7846 // When you click the button it adds focus, which will show the menu.
7847 // So we'll remove focus when the mouse leaves the button. Focus is needed
7848 // for tab navigation.
7850 this.one(this.menu.contentEl(), 'mouseleave', Fn.bind(this, function (e) {
7851 this.unpressButton();
7854 if (this.buttonPressed_) {
7855 this.unpressButton();
7862 * Handle tab, escape, down arrow, and up arrow keys for `MenuButton`. See
7863 * {@link ClickableComponent#handleKeyPress} for instances where this is called.
7865 * @param {EventTarget~Event} event
7866 * The `keydown` event that caused this function to be called.
7872 MenuButton.prototype.handleKeyPress = function handleKeyPress(event) {
7874 // Escape (27) key or Tab (9) key unpress the 'button'
7875 if (event.which === 27 || event.which === 9) {
7876 if (this.buttonPressed_) {
7877 this.unpressButton();
7879 // Don't preventDefault for Tab key - we still want to lose focus
7880 if (event.which !== 9) {
7881 event.preventDefault();
7883 // Up (38) key or Down (40) key press the 'button'
7884 } else if (event.which === 38 || event.which === 40) {
7885 if (!this.buttonPressed_) {
7887 event.preventDefault();
7890 _ClickableComponent.prototype.handleKeyPress.call(this, event);
7895 * Handle a `keydown` event on a sub-menu. The listener for this is added in
7898 * @param {EventTarget~Event} event
7905 MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) {
7907 // Escape (27) key or Tab (9) key unpress the 'button'
7908 if (event.which === 27 || event.which === 9) {
7909 if (this.buttonPressed_) {
7910 this.unpressButton();
7912 // Don't preventDefault for Tab key - we still want to lose focus
7913 if (event.which !== 9) {
7914 event.preventDefault();
7920 * Put the current `MenuButton` into a pressed state.
7924 MenuButton.prototype.pressButton = function pressButton() {
7925 if (this.enabled_) {
7926 this.buttonPressed_ = true;
7927 this.menu.lockShowing();
7928 this.el_.setAttribute('aria-expanded', 'true');
7929 // set the focus into the submenu
7935 * Take the current `MenuButton` out of a pressed state.
7939 MenuButton.prototype.unpressButton = function unpressButton() {
7940 if (this.enabled_) {
7941 this.buttonPressed_ = false;
7942 this.menu.unlockShowing();
7943 this.el_.setAttribute('aria-expanded', 'false');
7944 // Set focus back to this menu button
7950 * Disable the `MenuButton`. Don't allow it to be clicked.
7952 * @return {MenuButton}
7953 * Returns itself; method can be chained.
7957 MenuButton.prototype.disable = function disable() {
7958 // Unpress, but don't force focus on this button
7959 this.buttonPressed_ = false;
7960 this.menu.unlockShowing();
7961 this.el_.setAttribute('aria-expanded', 'false');
7963 this.enabled_ = false;
7965 return _ClickableComponent.prototype.disable.call(this);
7969 * Enable the `MenuButton`. Allow it to be clicked.
7971 * @return {MenuButton}
7972 * Returns itself; method can be chained.
7976 MenuButton.prototype.enable = function enable() {
7977 this.enabled_ = true;
7979 return _ClickableComponent.prototype.enable.call(this);
7983 }(_clickableComponent2['default']);
7985 _component2['default'].registerComponent('MenuButton', MenuButton);
7986 exports['default'] = MenuButton;
7988 },{"3":3,"49":49,"5":5,"81":81,"83":83,"91":91}],48:[function(_dereq_,module,exports){
7991 exports.__esModule = true;
7993 var _clickableComponent = _dereq_(3);
7995 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
7997 var _component = _dereq_(5);
7999 var _component2 = _interopRequireDefault(_component);
8001 var _obj = _dereq_(88);
8003 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8005 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8007 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; }
8009 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; } /**
8010 * @file menu-item.js
8015 * The component for a menu item. `<li>`
8017 * @extends ClickableComponent
8019 var MenuItem = function (_ClickableComponent) {
8020 _inherits(MenuItem, _ClickableComponent);
8023 * Creates an instance of the this class.
8025 * @param {Player} player
8026 * The `Player` that this class should be attached to.
8028 * @param {Object} [options={}]
8029 * The key/value store of player options.
8032 function MenuItem(player, options) {
8033 _classCallCheck(this, MenuItem);
8035 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
8037 _this.selectable = options.selectable;
8039 _this.selected(options.selected);
8041 if (_this.selectable) {
8042 // TODO: May need to be either menuitemcheckbox or menuitemradio,
8043 // and may need logical grouping of menu items.
8044 _this.el_.setAttribute('role', 'menuitemcheckbox');
8046 _this.el_.setAttribute('role', 'menuitem');
8052 * Create the `MenuItem's DOM element
8054 * @param {string} [type=li]
8055 * Element's node type, not actually used, always set to `li`.
8057 * @param {Object} [props={}]
8058 * An object of properties that should be set on the element
8060 * @param {Object} [attrs={}]
8061 * An object of attributes that should be set on the element
8064 * The element that gets created.
8068 MenuItem.prototype.createEl = function createEl(type, props, attrs) {
8069 // The control is textual, not just an icon
8070 this.nonIconControl = true;
8072 return _ClickableComponent.prototype.createEl.call(this, 'li', (0, _obj.assign)({
8073 className: 'vjs-menu-item',
8074 innerHTML: this.localize(this.options_.label),
8080 * Any click on a `MenuItem` puts int into the selected state.
8081 * See {@link ClickableComponent#handleClick} for instances where this is called.
8083 * @param {EventTarget~Event} event
8084 * The `keydown`, `tap`, or `click` event that caused this function to be
8092 MenuItem.prototype.handleClick = function handleClick(event) {
8093 this.selected(true);
8097 * Set the state for this menu item as selected or not.
8099 * @param {boolean} selected
8100 * if the menu item is selected or not
8104 MenuItem.prototype.selected = function selected(_selected) {
8105 if (this.selectable) {
8107 this.addClass('vjs-selected');
8108 this.el_.setAttribute('aria-checked', 'true');
8109 // aria-checked isn't fully supported by browsers/screen readers,
8110 // so indicate selected state to screen reader in the control text.
8111 this.controlText(', selected');
8113 this.removeClass('vjs-selected');
8114 this.el_.setAttribute('aria-checked', 'false');
8115 // Indicate un-selected state to screen reader
8116 // Note that a space clears out the selected state text
8117 this.controlText(' ');
8123 }(_clickableComponent2['default']);
8125 _component2['default'].registerComponent('MenuItem', MenuItem);
8126 exports['default'] = MenuItem;
8128 },{"3":3,"5":5,"88":88}],49:[function(_dereq_,module,exports){
8131 exports.__esModule = true;
8133 var _component = _dereq_(5);
8135 var _component2 = _interopRequireDefault(_component);
8137 var _dom = _dereq_(81);
8139 var Dom = _interopRequireWildcard(_dom);
8141 var _fn = _dereq_(83);
8143 var Fn = _interopRequireWildcard(_fn);
8145 var _events = _dereq_(82);
8147 var Events = _interopRequireWildcard(_events);
8149 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; } }
8151 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8153 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8155 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; }
8157 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; } /**
8163 * The Menu component is used to build popup menus, including subtitle and
8164 * captions selection menus.
8166 * @extends Component
8168 var Menu = function (_Component) {
8169 _inherits(Menu, _Component);
8172 * Create an instance of this class.
8174 * @param {Player} player
8175 * the player that this component should attach to
8177 * @param {Object} [options]
8178 * Object of option names and values
8181 function Menu(player, options) {
8182 _classCallCheck(this, Menu);
8184 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
8186 _this.focusedChild_ = -1;
8188 _this.on('keydown', _this.handleKeyPress);
8193 * Add a {@link MenuItem} to the menu.
8195 * @param {Object|string} component
8196 * The name or instance of the `MenuItem` to add.
8201 Menu.prototype.addItem = function addItem(component) {
8202 this.addChild(component);
8203 component.on('click', Fn.bind(this, function (event) {
8204 this.unlockShowing();
8205 // TODO: Need to set keyboard focus back to the menuButton
8210 * Create the `Menu`s DOM element.
8213 * the element that was created
8217 Menu.prototype.createEl = function createEl() {
8218 var contentElType = this.options_.contentElType || 'ul';
8220 this.contentEl_ = Dom.createEl(contentElType, {
8221 className: 'vjs-menu-content'
8224 this.contentEl_.setAttribute('role', 'menu');
8226 var el = _Component.prototype.createEl.call(this, 'div', {
8227 append: this.contentEl_,
8228 className: 'vjs-menu'
8231 el.setAttribute('role', 'presentation');
8232 el.appendChild(this.contentEl_);
8234 // Prevent clicks from bubbling up. Needed for Menu Buttons,
8235 // where a click on the parent is significant
8236 Events.on(el, 'click', function (event) {
8237 event.preventDefault();
8238 event.stopImmediatePropagation();
8245 * Handle a `keydown` event on this menu. This listener is added in the constructor.
8247 * @param {EventTarget~Event} event
8248 * A `keydown` event that happened on the menu.
8254 Menu.prototype.handleKeyPress = function handleKeyPress(event) {
8255 // Left and Down Arrows
8256 if (event.which === 37 || event.which === 40) {
8257 event.preventDefault();
8260 // Up and Right Arrows
8261 } else if (event.which === 38 || event.which === 39) {
8262 event.preventDefault();
8268 * Move to next (lower) menu item for keyboard users.
8272 Menu.prototype.stepForward = function stepForward() {
8275 if (this.focusedChild_ !== undefined) {
8276 stepChild = this.focusedChild_ + 1;
8278 this.focus(stepChild);
8282 * Move to previous (higher) menu item for keyboard users.
8286 Menu.prototype.stepBack = function stepBack() {
8289 if (this.focusedChild_ !== undefined) {
8290 stepChild = this.focusedChild_ - 1;
8292 this.focus(stepChild);
8296 * Set focus on a {@link MenuItem} in the `Menu`.
8298 * @param {Object|string} [item=0]
8299 * Index of child item set focus on.
8303 Menu.prototype.focus = function focus() {
8304 var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
8306 var children = this.children().slice();
8307 var haveTitle = children.length && children[0].className && /vjs-menu-title/.test(children[0].className);
8313 if (children.length > 0) {
8316 } else if (item >= children.length) {
8317 item = children.length - 1;
8320 this.focusedChild_ = item;
8322 children[item].el_.focus();
8327 }(_component2['default']);
8329 _component2['default'].registerComponent('Menu', Menu);
8330 exports['default'] = Menu;
8332 },{"5":5,"81":81,"82":82,"83":83}],50:[function(_dereq_,module,exports){
8335 exports.__esModule = true;
8337 var _dom = _dereq_(81);
8339 var Dom = _interopRequireWildcard(_dom);
8341 var _fn = _dereq_(83);
8343 var Fn = _interopRequireWildcard(_fn);
8345 var _component = _dereq_(5);
8347 var _component2 = _interopRequireDefault(_component);
8349 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8351 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; } }
8353 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8355 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; }
8357 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; } /**
8358 * @file modal-dialog.js
8362 var MODAL_CLASS_NAME = 'vjs-modal-dialog';
8366 * The `ModalDialog` displays over the video and its controls, which blocks
8367 * interaction with the player until it is closed.
8369 * Modal dialogs include a "Close" button and will close when that button
8370 * is activated - or when ESC is pressed anywhere.
8372 * @extends Component
8375 var ModalDialog = function (_Component) {
8376 _inherits(ModalDialog, _Component);
8379 * Create an instance of this class.
8381 * @param {Player} player
8382 * The `Player` that this class should be attached to.
8384 * @param {Object} [options]
8385 * The key/value store of player options.
8387 * @param {Mixed} [options.content=undefined]
8388 * Provide customized content for this modal.
8390 * @param {string} [options.description]
8391 * A text description for the modal, primarily for accessibility.
8393 * @param {boolean} [options.fillAlways=false]
8394 * Normally, modals are automatically filled only the first time
8395 * they open. This tells the modal to refresh its content
8396 * every time it opens.
8398 * @param {string} [options.label]
8399 * A text label for the modal, primarily for accessibility.
8401 * @param {boolean} [options.temporary=true]
8402 * If `true`, the modal can only be opened once; it will be
8403 * disposed as soon as it's closed.
8405 * @param {boolean} [options.uncloseable=false]
8406 * If `true`, the user will not be able to close the modal
8407 * through the UI in the normal ways. Programmatic closing is
8410 function ModalDialog(player, options) {
8411 _classCallCheck(this, ModalDialog);
8413 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
8415 _this.opened_ = _this.hasBeenOpened_ = _this.hasBeenFilled_ = false;
8417 _this.closeable(!_this.options_.uncloseable);
8418 _this.content(_this.options_.content);
8420 // Make sure the contentEl is defined AFTER any children are initialized
8421 // because we only want the contents of the modal in the contentEl
8422 // (not the UI elements like the close button).
8423 _this.contentEl_ = Dom.createEl('div', {
8424 className: MODAL_CLASS_NAME + '-content'
8429 _this.descEl_ = Dom.createEl('p', {
8430 className: MODAL_CLASS_NAME + '-description vjs-offscreen',
8431 id: _this.el().getAttribute('aria-describedby')
8434 Dom.textContent(_this.descEl_, _this.description());
8435 _this.el_.appendChild(_this.descEl_);
8436 _this.el_.appendChild(_this.contentEl_);
8441 * Create the `ModalDialog`'s DOM element
8444 * The DOM element that gets created.
8448 ModalDialog.prototype.createEl = function createEl() {
8449 return _Component.prototype.createEl.call(this, 'div', {
8450 className: this.buildCSSClass(),
8453 'aria-describedby': this.id() + '_description',
8454 'aria-hidden': 'true',
8455 'aria-label': this.label(),
8461 * Builds the default DOM `className`.
8464 * The DOM `className` for this object.
8468 ModalDialog.prototype.buildCSSClass = function buildCSSClass() {
8469 return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this);
8473 * Handles `keydown` events on the document, looking for ESC, which closes
8476 * @param {EventTarget~Event} e
8477 * The keypress that triggered this event.
8483 ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) {
8484 if (e.which === ESC && this.closeable()) {
8490 * Returns the label string for this modal. Primarily used for accessibility.
8493 * the localized or raw label of this modal.
8497 ModalDialog.prototype.label = function label() {
8498 return this.options_.label || this.localize('Modal Window');
8502 * Returns the description string for this modal. Primarily used for
8506 * The localized or raw description of this modal.
8510 ModalDialog.prototype.description = function description() {
8511 var desc = this.options_.description || this.localize('This is a modal window.');
8513 // Append a universal closeability message if the modal is closeable.
8514 if (this.closeable()) {
8515 desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.');
8524 * @fires ModalDialog#beforemodalopen
8525 * @fires ModalDialog#modalopen
8527 * @return {ModalDialog}
8528 * Returns itself; method can be chained.
8532 ModalDialog.prototype.open = function open() {
8533 if (!this.opened_) {
8534 var player = this.player();
8537 * Fired just before a `ModalDialog` is opened.
8539 * @event ModalDialog#beforemodalopen
8540 * @type {EventTarget~Event}
8542 this.trigger('beforemodalopen');
8543 this.opened_ = true;
8545 // Fill content if the modal has never opened before and
8546 // never been filled.
8547 if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) {
8551 // If the player was playing, pause it and take note of its previously
8553 this.wasPlaying_ = !player.paused();
8555 if (this.options_.pauseOnOpen && this.wasPlaying_) {
8559 if (this.closeable()) {
8560 this.on(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
8563 player.controls(false);
8565 this.el().setAttribute('aria-hidden', 'false');
8568 * Fired just after a `ModalDialog` is opened.
8570 * @event ModalDialog#modalopen
8571 * @type {EventTarget~Event}
8573 this.trigger('modalopen');
8574 this.hasBeenOpened_ = true;
8580 * If the `ModalDialog` is currently open or closed.
8582 * @param {boolean} [value]
8583 * If given, it will open (`true`) or close (`false`) the modal.
8586 * the current open state of the modaldialog
8590 ModalDialog.prototype.opened = function opened(value) {
8591 if (typeof value === 'boolean') {
8592 this[value ? 'open' : 'close']();
8594 return this.opened_;
8598 * Closes the modal, does nothing if the `ModalDialog` is
8601 * @fires ModalDialog#beforemodalclose
8602 * @fires ModalDialog#modalclose
8604 * @return {ModalDialog}
8605 * Returns itself; method can be chained.
8609 ModalDialog.prototype.close = function close() {
8611 var player = this.player();
8614 * Fired just before a `ModalDialog` is closed.
8616 * @event ModalDialog#beforemodalclose
8617 * @type {EventTarget~Event}
8619 this.trigger('beforemodalclose');
8620 this.opened_ = false;
8622 if (this.wasPlaying_ && this.options_.pauseOnOpen) {
8626 if (this.closeable()) {
8627 this.off(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
8630 player.controls(true);
8632 this.el().setAttribute('aria-hidden', 'true');
8635 * Fired just after a `ModalDialog` is closed.
8637 * @event ModalDialog#modalclose
8638 * @type {EventTarget~Event}
8640 this.trigger('modalclose');
8642 if (this.options_.temporary) {
8650 * Check to see if the `ModalDialog` is closeable via the UI.
8652 * @param {boolean} [value]
8653 * If given as a boolean, it will set the `closeable` option.
8656 * Returns the final value of the closable option.
8660 ModalDialog.prototype.closeable = function closeable(value) {
8661 if (typeof value === 'boolean') {
8662 var closeable = this.closeable_ = !!value;
8663 var close = this.getChild('closeButton');
8665 // If this is being made closeable and has no close button, add one.
8666 if (closeable && !close) {
8668 // The close button should be a child of the modal - not its
8669 // content element, so temporarily change the content element.
8670 var temp = this.contentEl_;
8672 this.contentEl_ = this.el_;
8673 close = this.addChild('closeButton', { controlText: 'Close Modal Dialog' });
8674 this.contentEl_ = temp;
8675 this.on(close, 'close', this.close);
8678 // If this is being made uncloseable and has a close button, remove it.
8679 if (!closeable && close) {
8680 this.off(close, 'close', this.close);
8681 this.removeChild(close);
8685 return this.closeable_;
8689 * Fill the modal's content element with the modal's "content" option.
8690 * The content element will be emptied before this change takes place.
8692 * @return {ModalDialog}
8693 * Returns itself; method can be chained.
8697 ModalDialog.prototype.fill = function fill() {
8698 return this.fillWith(this.content());
8702 * Fill the modal's content element with arbitrary content.
8703 * The content element will be emptied before this change takes place.
8705 * @fires ModalDialog#beforemodalfill
8706 * @fires ModalDialog#modalfill
8708 * @param {Mixed} [content]
8709 * The same rules apply to this as apply to the `content` option.
8711 * @return {ModalDialog}
8712 * Returns itself; method can be chained.
8716 ModalDialog.prototype.fillWith = function fillWith(content) {
8717 var contentEl = this.contentEl();
8718 var parentEl = contentEl.parentNode;
8719 var nextSiblingEl = contentEl.nextSibling;
8722 * Fired just before a `ModalDialog` is filled with content.
8724 * @event ModalDialog#beforemodalfill
8725 * @type {EventTarget~Event}
8727 this.trigger('beforemodalfill');
8728 this.hasBeenFilled_ = true;
8730 // Detach the content element from the DOM before performing
8731 // manipulation to avoid modifying the live DOM multiple times.
8732 parentEl.removeChild(contentEl);
8734 Dom.insertContent(contentEl, content);
8736 * Fired just after a `ModalDialog` is filled with content.
8738 * @event ModalDialog#modalfill
8739 * @type {EventTarget~Event}
8741 this.trigger('modalfill');
8743 // Re-inject the re-filled content element.
8744 if (nextSiblingEl) {
8745 parentEl.insertBefore(contentEl, nextSiblingEl);
8747 parentEl.appendChild(contentEl);
8754 * Empties the content element. This happens anytime the modal is filled.
8756 * @fires ModalDialog#beforemodalempty
8757 * @fires ModalDialog#modalempty
8759 * @return {ModalDialog}
8760 * Returns itself; method can be chained.
8764 ModalDialog.prototype.empty = function empty() {
8766 * Fired just before a `ModalDialog` is emptied.
8768 * @event ModalDialog#beforemodalempty
8769 * @type {EventTarget~Event}
8771 this.trigger('beforemodalempty');
8772 Dom.emptyEl(this.contentEl());
8775 * Fired just after a `ModalDialog` is emptied.
8777 * @event ModalDialog#modalempty
8778 * @type {EventTarget~Event}
8780 this.trigger('modalempty');
8785 * Gets or sets the modal content, which gets normalized before being
8786 * rendered into the DOM.
8788 * This does not update the DOM or fill the modal, but it is called during
8791 * @param {Mixed} [value]
8792 * If defined, sets the internal content value to be used on the
8793 * next call(s) to `fill`. This value is normalized before being
8794 * inserted. To "clear" the internal content value, pass `null`.
8797 * The current content of the modal dialog
8801 ModalDialog.prototype.content = function content(value) {
8802 if (typeof value !== 'undefined') {
8803 this.content_ = value;
8805 return this.content_;
8809 }(_component2['default']);
8812 * Default options for `ModalDialog` default options.
8819 ModalDialog.prototype.options_ = {
8824 _component2['default'].registerComponent('ModalDialog', ModalDialog);
8825 exports['default'] = ModalDialog;
8827 },{"5":5,"81":81,"83":83}],51:[function(_dereq_,module,exports){
8830 exports.__esModule = true;
8832 var _component = _dereq_(5);
8834 var _component2 = _interopRequireDefault(_component);
8836 var _document = _dereq_(94);
8838 var _document2 = _interopRequireDefault(_document);
8840 var _window = _dereq_(95);
8842 var _window2 = _interopRequireDefault(_window);
8844 var _events = _dereq_(82);
8846 var Events = _interopRequireWildcard(_events);
8848 var _dom = _dereq_(81);
8850 var Dom = _interopRequireWildcard(_dom);
8852 var _fn = _dereq_(83);
8854 var Fn = _interopRequireWildcard(_fn);
8856 var _guid = _dereq_(85);
8858 var Guid = _interopRequireWildcard(_guid);
8860 var _browser = _dereq_(78);
8862 var browser = _interopRequireWildcard(_browser);
8864 var _log = _dereq_(86);
8866 var _log2 = _interopRequireDefault(_log);
8868 var _toTitleCase = _dereq_(91);
8870 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
8872 var _timeRanges = _dereq_(90);
8874 var _buffer = _dereq_(79);
8876 var _stylesheet = _dereq_(89);
8878 var stylesheet = _interopRequireWildcard(_stylesheet);
8880 var _fullscreenApi = _dereq_(44);
8882 var _fullscreenApi2 = _interopRequireDefault(_fullscreenApi);
8884 var _mediaError = _dereq_(46);
8886 var _mediaError2 = _interopRequireDefault(_mediaError);
8888 var _tuple = _dereq_(97);
8890 var _tuple2 = _interopRequireDefault(_tuple);
8892 var _obj = _dereq_(88);
8894 var _mergeOptions = _dereq_(87);
8896 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
8898 var _textTrackListConverter = _dereq_(69);
8900 var _textTrackListConverter2 = _interopRequireDefault(_textTrackListConverter);
8902 var _modalDialog = _dereq_(50);
8904 var _modalDialog2 = _interopRequireDefault(_modalDialog);
8906 var _tech = _dereq_(62);
8908 var _tech2 = _interopRequireDefault(_tech);
8910 var _audioTrackList = _dereq_(63);
8912 var _audioTrackList2 = _interopRequireDefault(_audioTrackList);
8914 var _videoTrackList = _dereq_(76);
8916 var _videoTrackList2 = _interopRequireDefault(_videoTrackList);
8940 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; } }
8942 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8944 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8946 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; }
8948 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; } /**
8951 // Subclasses Component
8954 // The following imports are used only to ensure that the corresponding modules
8955 // are always included in the video.js package. Importing the modules will
8956 // execute them and they will register themselves with video.js.
8959 // Import Html5 tech, at least for disposing the original video tag.
8962 // The following tech events are simply re-triggered
8963 // on the player when they happen
8964 var TECH_EVENTS_RETRIGGER = [
8966 * Fired while the user agent is downloading media data.
8968 * @event Player#progress
8969 * @type {EventTarget~Event}
8972 * Retrigger the `progress` event that was triggered by the {@link Tech}.
8975 * @method Player#handleTechProgress_
8976 * @fires Player#progress
8977 * @listens Tech#progress
8982 * Fires when the loading of an audio/video is aborted.
8984 * @event Player#abort
8985 * @type {EventTarget~Event}
8988 * Retrigger the `abort` event that was triggered by the {@link Tech}.
8991 * @method Player#handleTechAbort_
8992 * @fires Player#abort
8993 * @listens Tech#abort
8998 * Fires when the browser is intentionally not getting media data.
9000 * @event Player#suspend
9001 * @type {EventTarget~Event}
9004 * Retrigger the `suspend` event that was triggered by the {@link Tech}.
9007 * @method Player#handleTechSuspend_
9008 * @fires Player#suspend
9009 * @listens Tech#suspend
9014 * Fires when the current playlist is empty.
9016 * @event Player#emptied
9017 * @type {EventTarget~Event}
9020 * Retrigger the `emptied` event that was triggered by the {@link Tech}.
9023 * @method Player#handleTechEmptied_
9024 * @fires Player#emptied
9025 * @listens Tech#emptied
9029 * Fires when the browser is trying to get media data, but data is not available.
9031 * @event Player#stalled
9032 * @type {EventTarget~Event}
9035 * Retrigger the `stalled` event that was triggered by the {@link Tech}.
9038 * @method Player#handleTechStalled_
9039 * @fires Player#stalled
9040 * @listens Tech#stalled
9045 * Fires when the browser has loaded meta data for the audio/video.
9047 * @event Player#loadedmetadata
9048 * @type {EventTarget~Event}
9051 * Retrigger the `stalled` event that was triggered by the {@link Tech}.
9054 * @method Player#handleTechLoadedmetadata_
9055 * @fires Player#loadedmetadata
9056 * @listens Tech#loadedmetadata
9061 * Fires when the browser has loaded the current frame of the audio/video.
9063 * @event player#loadeddata
9067 * Retrigger the `loadeddata` event that was triggered by the {@link Tech}.
9070 * @method Player#handleTechLoaddeddata_
9071 * @fires Player#loadeddata
9072 * @listens Tech#loadeddata
9077 * Fires when the current playback position has changed.
9079 * @event player#timeupdate
9083 * Retrigger the `timeupdate` event that was triggered by the {@link Tech}.
9086 * @method Player#handleTechTimeUpdate_
9087 * @fires Player#timeupdate
9088 * @listens Tech#timeupdate
9093 * Fires when the playing speed of the audio/video is changed
9095 * @event player#ratechange
9099 * Retrigger the `ratechange` event that was triggered by the {@link Tech}.
9102 * @method Player#handleTechRatechange_
9103 * @fires Player#ratechange
9104 * @listens Tech#ratechange
9109 * Fires when the volume has been changed
9111 * @event player#volumechange
9115 * Retrigger the `volumechange` event that was triggered by the {@link Tech}.
9118 * @method Player#handleTechVolumechange_
9119 * @fires Player#volumechange
9120 * @listens Tech#volumechange
9125 * Fires when the text track has been changed
9127 * @event player#texttrackchange
9131 * Retrigger the `texttrackchange` event that was triggered by the {@link Tech}.
9134 * @method Player#handleTechTexttrackchange_
9135 * @fires Player#texttrackchange
9136 * @listens Tech#texttrackchange
9141 * An instance of the `Player` class is created when any of the Video.js setup methods
9142 * are used to initialize a video.
9144 * After an instance has been created it can be accessed globally in two ways:
9145 * 1. By calling `videojs('example_video_1');`
9146 * 2. By using it directly via `videojs.players.example_video_1;`
9148 * @extends Component
9151 var Player = function (_Component) {
9152 _inherits(Player, _Component);
9155 * Create an instance of this class.
9157 * @param {Element} tag
9158 * The original video DOM element used for configuring options.
9160 * @param {Object} [options]
9161 * Object of option names and values.
9163 * @param {Component~ReadyCallback} [ready]
9164 * Ready callback function.
9166 function Player(tag, options, ready) {
9167 _classCallCheck(this, Player);
9169 // Make sure tag ID exists
9170 tag.id = tag.id || 'vjs_video_' + Guid.newGUID();
9173 // The options argument overrides options set in the video tag
9174 // which overrides globally set options.
9175 // This latter part coincides with the load order
9176 // (tag must exist before Player)
9177 options = (0, _obj.assign)(Player.getTagSettings(tag), options);
9179 // Delay the initialization of children because we need to set up
9180 // player properties first, and can't use `this` before `super()`
9181 options.initChildren = false;
9183 // Same with creating the element
9184 options.createEl = false;
9186 // we don't want the player to report touch activity on itself
9187 // see enableTouchActivity in Component
9188 options.reportTouchActivity = false;
9190 // If language is not set, get the closest lang attribute
9191 if (!options.language) {
9192 if (typeof tag.closest === 'function') {
9193 var closest = tag.closest('[lang]');
9196 options.language = closest.getAttribute('lang');
9201 while (element && element.nodeType === 1) {
9202 if (Dom.getElAttributes(element).hasOwnProperty('lang')) {
9203 options.language = element.getAttribute('lang');
9206 element = element.parentNode;
9211 // Run base component initializing with new options
9213 // if the global option object was accidentally blown away by
9214 // someone, bail early with an informative error
9215 var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready));
9217 if (!_this.options_ || !_this.options_.techOrder || !_this.options_.techOrder.length) {
9218 throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?');
9221 // Store the original tag used to set options
9224 // Store the tag attributes used to restore html5 element
9225 _this.tagAttributes = tag && Dom.getElAttributes(tag);
9227 // Update current language
9228 _this.language(_this.options_.language);
9230 // Update Supported Languages
9231 if (options.languages) {
9232 // Normalise player option languages to lowercase
9233 var languagesToLower = {};
9235 Object.getOwnPropertyNames(options.languages).forEach(function (name) {
9236 languagesToLower[name.toLowerCase()] = options.languages[name];
9238 _this.languages_ = languagesToLower;
9240 _this.languages_ = Player.prototype.options_.languages;
9243 // Cache for video property values.
9247 _this.poster_ = options.poster || '';
9250 _this.controls_ = !!options.controls;
9252 // Original tag settings stored in options
9253 // now remove immediately so native controls don't flash.
9254 // May be turned back on by HTML5 tech if nativeControlsForTouch is true
9255 tag.controls = false;
9258 * Store the internal state of scrubbing
9261 * @return {Boolean} True if the user is scrubbing
9263 _this.scrubbing_ = false;
9265 _this.el_ = _this.createEl();
9267 // We also want to pass the original player options to each component and plugin
9268 // as well so they don't need to reach back into the player for options later.
9269 // We also need to do another copy of this.options_ so we don't end up with
9270 // an infinite loop.
9271 var playerOptionsCopy = (0, _mergeOptions2['default'])(_this.options_);
9274 if (options.plugins) {
9275 var plugins = options.plugins;
9277 Object.getOwnPropertyNames(plugins).forEach(function (name) {
9278 if (typeof this[name] === 'function') {
9279 this[name](plugins[name]);
9281 _log2['default'].error('Unable to find plugin:', name);
9286 _this.options_.playerOptions = playerOptionsCopy;
9288 _this.initChildren();
9290 // Set isAudio based on whether or not an audio tag was used
9291 _this.isAudio(tag.nodeName.toLowerCase() === 'audio');
9293 // Update controls className. Can't do this when the controls are initially
9294 // set because the element doesn't exist yet.
9295 if (_this.controls()) {
9296 _this.addClass('vjs-controls-enabled');
9298 _this.addClass('vjs-controls-disabled');
9301 // Set ARIA label and region role depending on player type
9302 _this.el_.setAttribute('role', 'region');
9303 if (_this.isAudio()) {
9304 _this.el_.setAttribute('aria-label', 'audio player');
9306 _this.el_.setAttribute('aria-label', 'video player');
9309 if (_this.isAudio()) {
9310 _this.addClass('vjs-audio');
9313 if (_this.flexNotSupported_()) {
9314 _this.addClass('vjs-no-flex');
9317 // TODO: Make this smarter. Toggle user state between touching/mousing
9318 // using events, since devices can have both touch and mouse events.
9319 // if (browser.TOUCH_ENABLED) {
9320 // this.addClass('vjs-touch-enabled');
9323 // iOS Safari has broken hover handling
9324 if (!browser.IS_IOS) {
9325 _this.addClass('vjs-workinghover');
9328 // Make player easily findable by ID
9329 Player.players[_this.id_] = _this;
9331 // When the player is first initialized, trigger activity so components
9332 // like the control bar show themselves if needed
9333 _this.userActive(true);
9334 _this.reportUserActivity();
9335 _this.listenForUserActivity_();
9337 _this.on('fullscreenchange', _this.handleFullscreenChange_);
9338 _this.on('stageclick', _this.handleStageClick_);
9343 * Destroys the video player and does any necessary cleanup.
9345 * This is especially helpful if you are dynamically adding and removing videos
9348 * @fires Player#dispose
9352 Player.prototype.dispose = function dispose() {
9354 * Called when the player is being disposed of.
9356 * @event Player#dispose
9357 * @type {EventTarget~Event}
9359 this.trigger('dispose');
9360 // prevent dispose from being called twice
9361 this.off('dispose');
9363 if (this.styleEl_ && this.styleEl_.parentNode) {
9364 this.styleEl_.parentNode.removeChild(this.styleEl_);
9367 // Kill reference to this player
9368 Player.players[this.id_] = null;
9370 if (this.tag && this.tag.player) {
9371 this.tag.player = null;
9374 if (this.el_ && this.el_.player) {
9375 this.el_.player = null;
9379 this.tech_.dispose();
9382 _Component.prototype.dispose.call(this);
9386 * Create the `Player`'s DOM element.
9389 * The DOM element that gets created.
9393 Player.prototype.createEl = function createEl() {
9396 var playerElIngest = this.playerElIngest_ = tag.parentNode && tag.parentNode.hasAttribute && tag.parentNode.hasAttribute('data-vjs-player');
9398 if (playerElIngest) {
9399 el = this.el_ = tag.parentNode;
9401 el = this.el_ = _Component.prototype.createEl.call(this, 'div');
9404 // set tabindex to -1 so we could focus on the player element
9405 tag.setAttribute('tabindex', '-1');
9407 // Remove width/height attrs from tag so CSS can make it 100% width/height
9408 tag.removeAttribute('width');
9409 tag.removeAttribute('height');
9411 // Copy over all the attributes from the tag, including ID and class
9412 // ID will now reference player box, not the video tag
9413 var attrs = Dom.getElAttributes(tag);
9415 Object.getOwnPropertyNames(attrs).forEach(function (attr) {
9416 // workaround so we don't totally break IE7
9417 // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7
9418 if (attr === 'class') {
9419 el.className += ' ' + attrs[attr];
9421 el.setAttribute(attr, attrs[attr]);
9425 // Update tag id/class for use as HTML5 playback tech
9426 // Might think we should do this after embedding in container so .vjs-tech class
9427 // doesn't flash 100% width/height, but class only applies with .video-js parent
9428 tag.playerId = tag.id;
9429 tag.id += '_html5_api';
9430 tag.className = 'vjs-tech';
9432 // Make player findable on elements
9433 tag.player = el.player = this;
9434 // Default state of video is paused
9435 this.addClass('vjs-paused');
9437 // Add a style element in the player that we'll use to set the width/height
9438 // of the player in a way that's still overrideable by CSS, just like the
9440 if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) {
9441 this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions');
9442 var defaultsStyleEl = Dom.$('.vjs-styles-defaults');
9443 var head = Dom.$('head');
9445 head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild);
9448 // Pass in the width/height/aspectRatio options which will update the style el
9449 this.width(this.options_.width);
9450 this.height(this.options_.height);
9451 this.fluid(this.options_.fluid);
9452 this.aspectRatio(this.options_.aspectRatio);
9454 // Hide any links within the video/audio tag, because IE doesn't hide them completely.
9455 var links = tag.getElementsByTagName('a');
9457 for (var i = 0; i < links.length; i++) {
9458 var linkEl = links.item(i);
9460 Dom.addElClass(linkEl, 'vjs-hidden');
9461 linkEl.setAttribute('hidden', 'hidden');
9464 // insertElFirst seems to cause the networkState to flicker from 3 to 2, so
9465 // keep track of the original for later so we can know if the source originally failed
9466 tag.initNetworkState_ = tag.networkState;
9468 // Wrap video tag in div (el/box) container
9469 if (tag.parentNode && !playerElIngest) {
9470 tag.parentNode.insertBefore(el, tag);
9473 // insert the tag as the first child of the player element
9474 // then manually add it to the children array so that this.addChild
9475 // will work properly for other components
9477 // Breaks iPhone, fixed in HTML5 setup.
9478 Dom.insertElFirst(tag, el);
9479 this.children_.unshift(tag);
9487 * A getter/setter for the `Player`'s width.
9489 * @param {number} [value]
9490 * The value to set the `Player's width to.
9493 * The current width of the `Player`.
9497 Player.prototype.width = function width(value) {
9498 return this.dimension('width', value);
9502 * A getter/setter for the `Player`'s height.
9504 * @param {number} [value]
9505 * The value to set the `Player's heigth to.
9508 * The current heigth of the `Player`.
9512 Player.prototype.height = function height(value) {
9513 return this.dimension('height', value);
9517 * A getter/setter for the `Player`'s width & height.
9519 * @param {string} dimension
9520 * This string can be:
9524 * @param {number} [value]
9525 * Value for dimension specified in the first argument.
9527 * @return {Player|number}
9528 * - Returns itself when setting; method can be chained.
9529 * - The dimension arguments value when getting (width/height).
9533 Player.prototype.dimension = function dimension(_dimension, value) {
9534 var privDimension = _dimension + '_';
9536 if (value === undefined) {
9537 return this[privDimension] || 0;
9541 // If an empty string is given, reset the dimension to be automatic
9542 this[privDimension] = undefined;
9544 var parsedVal = parseFloat(value);
9546 if (isNaN(parsedVal)) {
9547 _log2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension);
9551 this[privDimension] = parsedVal;
9554 this.updateStyleEl_();
9559 * A getter/setter/toggler for the vjs-fluid `className` on the `Player`.
9561 * @param {boolean} [bool]
9562 * - A value of true adds the class.
9563 * - A value of false removes the class.
9564 * - No value will toggle the fluid class.
9566 * @return {boolean|undefined}
9567 * - The value of fluid when getting.
9568 * - `undefined` when setting.
9572 Player.prototype.fluid = function fluid(bool) {
9573 if (bool === undefined) {
9574 return !!this.fluid_;
9577 this.fluid_ = !!bool;
9580 this.addClass('vjs-fluid');
9582 this.removeClass('vjs-fluid');
9585 this.updateStyleEl_();
9589 * Get/Set the aspect ratio
9591 * @param {string} [ratio]
9592 * Aspect ratio for player
9594 * @return {string|undefined}
9595 * returns the current aspect ratio when getting
9599 * A getter/setter for the `Player`'s aspect ratio.
9601 * @param {string} [ratio]
9602 * The value to set the `Player's aspect ratio to.
9604 * @return {string|undefined}
9605 * - The current aspect ratio of the `Player` when getting.
9606 * - undefined when setting
9610 Player.prototype.aspectRatio = function aspectRatio(ratio) {
9611 if (ratio === undefined) {
9612 return this.aspectRatio_;
9615 // Check for width:height format
9616 if (!/^\d+\:\d+$/.test(ratio)) {
9617 throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.');
9619 this.aspectRatio_ = ratio;
9621 // We're assuming if you set an aspect ratio you want fluid mode,
9622 // because in fixed mode you could calculate width and height yourself.
9625 this.updateStyleEl_();
9629 * Update styles of the `Player` element (height, width and aspect ratio).
9632 * @listens Tech#loadedmetadata
9636 Player.prototype.updateStyleEl_ = function updateStyleEl_() {
9637 if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE === true) {
9638 var _width = typeof this.width_ === 'number' ? this.width_ : this.options_.width;
9639 var _height = typeof this.height_ === 'number' ? this.height_ : this.options_.height;
9640 var techEl = this.tech_ && this.tech_.el();
9644 techEl.width = _width;
9647 techEl.height = _height;
9655 var height = void 0;
9656 var aspectRatio = void 0;
9657 var idClass = void 0;
9659 // The aspect ratio is either used directly or to calculate width and height.
9660 if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') {
9661 // Use any aspectRatio that's been specifically set
9662 aspectRatio = this.aspectRatio_;
9663 } else if (this.videoWidth() > 0) {
9664 // Otherwise try to get the aspect ratio from the video metadata
9665 aspectRatio = this.videoWidth() + ':' + this.videoHeight();
9667 // Or use a default. The video element's is 2:1, but 16:9 is more common.
9668 aspectRatio = '16:9';
9671 // Get the ratio as a decimal we can use to calculate dimensions
9672 var ratioParts = aspectRatio.split(':');
9673 var ratioMultiplier = ratioParts[1] / ratioParts[0];
9675 if (this.width_ !== undefined) {
9676 // Use any width that's been specifically set
9677 width = this.width_;
9678 } else if (this.height_ !== undefined) {
9679 // Or calulate the width from the aspect ratio if a height has been set
9680 width = this.height_ / ratioMultiplier;
9682 // Or use the video's metadata, or use the video el's default of 300
9683 width = this.videoWidth() || 300;
9686 if (this.height_ !== undefined) {
9687 // Use any height that's been specifically set
9688 height = this.height_;
9690 // Otherwise calculate the height from the ratio and the width
9691 height = width * ratioMultiplier;
9694 // Ensure the CSS class is valid by starting with an alpha character
9695 if (/^[^a-zA-Z]/.test(this.id())) {
9696 idClass = 'dimensions-' + this.id();
9698 idClass = this.id() + '-dimensions';
9701 // Ensure the right class is still on the player for the style element
9702 this.addClass(idClass);
9704 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 ');
9708 * Load/Create an instance of playback {@link Tech} including element
9709 * and API methods. Then append the `Tech` element in `Player` as a child.
9711 * @param {string} techName
9712 * name of the playback technology
9714 * @param {string} source
9721 Player.prototype.loadTech_ = function loadTech_(techName, source) {
9724 // Pause and remove current playback technology
9729 // get rid of the HTML5 video tag as soon as we are using another tech
9730 if (techName !== 'Html5' && this.tag) {
9731 _tech2['default'].getTech('Html5').disposeMediaElement(this.tag);
9732 this.tag.player = null;
9736 this.techName_ = techName;
9738 // Turn off API access because we're loading a new tech that might load asynchronously
9739 this.isReady_ = false;
9741 // Grab tech-specific options from player options and add source and parent element to use.
9742 var techOptions = (0, _obj.assign)({
9744 'nativeControlsForTouch': this.options_.nativeControlsForTouch,
9745 'playerId': this.id(),
9746 'techId': this.id() + '_' + techName + '_api',
9747 'videoTracks': this.videoTracks_,
9748 'textTracks': this.textTracks_,
9749 'audioTracks': this.audioTracks_,
9750 'autoplay': this.options_.autoplay,
9751 'preload': this.options_.preload,
9752 'loop': this.options_.loop,
9753 'muted': this.options_.muted,
9754 'poster': this.poster(),
9755 'language': this.language(),
9756 'playerElIngest': this.playerElIngest_ || false,
9757 'vtt.js': this.options_['vtt.js']
9758 }, this.options_[techName.toLowerCase()]);
9761 techOptions.tag = this.tag;
9765 this.currentType_ = source.type;
9767 if (source.src === this.cache_.src && this.cache_.currentTime > 0) {
9768 techOptions.startTime = this.cache_.currentTime;
9771 this.cache_.sources = null;
9772 this.cache_.source = source;
9773 this.cache_.src = source.src;
9776 // Initialize tech instance
9777 var TechComponent = _tech2['default'].getTech(techName);
9779 // Support old behavior of techs being registered as components.
9780 // Remove once that deprecated behavior is removed.
9781 if (!TechComponent) {
9782 TechComponent = _component2['default'].getComponent(techName);
9784 this.tech_ = new TechComponent(techOptions);
9786 // player.triggerReady is always async, so don't need this to be async
9787 this.tech_.ready(Fn.bind(this, this.handleTechReady_), true);
9789 _textTrackListConverter2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_);
9791 // Listen to all HTML5-defined events and trigger them on the player
9792 TECH_EVENTS_RETRIGGER.forEach(function (event) {
9793 _this2.on(_this2.tech_, event, _this2['handleTech' + (0, _toTitleCase2['default'])(event) + '_']);
9795 this.on(this.tech_, 'loadstart', this.handleTechLoadStart_);
9796 this.on(this.tech_, 'waiting', this.handleTechWaiting_);
9797 this.on(this.tech_, 'canplay', this.handleTechCanPlay_);
9798 this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_);
9799 this.on(this.tech_, 'playing', this.handleTechPlaying_);
9800 this.on(this.tech_, 'ended', this.handleTechEnded_);
9801 this.on(this.tech_, 'seeking', this.handleTechSeeking_);
9802 this.on(this.tech_, 'seeked', this.handleTechSeeked_);
9803 this.on(this.tech_, 'play', this.handleTechPlay_);
9804 this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_);
9805 this.on(this.tech_, 'pause', this.handleTechPause_);
9806 this.on(this.tech_, 'durationchange', this.handleTechDurationChange_);
9807 this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_);
9808 this.on(this.tech_, 'error', this.handleTechError_);
9809 this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_);
9810 this.on(this.tech_, 'posterchange', this.handleTechPosterChange_);
9811 this.on(this.tech_, 'textdata', this.handleTechTextData_);
9813 this.usingNativeControls(this.techGet_('controls'));
9815 if (this.controls() && !this.usingNativeControls()) {
9816 this.addTechControlsListeners_();
9819 // Add the tech element in the DOM if it was not already there
9820 // Make sure to not insert the original video element if using Html5
9821 if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) {
9822 Dom.insertElFirst(this.tech_.el(), this.el());
9825 // Get rid of the original video tag reference after the first tech is loaded
9827 this.tag.player = null;
9833 * Unload and dispose of the current playback {@link Tech}.
9839 Player.prototype.unloadTech_ = function unloadTech_() {
9840 // Save the current text tracks so that we can reuse the same text tracks with the next tech
9841 this.videoTracks_ = this.videoTracks();
9842 this.textTracks_ = this.textTracks();
9843 this.audioTracks_ = this.audioTracks();
9844 this.textTracksJson_ = _textTrackListConverter2['default'].textTracksToJson(this.tech_);
9846 this.isReady_ = false;
9848 this.tech_.dispose();
9854 * Return a reference to the current {@link Tech}, but only if given an object with the
9855 * `IWillNotUseThisInPlugins` property having a true value. This is try and prevent misuse
9856 * of techs by plugins.
9858 * @param {Object} safety
9859 * An object that must contain `{IWillNotUseThisInPlugins: true}`
9861 * @param {boolean} safety.IWillNotUseThisInPlugins
9862 * Must be set to true or else this function will throw an error.
9869 Player.prototype.tech = function tech(safety) {
9870 if (safety && safety.IWillNotUseThisInPlugins) {
9873 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 ';
9875 _window2['default'].alert(errorText);
9876 throw new Error(errorText);
9880 * Set up click and touch listeners for the playback element
9882 * - On desktops: a click on the video itself will toggle playback
9883 * - On mobile devices: a click on the video toggles controls
9884 * which is done by toggling the user state between active and
9886 * - A tap can signal that a user has become active or has become inactive
9887 * e.g. a quick tap on an iPhone movie should reveal the controls. Another
9888 * quick tap should hide them again (signaling the user is in an inactive
9890 * - In addition to this, we still want the user to be considered inactive after
9891 * a few seconds of inactivity.
9893 * > Note: the only part of iOS interaction we can't mimic with this setup
9894 * is a touch and hold on the video element counting as activity in order to
9895 * keep the controls showing, but that shouldn't be an issue. A touch and hold
9896 * on any controls will still keep the user active
9902 Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() {
9903 // Make sure to remove all the previous listeners in case we are called multiple times.
9904 this.removeTechControlsListeners_();
9906 // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
9907 // trigger mousedown/up.
9908 // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object
9909 // Any touch events are set to block the mousedown event from happening
9910 this.on(this.tech_, 'mousedown', this.handleTechClick_);
9912 // If the controls were hidden we don't want that to change without a tap event
9913 // so we'll check if the controls were already showing before reporting user
9915 this.on(this.tech_, 'touchstart', this.handleTechTouchStart_);
9916 this.on(this.tech_, 'touchmove', this.handleTechTouchMove_);
9917 this.on(this.tech_, 'touchend', this.handleTechTouchEnd_);
9919 // The tap listener needs to come after the touchend listener because the tap
9920 // listener cancels out any reportedUserActivity when setting userActive(false)
9921 this.on(this.tech_, 'tap', this.handleTechTap_);
9925 * Remove the listeners used for click and tap controls. This is needed for
9926 * toggling to controls disabled, where a tap/touch should do nothing.
9932 Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() {
9933 // We don't want to just use `this.off()` because there might be other needed
9934 // listeners added by techs that extend this.
9935 this.off(this.tech_, 'tap', this.handleTechTap_);
9936 this.off(this.tech_, 'touchstart', this.handleTechTouchStart_);
9937 this.off(this.tech_, 'touchmove', this.handleTechTouchMove_);
9938 this.off(this.tech_, 'touchend', this.handleTechTouchEnd_);
9939 this.off(this.tech_, 'mousedown', this.handleTechClick_);
9943 * Player waits for the tech to be ready
9949 Player.prototype.handleTechReady_ = function handleTechReady_() {
9950 this.triggerReady();
9952 // Keep the same volume as before
9953 if (this.cache_.volume) {
9954 this.techCall_('setVolume', this.cache_.volume);
9957 // Look if the tech found a higher resolution poster while loading
9958 this.handleTechPosterChange_();
9960 // Update the duration if available
9961 this.handleTechDurationChange_();
9963 // Chrome and Safari both have issues with autoplay.
9964 // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
9965 // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
9966 // This fixes both issues. Need to wait for API, so it updates displays correctly
9967 if ((this.src() || this.currentSrc()) && this.tag && this.options_.autoplay && this.paused()) {
9969 // Chrome Fix. Fixed in Chrome v16.
9970 delete this.tag.poster;
9972 (0, _log2['default'])('deleting tag.poster throws in some browsers', e);
9979 * Retrigger the `loadstart` event that was triggered by the {@link Tech}. This
9980 * function will also trigger {@link Player#firstplay} if it is the first loadstart
9983 * @fires Player#loadstart
9984 * @fires Player#firstplay
9985 * @listens Tech#loadstart
9990 Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() {
9991 // TODO: Update to use `emptied` event instead. See #1277.
9993 this.removeClass('vjs-ended');
9994 this.removeClass('vjs-seeking');
9996 // reset the error state
9999 // If it's already playing we want to trigger a firstplay event now.
10000 // The firstplay event relies on both the play and loadstart events
10001 // which can happen in any order for a new source
10002 if (!this.paused()) {
10004 * Fired when the user agent begins looking for media data
10006 * @event Player#loadstart
10007 * @type {EventTarget~Event}
10009 this.trigger('loadstart');
10010 this.trigger('firstplay');
10012 // reset the hasStarted state
10013 this.hasStarted(false);
10014 this.trigger('loadstart');
10019 * Add/remove the vjs-has-started class
10021 * @fires Player#firstplay
10023 * @param {boolean} hasStarted
10024 * - true: adds the class
10025 * - false: remove the class
10027 * @return {boolean}
10028 * the boolean value of hasStarted
10032 Player.prototype.hasStarted = function hasStarted(_hasStarted) {
10033 if (_hasStarted !== undefined) {
10034 // only update if this is a new value
10035 if (this.hasStarted_ !== _hasStarted) {
10036 this.hasStarted_ = _hasStarted;
10038 this.addClass('vjs-has-started');
10039 // trigger the firstplay event if this newly has played
10040 this.trigger('firstplay');
10042 this.removeClass('vjs-has-started');
10047 return !!this.hasStarted_;
10051 * Fired whenever the media begins or resumes playback
10053 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play}
10054 * @fires Player#play
10055 * @listens Tech#play
10060 Player.prototype.handleTechPlay_ = function handleTechPlay_() {
10061 this.removeClass('vjs-ended');
10062 this.removeClass('vjs-paused');
10063 this.addClass('vjs-playing');
10065 // hide the poster when the user hits play
10066 this.hasStarted(true);
10068 * Triggered whenever an {@link Tech#play} event happens. Indicates that
10069 * playback has started or resumed.
10071 * @event Player#play
10072 * @type {EventTarget~Event}
10074 this.trigger('play');
10078 * Retrigger the `waiting` event that was triggered by the {@link Tech}.
10080 * @fires Player#waiting
10081 * @listens Tech#waiting
10086 Player.prototype.handleTechWaiting_ = function handleTechWaiting_() {
10089 this.addClass('vjs-waiting');
10091 * A readyState change on the DOM element has caused playback to stop.
10093 * @event Player#waiting
10094 * @type {EventTarget~Event}
10096 this.trigger('waiting');
10097 this.one('timeupdate', function () {
10098 return _this3.removeClass('vjs-waiting');
10103 * Retrigger the `canplay` event that was triggered by the {@link Tech}.
10104 * > Note: This is not consistent between browsers. See #1351
10106 * @fires Player#canplay
10107 * @listens Tech#canplay
10112 Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() {
10113 this.removeClass('vjs-waiting');
10115 * The media has a readyState of HAVE_FUTURE_DATA or greater.
10117 * @event Player#canplay
10118 * @type {EventTarget~Event}
10120 this.trigger('canplay');
10124 * Retrigger the `canplaythrough` event that was triggered by the {@link Tech}.
10126 * @fires Player#canplaythrough
10127 * @listens Tech#canplaythrough
10132 Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() {
10133 this.removeClass('vjs-waiting');
10135 * The media has a readyState of HAVE_ENOUGH_DATA or greater. This means that the
10136 * entire media file can be played without buffering.
10138 * @event Player#canplaythrough
10139 * @type {EventTarget~Event}
10141 this.trigger('canplaythrough');
10145 * Retrigger the `playing` event that was triggered by the {@link Tech}.
10147 * @fires Player#playing
10148 * @listens Tech#playing
10153 Player.prototype.handleTechPlaying_ = function handleTechPlaying_() {
10154 this.removeClass('vjs-waiting');
10156 * The media is no longer blocked from playback, and has started playing.
10158 * @event Player#playing
10159 * @type {EventTarget~Event}
10161 this.trigger('playing');
10165 * Retrigger the `seeking` event that was triggered by the {@link Tech}.
10167 * @fires Player#seeking
10168 * @listens Tech#seeking
10173 Player.prototype.handleTechSeeking_ = function handleTechSeeking_() {
10174 this.addClass('vjs-seeking');
10176 * Fired whenever the player is jumping to a new time
10178 * @event Player#seeking
10179 * @type {EventTarget~Event}
10181 this.trigger('seeking');
10185 * Retrigger the `seeked` event that was triggered by the {@link Tech}.
10187 * @fires Player#seeked
10188 * @listens Tech#seeked
10193 Player.prototype.handleTechSeeked_ = function handleTechSeeked_() {
10194 this.removeClass('vjs-seeking');
10196 * Fired when the player has finished jumping to a new time
10198 * @event Player#seeked
10199 * @type {EventTarget~Event}
10201 this.trigger('seeked');
10205 * Retrigger the `firstplay` event that was triggered by the {@link Tech}.
10207 * @fires Player#firstplay
10208 * @listens Tech#firstplay
10209 * @deprecated As of 6.0 passing the `starttime` option to the player will be deprecated
10214 Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() {
10215 // If the first starttime attribute is specified
10216 // then we will start at the given offset in seconds
10217 if (this.options_.starttime) {
10218 _log2['default'].warn('Passing the `starttime` option to the player will be deprecated in 6.0');
10219 this.currentTime(this.options_.starttime);
10222 this.addClass('vjs-has-started');
10224 * Fired the first time a video is played. Not part of the HLS spec, and this is
10225 * probably not the best implementation yet, so use sparingly. If you don't have a
10226 * reason to prevent playback, use `myPlayer.one('play');` instead.
10228 * @event Player#firstplay
10229 * @type {EventTarget~Event}
10231 this.trigger('firstplay');
10235 * Retrigger the `pause` event that was triggered by the {@link Tech}.
10237 * @fires Player#pause
10238 * @listens Tech#pause
10243 Player.prototype.handleTechPause_ = function handleTechPause_() {
10244 this.removeClass('vjs-playing');
10245 this.addClass('vjs-paused');
10247 * Fired whenever the media has been paused
10249 * @event Player#pause
10250 * @type {EventTarget~Event}
10252 this.trigger('pause');
10256 * Retrigger the `ended` event that was triggered by the {@link Tech}.
10258 * @fires Player#ended
10259 * @listens Tech#ended
10264 Player.prototype.handleTechEnded_ = function handleTechEnded_() {
10265 this.addClass('vjs-ended');
10266 if (this.options_.loop) {
10267 this.currentTime(0);
10269 } else if (!this.paused()) {
10274 * Fired when the end of the media resource is reached (currentTime == duration)
10276 * @event Player#ended
10277 * @type {EventTarget~Event}
10279 this.trigger('ended');
10283 * Fired when the duration of the media resource is first known or changed
10285 * @listens Tech#durationchange
10290 Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() {
10291 this.duration(this.techGet_('duration'));
10295 * Handle a click on the media element to play/pause
10297 * @param {EventTarget~Event} event
10298 * the event that caused this function to trigger
10300 * @listens Tech#mousedown
10305 Player.prototype.handleTechClick_ = function handleTechClick_(event) {
10306 // We're using mousedown to detect clicks thanks to Flash, but mousedown
10307 // will also be triggered with right-clicks, so we need to prevent that
10308 if (event.button !== 0) {
10312 // When controls are disabled a click should not toggle playback because
10313 // the click is considered a control
10314 if (this.controls()) {
10315 if (this.paused()) {
10324 * Handle a tap on the media element. It will toggle the user
10325 * activity state, which hides and shows the controls.
10327 * @listens Tech#tap
10332 Player.prototype.handleTechTap_ = function handleTechTap_() {
10333 this.userActive(!this.userActive());
10337 * Handle touch to start
10339 * @listens Tech#touchstart
10344 Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() {
10345 this.userWasActive = this.userActive();
10349 * Handle touch to move
10351 * @listens Tech#touchmove
10356 Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() {
10357 if (this.userWasActive) {
10358 this.reportUserActivity();
10363 * Handle touch to end
10365 * @param {EventTarget~Event} event
10366 * the touchend event that triggered
10369 * @listens Tech#touchend
10374 Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) {
10375 // Stop the mouse events from also happening
10376 event.preventDefault();
10380 * Fired when the player switches in or out of fullscreen mode
10383 * @listens Player#fullscreenchange
10387 Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() {
10388 if (this.isFullscreen()) {
10389 this.addClass('vjs-fullscreen');
10391 this.removeClass('vjs-fullscreen');
10396 * native click events on the SWF aren't triggered on IE11, Win8.1RT
10397 * use stageclick events triggered from inside the SWF instead
10400 * @listens stageclick
10404 Player.prototype.handleStageClick_ = function handleStageClick_() {
10405 this.reportUserActivity();
10409 * Handle Tech Fullscreen Change
10411 * @param {EventTarget~Event} event
10412 * the fullscreenchange event that triggered this function
10414 * @param {Object} data
10415 * the data that was sent with the event
10418 * @listens Tech#fullscreenchange
10419 * @fires Player#fullscreenchange
10423 Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) {
10425 this.isFullscreen(data.isFullscreen);
10428 * Fired when going in and out of fullscreen.
10430 * @event Player#fullscreenchange
10431 * @type {EventTarget~Event}
10433 this.trigger('fullscreenchange');
10437 * Fires when an error occurred during the loading of an audio/video.
10440 * @listens Tech#error
10444 Player.prototype.handleTechError_ = function handleTechError_() {
10445 var error = this.tech_.error();
10451 * Retrigger the `textdata` event that was triggered by the {@link Tech}.
10453 * @fires Player#textdata
10454 * @listens Tech#textdata
10459 Player.prototype.handleTechTextData_ = function handleTechTextData_() {
10462 if (arguments.length > 1) {
10463 data = arguments[1];
10467 * Fires when we get a textdata event from tech
10469 * @event Player#textdata
10470 * @type {EventTarget~Event}
10472 this.trigger('textdata', data);
10476 * Get object for cached values.
10479 * get the current object cache
10483 Player.prototype.getCache = function getCache() {
10484 return this.cache_;
10488 * Pass values to the playback tech
10490 * @param {string} [method]
10491 * the method to call
10493 * @param {Object} arg
10494 * the argument to pass
10500 Player.prototype.techCall_ = function techCall_(method, arg) {
10501 // If it's not ready yet, call method when it is
10502 if (this.tech_ && !this.tech_.isReady_) {
10503 this.tech_.ready(function () {
10507 // Otherwise call method now
10511 this.tech_[method](arg);
10514 (0, _log2['default'])(e);
10521 * Get calls can't wait for the tech, and sometimes don't need to.
10523 * @param {string} method
10526 * @return {Function|undefined}
10527 * the method or undefined
10533 Player.prototype.techGet_ = function techGet_(method) {
10534 if (this.tech_ && this.tech_.isReady_) {
10536 // Flash likes to die and reload when you hide or reposition it.
10537 // In these cases the object methods go away and we get errors.
10538 // When that happens we'll catch the errors and inform tech that it's not ready any more.
10540 return this.tech_[method]();
10542 // When building additional tech libs, an expected method may not be defined yet
10543 if (this.tech_[method] === undefined) {
10544 (0, _log2['default'])('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e);
10546 // When a method isn't available on the object it throws a TypeError
10547 } else if (e.name === 'TypeError') {
10548 (0, _log2['default'])('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e);
10549 this.tech_.isReady_ = false;
10551 (0, _log2['default'])(e);
10561 * start media playback
10564 * A reference to the player object this function was called on
10568 Player.prototype.play = function play() {
10569 // Only calls the tech's play if we already have a src loaded
10570 if (this.src() || this.currentSrc()) {
10571 this.techCall_('play');
10573 this.tech_.one('loadstart', function () {
10582 * Pause the video playback
10585 * A reference to the player object this function was called on
10589 Player.prototype.pause = function pause() {
10590 this.techCall_('pause');
10595 * Check if the player is paused or has yet to play
10597 * @return {boolean}
10598 * - false: if the media is currently playing
10599 * - true: if media is not currently playing
10603 Player.prototype.paused = function paused() {
10604 // The initial state of paused should be true (in Safari it's actually false)
10605 return this.techGet_('paused') === false ? false : true;
10609 * Returns whether or not the user is "scrubbing". Scrubbing is
10610 * when the user has clicked the progress bar handle and is
10611 * dragging it along the progress bar.
10613 * @param {boolean} [isScrubbing]
10614 * wether the user is or is not scrubbing
10616 * @return {boolean|Player}
10617 * A instance of the player that called this function when setting,
10618 * and the value of scrubbing when getting
10622 Player.prototype.scrubbing = function scrubbing(isScrubbing) {
10623 if (isScrubbing !== undefined) {
10624 this.scrubbing_ = !!isScrubbing;
10627 this.addClass('vjs-scrubbing');
10629 this.removeClass('vjs-scrubbing');
10635 return this.scrubbing_;
10639 * Get or set the current time (in seconds)
10641 * @param {number|string} [seconds]
10642 * The time to seek to in seconds
10644 * @return {Player|number}
10645 * - the current time in seconds when getting
10646 * - a reference to the current player object when setting
10650 Player.prototype.currentTime = function currentTime(seconds) {
10651 if (seconds !== undefined) {
10653 this.techCall_('setCurrentTime', seconds);
10658 // cache last currentTime and return. default to 0 seconds
10660 // Caching the currentTime is meant to prevent a massive amount of reads on the tech's
10661 // currentTime when scrubbing, but may not provide much performance benefit afterall.
10662 // Should be tested. Also something has to read the actual current time or the cache will
10663 // never get updated.
10664 this.cache_.currentTime = this.techGet_('currentTime') || 0;
10665 return this.cache_.currentTime;
10669 * Normally gets the length in time of the video in seconds;
10670 * in all but the rarest use cases an argument will NOT be passed to the method
10672 * > **NOTE**: The video must have started loading before the duration can be
10673 * known, and in the case of Flash, may not be known until the video starts
10676 * @fires Player#durationchange
10678 * @param {number} [seconds]
10679 * The duration of the video to set in seconds
10681 * @return {number|Player}
10682 * - The duration of the video in seconds when getting
10683 * - A reference to the player that called this function
10688 Player.prototype.duration = function duration(seconds) {
10689 if (seconds === undefined) {
10690 return this.cache_.duration || 0;
10693 seconds = parseFloat(seconds) || 0;
10695 // Standardize on Inifity for signaling video is live
10697 seconds = Infinity;
10700 if (seconds !== this.cache_.duration) {
10701 // Cache the last set value for optimized scrubbing (esp. Flash)
10702 this.cache_.duration = seconds;
10704 if (seconds === Infinity) {
10705 this.addClass('vjs-live');
10707 this.removeClass('vjs-live');
10710 * @event Player#durationchange
10711 * @type {EventTarget~Event}
10713 this.trigger('durationchange');
10720 * Calculates how much time is left in the video. Not part
10721 * of the native video API.
10724 * The time remaining in seconds
10728 Player.prototype.remainingTime = function remainingTime() {
10729 return this.duration() - this.currentTime();
10733 // Kind of like an array of portions of the video that have been downloaded.
10736 * Get a TimeRange object with an array of the times of the video
10737 * that have been downloaded. If you just want the percent of the
10738 * video that's been downloaded, use bufferedPercent.
10740 * @see [Buffered Spec]{@link http://dev.w3.org/html5/spec/video.html#dom-media-buffered}
10742 * @return {TimeRange}
10743 * A mock TimeRange object (following HTML spec)
10747 Player.prototype.buffered = function buffered() {
10748 var buffered = this.techGet_('buffered');
10750 if (!buffered || !buffered.length) {
10751 buffered = (0, _timeRanges.createTimeRange)(0, 0);
10758 * Get the percent (as a decimal) of the video that's been downloaded.
10759 * This method is not a part of the native HTML video API.
10762 * A decimal between 0 and 1 representing the percent
10763 * that is bufferred 0 being 0% and 1 being 100%
10767 Player.prototype.bufferedPercent = function bufferedPercent() {
10768 return (0, _buffer.bufferedPercent)(this.buffered(), this.duration());
10772 * Get the ending time of the last buffered time range
10773 * This is used in the progress bar to encapsulate all time ranges.
10776 * The end of the last buffered time range
10780 Player.prototype.bufferedEnd = function bufferedEnd() {
10781 var buffered = this.buffered();
10782 var duration = this.duration();
10783 var end = buffered.end(buffered.length - 1);
10785 if (end > duration) {
10793 * Get or set the current volume of the media
10795 * @param {number} [percentAsDecimal]
10796 * The new volume as a decimal percent:
10797 * - 0 is muted/0%/off
10798 * - 1.0 is 100%/full
10799 * - 0.5 is half volume or 50%
10801 * @return {Player|number}
10802 * a reference to the calling player when setting and the
10803 * current volume as a percent when getting
10807 Player.prototype.volume = function volume(percentAsDecimal) {
10810 if (percentAsDecimal !== undefined) {
10811 // Force value to between 0 and 1
10812 vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal)));
10813 this.cache_.volume = vol;
10814 this.techCall_('setVolume', vol);
10819 // Default to 1 when returning current volume.
10820 vol = parseFloat(this.techGet_('volume'));
10821 return isNaN(vol) ? 1 : vol;
10825 * Get the current muted state, or turn mute on or off
10827 * @param {boolean} [muted]
10829 * - false to unmute
10831 * @return {boolean|Player}
10832 * - true if mute is on and getting
10833 * - false if mute is off and getting
10834 * - A reference to the current player when setting
10838 Player.prototype.muted = function muted(_muted) {
10839 if (_muted !== undefined) {
10840 this.techCall_('setMuted', _muted);
10843 return this.techGet_('muted') || false;
10847 * Check if current tech can support native fullscreen
10848 * (e.g. with built in controls like iOS, so not our flash swf)
10850 * @return {boolean}
10851 * if native fullscreen is supported
10855 Player.prototype.supportsFullScreen = function supportsFullScreen() {
10856 return this.techGet_('supportsFullScreen') || false;
10860 * Check if the player is in fullscreen mode or tell the player that it
10861 * is or is not in fullscreen mode.
10863 * > NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official
10864 * property and instead document.fullscreenElement is used. But isFullscreen is
10865 * still a valuable property for internal player workings.
10867 * @param {boolean} [isFS]
10868 * Set the players current fullscreen state
10870 * @return {boolean|Player}
10871 * - true if fullscreen is on and getting
10872 * - false if fullscreen is off and getting
10873 * - A reference to the current player when setting
10877 Player.prototype.isFullscreen = function isFullscreen(isFS) {
10878 if (isFS !== undefined) {
10879 this.isFullscreen_ = !!isFS;
10882 return !!this.isFullscreen_;
10886 * Increase the size of the video to full screen
10887 * In some browsers, full screen is not supported natively, so it enters
10888 * "full window mode", where the video fills the browser window.
10889 * In browsers and devices that support native full screen, sometimes the
10890 * browser's default controls will be shown, and not the Video.js custom skin.
10891 * This includes most mobile devices (iOS, Android) and older versions of
10894 * @fires Player#fullscreenchange
10896 * A reference to the current player
10900 Player.prototype.requestFullscreen = function requestFullscreen() {
10901 var fsApi = _fullscreenApi2['default'];
10903 this.isFullscreen(true);
10905 if (fsApi.requestFullscreen) {
10906 // the browser supports going fullscreen at the element level so we can
10907 // take the controls fullscreen as well as the video
10909 // Trigger fullscreenchange event after change
10910 // We have to specifically add this each time, and remove
10911 // when canceling fullscreen. Otherwise if there's multiple
10912 // players on a page, they would all be reacting to the same fullscreen
10914 Events.on(_document2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) {
10915 this.isFullscreen(_document2['default'][fsApi.fullscreenElement]);
10917 // If cancelling fullscreen, remove event listener.
10918 if (this.isFullscreen() === false) {
10919 Events.off(_document2['default'], fsApi.fullscreenchange, documentFullscreenChange);
10922 * @event Player#fullscreenchange
10923 * @type {EventTarget~Event}
10925 this.trigger('fullscreenchange');
10928 this.el_[fsApi.requestFullscreen]();
10929 } else if (this.tech_.supportsFullScreen()) {
10930 // we can't take the video.js controls fullscreen but we can go fullscreen
10931 // with native controls
10932 this.techCall_('enterFullScreen');
10934 // fullscreen isn't supported so we'll just stretch the video element to
10935 // fill the viewport
10936 this.enterFullWindow();
10938 * @event Player#fullscreenchange
10939 * @type {EventTarget~Event}
10941 this.trigger('fullscreenchange');
10948 * Return the video to its normal size after having been in full screen mode
10950 * @fires Player#fullscreenchange
10953 * A reference to the current player
10957 Player.prototype.exitFullscreen = function exitFullscreen() {
10958 var fsApi = _fullscreenApi2['default'];
10960 this.isFullscreen(false);
10962 // Check for browser element fullscreen support
10963 if (fsApi.requestFullscreen) {
10964 _document2['default'][fsApi.exitFullscreen]();
10965 } else if (this.tech_.supportsFullScreen()) {
10966 this.techCall_('exitFullScreen');
10968 this.exitFullWindow();
10970 * @event Player#fullscreenchange
10971 * @type {EventTarget~Event}
10973 this.trigger('fullscreenchange');
10980 * When fullscreen isn't supported we can stretch the
10981 * video container to as wide as the browser will let us.
10983 * @fires Player#enterFullWindow
10987 Player.prototype.enterFullWindow = function enterFullWindow() {
10988 this.isFullWindow = true;
10990 // Storing original doc overflow value to return to when fullscreen is off
10991 this.docOrigOverflow = _document2['default'].documentElement.style.overflow;
10993 // Add listener for esc key to exit fullscreen
10994 Events.on(_document2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey));
10996 // Hide any scroll bars
10997 _document2['default'].documentElement.style.overflow = 'hidden';
10999 // Apply fullscreen styles
11000 Dom.addElClass(_document2['default'].body, 'vjs-full-window');
11003 * @event Player#enterFullWindow
11004 * @type {EventTarget~Event}
11006 this.trigger('enterFullWindow');
11010 * Check for call to either exit full window or
11011 * full screen on ESC key
11013 * @param {string} event
11014 * Event to check for key press
11018 Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) {
11019 if (event.keyCode === 27) {
11020 if (this.isFullscreen() === true) {
11021 this.exitFullscreen();
11023 this.exitFullWindow();
11031 * @fires Player#exitFullWindow
11035 Player.prototype.exitFullWindow = function exitFullWindow() {
11036 this.isFullWindow = false;
11037 Events.off(_document2['default'], 'keydown', this.fullWindowOnEscKey);
11039 // Unhide scroll bars.
11040 _document2['default'].documentElement.style.overflow = this.docOrigOverflow;
11042 // Remove fullscreen styles
11043 Dom.removeElClass(_document2['default'].body, 'vjs-full-window');
11045 // Resize the box, controller, and poster to original sizes
11046 // this.positionAll();
11048 * @event Player#exitFullWindow
11049 * @type {EventTarget~Event}
11051 this.trigger('exitFullWindow');
11055 * Check whether the player can play a given mimetype
11057 * @see https://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-navigator-canplaytype
11059 * @param {string} type
11060 * The mimetype to check
11063 * 'probably', 'maybe', or '' (empty string)
11067 Player.prototype.canPlayType = function canPlayType(type) {
11070 // Loop through each playback technology in the options order
11071 for (var i = 0, j = this.options_.techOrder; i < j.length; i++) {
11072 var techName = (0, _toTitleCase2['default'])(j[i]);
11073 var tech = _tech2['default'].getTech(techName);
11075 // Support old behavior of techs being registered as components.
11076 // Remove once that deprecated behavior is removed.
11078 tech = _component2['default'].getComponent(techName);
11081 // Check if the current tech is defined before continuing
11083 _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
11087 // Check if the browser supports this technology
11088 if (tech.isSupported()) {
11089 can = tech.canPlayType(type);
11101 * Select source based on tech-order or source-order
11102 * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise,
11103 * defaults to tech-order selection
11105 * @param {Array} sources
11106 * The sources for a media asset
11108 * @return {Object|boolean}
11109 * Object of source and tech order or false
11113 Player.prototype.selectSource = function selectSource(sources) {
11116 // Get only the techs specified in `techOrder` that exist and are supported by the
11117 // current platform
11118 var techs = this.options_.techOrder.map(_toTitleCase2['default']).map(function (techName) {
11119 // `Component.getComponent(...)` is for support of old behavior of techs
11120 // being registered as components.
11121 // Remove once that deprecated behavior is removed.
11122 return [techName, _tech2['default'].getTech(techName) || _component2['default'].getComponent(techName)];
11123 }).filter(function (_ref) {
11124 var techName = _ref[0],
11127 // Check if the current tech is defined before continuing
11129 // Check if the browser supports this technology
11130 return tech.isSupported();
11133 _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
11137 // Iterate over each `innerArray` element once per `outerArray` element and execute
11138 // `tester` with both. If `tester` returns a non-falsy value, exit early and return
11140 var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) {
11141 var found = void 0;
11143 outerArray.some(function (outerChoice) {
11144 return innerArray.some(function (innerChoice) {
11145 found = tester(outerChoice, innerChoice);
11156 var foundSourceAndTech = void 0;
11157 var flip = function flip(fn) {
11158 return function (a, b) {
11162 var finder = function finder(_ref2, source) {
11163 var techName = _ref2[0],
11166 if (tech.canPlaySource(source, _this4.options_[techName.toLowerCase()])) {
11167 return { source: source, tech: techName };
11171 // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources
11172 // to select from them based on their priority.
11173 if (this.options_.sourceOrder) {
11174 // Source-first ordering
11175 foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder));
11177 // Tech-first ordering
11178 foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder);
11181 return foundSourceAndTech || false;
11185 * The source function updates the video source
11186 * There are three types of variables you can pass as the argument.
11187 * **URL string**: A URL to the the video file. Use this method if you are sure
11188 * the current playback technology (HTML5/Flash) can support the source you
11189 * provide. Currently only MP4 files can be used in both HTML5 and Flash.
11191 * @param {Tech~SourceObject|Tech~SourceObject[]} [source]
11192 * One SourceObject or an array of SourceObjects
11194 * @return {string|Player}
11195 * - The current video source when getting
11196 * - The player when setting
11200 Player.prototype.src = function src(source) {
11201 if (source === undefined) {
11202 return this.techGet_('src');
11205 var currentTech = _tech2['default'].getTech(this.techName_);
11207 // Support old behavior of techs being registered as components.
11208 // Remove once that deprecated behavior is removed.
11209 if (!currentTech) {
11210 currentTech = _component2['default'].getComponent(this.techName_);
11213 // case: Array of source objects to choose from and pick the best to play
11214 if (Array.isArray(source)) {
11215 this.sourceList_(source);
11217 // case: URL String (http://myvideo...)
11218 } else if (typeof source === 'string') {
11219 // create a source object from the string
11220 this.src({ src: source });
11222 // case: Source object { src: '', type: '' ... }
11223 } else if (source instanceof Object) {
11224 // check if the source has a type and the loaded tech cannot play the source
11225 // if there's no type we'll just try the current tech
11226 if (source.type && !currentTech.canPlaySource(source, this.options_[this.techName_.toLowerCase()])) {
11227 // create a source list with the current source and send through
11228 // the tech loop to check for a compatible technology
11229 this.sourceList_([source]);
11231 this.cache_.sources = null;
11232 this.cache_.source = source;
11233 this.cache_.src = source.src;
11235 this.currentType_ = source.type || '';
11237 // wait until the tech is ready to set the source
11238 this.ready(function () {
11240 // The setSource tech method was added with source handlers
11241 // so older techs won't support it
11242 // We need to check the direct prototype for the case where subclasses
11243 // of the tech do not support source handlers
11244 if (currentTech.prototype.hasOwnProperty('setSource')) {
11245 this.techCall_('setSource', source);
11247 this.techCall_('src', source.src);
11250 if (this.options_.preload === 'auto') {
11254 if (this.options_.autoplay) {
11258 // Set the source synchronously if possible (#2326)
11267 * Handle an array of source objects
11269 * @param {Tech~SourceObject[]} sources
11270 * Array of source objects
11276 Player.prototype.sourceList_ = function sourceList_(sources) {
11277 var sourceTech = this.selectSource(sources);
11280 if (sourceTech.tech === this.techName_) {
11281 // if this technology is already loaded, set the source
11282 this.src(sourceTech.source);
11284 // load this technology with the chosen source
11285 this.loadTech_(sourceTech.tech, sourceTech.source);
11288 this.cache_.sources = sources;
11290 // We need to wrap this in a timeout to give folks a chance to add error event handlers
11291 this.setTimeout(function () {
11292 this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) });
11295 // we could not find an appropriate tech, but let's still notify the delegate that this is it
11296 // this needs a better comment about why this is needed
11297 this.triggerReady();
11302 * Begin loading the src data.
11305 * A reference to the player
11309 Player.prototype.load = function load() {
11310 this.techCall_('load');
11315 * Reset the player. Loads the first tech in the techOrder,
11316 * and calls `reset` on the tech`.
11319 * A reference to the player
11323 Player.prototype.reset = function reset() {
11324 this.loadTech_((0, _toTitleCase2['default'])(this.options_.techOrder[0]), null);
11325 this.techCall_('reset');
11330 * Returns all of the current source objects.
11332 * @return {Tech~SourceObject[]}
11333 * The current source objects
11337 Player.prototype.currentSources = function currentSources() {
11338 var source = this.currentSource();
11341 // assume `{}` or `{ src }`
11342 if (Object.keys(source).length !== 0) {
11343 sources.push(source);
11346 return this.cache_.sources || sources;
11350 * Returns the current source object.
11352 * @return {Tech~SourceObject}
11353 * The current source object
11357 Player.prototype.currentSource = function currentSource() {
11359 var src = this.currentSrc();
11365 return this.cache_.source || source;
11369 * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4
11370 * Can be used in conjuction with `currentType` to assist in rebuilding the current source object.
11373 * The current source
11377 Player.prototype.currentSrc = function currentSrc() {
11378 return this.techGet_('currentSrc') || this.cache_.src || '';
11382 * Get the current source type e.g. video/mp4
11383 * This can allow you rebuild the current source object so that you could load the same
11384 * source and tech later
11387 * The source MIME type
11391 Player.prototype.currentType = function currentType() {
11392 return this.currentType_ || '';
11396 * Get or set the preload attribute
11398 * @param {boolean} [value]
11399 * - true means that we should preload
11400 * - false maens that we should not preload
11402 * @return {string|Player}
11403 * - the preload attribute value when getting
11404 * - the player when setting
11408 Player.prototype.preload = function preload(value) {
11409 if (value !== undefined) {
11410 this.techCall_('setPreload', value);
11411 this.options_.preload = value;
11414 return this.techGet_('preload');
11418 * Get or set the autoplay attribute.
11420 * @param {boolean} [value]
11421 * - true means that we should autoplay
11422 * - false maens that we should not autoplay
11424 * @return {string|Player}
11425 * - the current value of autoplay
11426 * - the player when setting
11430 Player.prototype.autoplay = function autoplay(value) {
11431 if (value !== undefined) {
11432 this.techCall_('setAutoplay', value);
11433 this.options_.autoplay = value;
11436 return this.techGet_('autoplay', value);
11440 * Get or set the loop attribute on the video element.
11442 * @param {boolean} [value]
11443 * - true means that we should loop the video
11444 * - false means that we should not loop the video
11446 * @return {string|Player}
11447 * - the current value of loop when getting
11448 * - the player when setting
11452 Player.prototype.loop = function loop(value) {
11453 if (value !== undefined) {
11454 this.techCall_('setLoop', value);
11455 this.options_.loop = value;
11458 return this.techGet_('loop');
11462 * Get or set the poster image source url
11464 * @fires Player#posterchange
11466 * @param {string} [src]
11467 * Poster image source URL
11469 * @return {string|Player}
11470 * - the current value of poster when getting
11471 * - the player when setting
11475 Player.prototype.poster = function poster(src) {
11476 if (src === undefined) {
11477 return this.poster_;
11480 // The correct way to remove a poster is to set as an empty string
11481 // other falsey values will throw errors
11486 // update the internal poster variable
11487 this.poster_ = src;
11489 // update the tech's poster
11490 this.techCall_('setPoster', src);
11492 // alert components that the poster has been set
11494 * This event fires when the poster image is changed on the player.
11496 * @event Player#posterchange
11497 * @type {EventTarget~Event}
11499 this.trigger('posterchange');
11505 * Some techs (e.g. YouTube) can provide a poster source in an
11506 * asynchronous way. We want the poster component to use this
11507 * poster source so that it covers up the tech's controls.
11508 * (YouTube's play button). However we only want to use this
11509 * soruce if the player user hasn't set a poster through
11512 * @fires Player#posterchange
11513 * @listens Tech#posterchange
11518 Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() {
11519 if (!this.poster_ && this.tech_ && this.tech_.poster) {
11520 this.poster_ = this.tech_.poster() || '';
11522 // Let components know the poster has changed
11523 this.trigger('posterchange');
11528 * Get or set whether or not the controls are showing.
11530 * @fires Player#controlsenabled
11532 * @param {boolean} [bool]
11533 * - true to turn controls on
11534 * - false to turn controls off
11536 * @return {boolean|Player}
11537 * - the current value of controls when getting
11538 * - the player when setting
11542 Player.prototype.controls = function controls(bool) {
11543 if (bool !== undefined) {
11546 // Don't trigger a change event unless it actually changed
11547 if (this.controls_ !== bool) {
11548 this.controls_ = bool;
11550 if (this.usingNativeControls()) {
11551 this.techCall_('setControls', bool);
11555 this.removeClass('vjs-controls-disabled');
11556 this.addClass('vjs-controls-enabled');
11558 * @event Player#controlsenabled
11559 * @type {EventTarget~Event}
11561 this.trigger('controlsenabled');
11563 if (!this.usingNativeControls()) {
11564 this.addTechControlsListeners_();
11567 this.removeClass('vjs-controls-enabled');
11568 this.addClass('vjs-controls-disabled');
11570 * @event Player#controlsdisabled
11571 * @type {EventTarget~Event}
11573 this.trigger('controlsdisabled');
11575 if (!this.usingNativeControls()) {
11576 this.removeTechControlsListeners_();
11582 return !!this.controls_;
11586 * Toggle native controls on/off. Native controls are the controls built into
11587 * devices (e.g. default iPhone controls), Flash, or other techs
11588 * (e.g. Vimeo Controls)
11589 * **This should only be set by the current tech, because only the tech knows
11590 * if it can support native controls**
11592 * @fires Player#usingnativecontrols
11593 * @fires Player#usingcustomcontrols
11595 * @param {boolean} [bool]
11596 * - true to turn native controls on
11597 * - false to turn native controls off
11599 * @return {boolean|Player}
11600 * - the current value of native controls when getting
11601 * - the player when setting
11605 Player.prototype.usingNativeControls = function usingNativeControls(bool) {
11606 if (bool !== undefined) {
11609 // Don't trigger a change event unless it actually changed
11610 if (this.usingNativeControls_ !== bool) {
11611 this.usingNativeControls_ = bool;
11613 this.addClass('vjs-using-native-controls');
11616 * player is using the native device controls
11618 * @event Player#usingnativecontrols
11619 * @type {EventTarget~Event}
11621 this.trigger('usingnativecontrols');
11623 this.removeClass('vjs-using-native-controls');
11626 * player is using the custom HTML controls
11628 * @event Player#usingcustomcontrols
11629 * @type {EventTarget~Event}
11631 this.trigger('usingcustomcontrols');
11636 return !!this.usingNativeControls_;
11640 * Set or get the current MediaError
11642 * @fires Player#error
11644 * @param {MediaError|string|number} [err]
11645 * A MediaError or a string/number to be turned
11646 * into a MediaError
11648 * @return {MediaError|null|Player}
11649 * - The current MediaError when getting (or null)
11650 * - The player when setting
11654 Player.prototype.error = function error(err) {
11655 if (err === undefined) {
11656 return this.error_ || null;
11659 // restoring to default
11660 if (err === null) {
11662 this.removeClass('vjs-error');
11663 if (this.errorDisplay) {
11664 this.errorDisplay.close();
11669 this.error_ = new _mediaError2['default'](err);
11671 // add the vjs-error classname to the player
11672 this.addClass('vjs-error');
11674 // log the name of the error type and any message
11675 // ie8 just logs "[object object]" if you just log the error object
11676 _log2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaError2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_);
11679 * @event Player#error
11680 * @type {EventTarget~Event}
11682 this.trigger('error');
11688 * Report user activity
11690 * @param {Object} event
11695 Player.prototype.reportUserActivity = function reportUserActivity(event) {
11696 this.userActivity_ = true;
11700 * Get/set if user is active
11702 * @fires Player#useractive
11703 * @fires Player#userinactive
11705 * @param {boolean} [bool]
11706 * - true if the user is active
11707 * - false if the user is inactive
11708 * @return {boolean|Player}
11709 * - the current value of userActive when getting
11710 * - the player when setting
11714 Player.prototype.userActive = function userActive(bool) {
11715 if (bool !== undefined) {
11717 if (bool !== this.userActive_) {
11718 this.userActive_ = bool;
11720 // If the user was inactive and is now active we want to reset the
11721 // inactivity timer
11722 this.userActivity_ = true;
11723 this.removeClass('vjs-user-inactive');
11724 this.addClass('vjs-user-active');
11726 * @event Player#useractive
11727 * @type {EventTarget~Event}
11729 this.trigger('useractive');
11731 // We're switching the state to inactive manually, so erase any other
11733 this.userActivity_ = false;
11735 // Chrome/Safari/IE have bugs where when you change the cursor it can
11736 // trigger a mousemove event. This causes an issue when you're hiding
11737 // the cursor when the user is inactive, and a mousemove signals user
11738 // activity. Making it impossible to go into inactive mode. Specifically
11739 // this happens in fullscreen when we really need to hide the cursor.
11741 // When this gets resolved in ALL browsers it can be removed
11742 // https://code.google.com/p/chromium/issues/detail?id=103041
11744 this.tech_.one('mousemove', function (e) {
11745 e.stopPropagation();
11746 e.preventDefault();
11750 this.removeClass('vjs-user-active');
11751 this.addClass('vjs-user-inactive');
11753 * @event Player#userinactive
11754 * @type {EventTarget~Event}
11756 this.trigger('userinactive');
11761 return this.userActive_;
11765 * Listen for user activity based on timeout value
11771 Player.prototype.listenForUserActivity_ = function listenForUserActivity_() {
11772 var mouseInProgress = void 0;
11773 var lastMoveX = void 0;
11774 var lastMoveY = void 0;
11775 var handleActivity = Fn.bind(this, this.reportUserActivity);
11777 var handleMouseMove = function handleMouseMove(e) {
11778 // #1068 - Prevent mousemove spamming
11779 // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970
11780 if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) {
11781 lastMoveX = e.screenX;
11782 lastMoveY = e.screenY;
11787 var handleMouseDown = function handleMouseDown() {
11789 // For as long as the they are touching the device or have their mouse down,
11790 // we consider them active even if they're not moving their finger or mouse.
11791 // So we want to continue to update that they are active
11792 this.clearInterval(mouseInProgress);
11793 // Setting userActivity=true now and setting the interval to the same time
11794 // as the activityCheck interval (250) should ensure we never miss the
11795 // next activityCheck
11796 mouseInProgress = this.setInterval(handleActivity, 250);
11799 var handleMouseUp = function handleMouseUp(event) {
11801 // Stop the interval that maintains activity if the mouse/touch is down
11802 this.clearInterval(mouseInProgress);
11805 // Any mouse movement will be considered user activity
11806 this.on('mousedown', handleMouseDown);
11807 this.on('mousemove', handleMouseMove);
11808 this.on('mouseup', handleMouseUp);
11810 // Listen for keyboard navigation
11811 // Shouldn't need to use inProgress interval because of key repeat
11812 this.on('keydown', handleActivity);
11813 this.on('keyup', handleActivity);
11815 // Run an interval every 250 milliseconds instead of stuffing everything into
11816 // the mousemove/touchmove function itself, to prevent performance degradation.
11817 // `this.reportUserActivity` simply sets this.userActivity_ to true, which
11818 // then gets picked up by this loop
11819 // http://ejohn.org/blog/learning-from-twitter/
11820 var inactivityTimeout = void 0;
11822 this.setInterval(function () {
11823 // Check to see if mouse/touch activity has happened
11824 if (this.userActivity_) {
11825 // Reset the activity tracker
11826 this.userActivity_ = false;
11828 // If the user state was inactive, set the state to active
11829 this.userActive(true);
11831 // Clear any existing inactivity timeout to start the timer over
11832 this.clearTimeout(inactivityTimeout);
11834 var timeout = this.options_.inactivityTimeout;
11837 // In <timeout> milliseconds, if no more activity has occurred the
11838 // user will be considered inactive
11839 inactivityTimeout = this.setTimeout(function () {
11840 // Protect against the case where the inactivityTimeout can trigger just
11841 // before the next user activity is picked up by the activity check loop
11842 // causing a flicker
11843 if (!this.userActivity_) {
11844 this.userActive(false);
11853 * Gets or sets the current playback rate. A playback rate of
11854 * 1.0 represents normal speed and 0.5 would indicate half-speed
11855 * playback, for instance.
11857 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate
11859 * @param {number} [rate]
11860 * New playback rate to set.
11862 * @return {number|Player}
11863 * - The current playback rate when getting or 1.0
11864 * - the player when setting
11868 Player.prototype.playbackRate = function playbackRate(rate) {
11869 if (rate !== undefined) {
11870 this.techCall_('setPlaybackRate', rate);
11874 if (this.tech_ && this.tech_.featuresPlaybackRate) {
11875 return this.techGet_('playbackRate');
11881 * Gets or sets the audio flag
11883 * @param {boolean} bool
11884 * - true signals that this is an audio player
11885 * - false signals that this is not an audio player
11887 * @return {Player|boolean}
11888 * - the current value of isAudio when getting
11889 * - the player if setting
11893 Player.prototype.isAudio = function isAudio(bool) {
11894 if (bool !== undefined) {
11895 this.isAudio_ = !!bool;
11899 return !!this.isAudio_;
11903 * Get the {@link VideoTrackList}
11905 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist
11907 * @return {VideoTrackList}
11908 * the current video track list
11912 Player.prototype.videoTracks = function videoTracks() {
11913 // if we have not yet loadTech_, we create videoTracks_
11914 // these will be passed to the tech during loading
11916 this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default']();
11917 return this.videoTracks_;
11920 return this.tech_.videoTracks();
11924 * Get the {@link AudioTrackList}
11926 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist
11928 * @return {AudioTrackList}
11929 * the current audio track list
11933 Player.prototype.audioTracks = function audioTracks() {
11934 // if we have not yet loadTech_, we create videoTracks_
11935 // these will be passed to the tech during loading
11937 this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default']();
11938 return this.audioTracks_;
11941 return this.tech_.audioTracks();
11945 * Get the {@link TextTrackList}
11947 * Text tracks are tracks of timed text events.
11948 * - Captions: text displayed over the video
11949 * for the hearing impaired
11950 * - Subtitles: text displayed over the video for
11951 * those who don't understand language in the video
11952 * - Chapters: text displayed in a menu allowing the user to jump
11953 * to particular points (chapters) in the video
11954 * - Descriptions: (not yet implemented) audio descriptions that are read back to
11955 * the user by a screen reading device
11957 * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks
11959 * @return {TextTrackList|undefined}
11960 * The current TextTrackList or undefined if
11961 * or undefined if we don't have a tech
11965 Player.prototype.textTracks = function textTracks() {
11966 // cannot use techGet_ directly because it checks to see whether the tech is ready.
11967 // Flash is unlikely to be ready in time but textTracks should still work.
11969 return this.tech_.textTracks();
11974 * Get the "remote" {@link TextTrackList}. Remote Text Tracks
11975 * are tracks that were added to the HTML video element and can
11976 * be removed, whereas normal texttracks cannot be removed.
11979 * @return {TextTrackList|undefined}
11980 * The current remote text track list or undefined
11981 * if we don't have a tech
11985 Player.prototype.remoteTextTracks = function remoteTextTracks() {
11987 return this.tech_.remoteTextTracks();
11992 * Get the "remote" {@link HTMLTrackElementList}.
11993 * This gives the user all of the DOM elements that match up
11994 * with the remote {@link TextTrackList}.
11996 * @return {HTMLTrackElementList}
11997 * The current remote text track list elements
11998 * or undefined if we don't have a tech
12002 Player.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
12004 return this.tech_.remoteTextTrackEls();
12009 * A helper method for adding a {@link TextTrack} to our
12010 * {@link TextTrackList}.
12012 * In addition to the W3C settings we allow adding additional info through options.
12014 * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack
12016 * @param {string} [kind]
12017 * the kind of TextTrack you are adding
12019 * @param {string} [label]
12020 * the label to give the TextTrack label
12022 * @param {string} [language]
12023 * the language to set on the TextTrack
12025 * @return {TextTrack|undefined}
12026 * the TextTrack that was added or undefined
12027 * if there is no tech
12031 Player.prototype.addTextTrack = function addTextTrack(kind, label, language) {
12033 return this.tech_.addTextTrack(kind, label, language);
12038 * Create a remote {@link TextTrack} and an {@link HTMLTrackElement}. It will
12039 * automatically removed from the video element whenever the source changes, unless
12040 * manualCleanup is set to false.
12042 * @param {Object} options
12043 * Options to pass to {@link HTMLTrackElement} during creation. See
12044 * {@link HTMLTrackElement} for object properties that you should use.
12046 * @param {boolean} [manualCleanup=true] if set to false, the TextTrack will be
12048 * @return {HTMLTrackElement}
12049 * the HTMLTrackElement that was created and added
12050 * to the HTMLTrackElementList and the remote
12053 * @deprecated The default value of the "manualCleanup" parameter will default
12054 * to "false" in upcoming versions of Video.js
12058 Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) {
12060 return this.tech_.addRemoteTextTrack(options, manualCleanup);
12065 * Remove a remote {@link TextTrack} from the respective
12066 * {@link TextTrackList} and {@link HTMLTrackElementList}.
12068 * @param {Object} track
12069 * Remote {@link TextTrack} to remove
12071 * @return {undefined}
12072 * does not return anything
12076 Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack() {
12077 var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
12078 _ref3$track = _ref3.track,
12079 track = _ref3$track === undefined ? arguments[0] : _ref3$track;
12081 // destructure the input into an object with a track argument, defaulting to arguments[0]
12082 // default the whole argument to an empty object if nothing was passed in
12085 return this.tech_.removeRemoteTextTrack(track);
12093 * current video width
12097 Player.prototype.videoWidth = function videoWidth() {
12098 return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0;
12105 * current video height
12109 Player.prototype.videoHeight = function videoHeight() {
12110 return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0;
12113 // Methods to add support for
12114 // initialTime: function() { return this.techCall_('initialTime'); },
12115 // startOffsetTime: function() { return this.techCall_('startOffsetTime'); },
12116 // played: function() { return this.techCall_('played'); },
12117 // defaultPlaybackRate: function() { return this.techCall_('defaultPlaybackRate'); },
12118 // defaultMuted: function() { return this.techCall_('defaultMuted'); }
12121 * The player's language code
12122 * NOTE: The language should be set in the player options if you want the
12123 * the controls to be built with a specific language. Changing the lanugage
12124 * later will not update controls text.
12126 * @param {string} [code]
12127 * the language code to set the player to
12129 * @return {string|Player}
12130 * - The current language code when getting
12131 * - A reference to the player when setting
12135 Player.prototype.language = function language(code) {
12136 if (code === undefined) {
12137 return this.language_;
12140 this.language_ = String(code).toLowerCase();
12145 * Get the player's language dictionary
12146 * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time
12147 * Languages specified directly in the player options have precedence
12150 * An array of of supported languages
12154 Player.prototype.languages = function languages() {
12155 return (0, _mergeOptions2['default'])(Player.prototype.options_.languages, this.languages_);
12159 * returns a JavaScript object reperesenting the current track
12160 * information. **DOES not return it as JSON**
12163 * Object representing the current of track info
12167 Player.prototype.toJSON = function toJSON() {
12168 var options = (0, _mergeOptions2['default'])(this.options_);
12169 var tracks = options.tracks;
12171 options.tracks = [];
12173 for (var i = 0; i < tracks.length; i++) {
12174 var track = tracks[i];
12176 // deep merge tracks and null out player so no circular references
12177 track = (0, _mergeOptions2['default'])(track);
12178 track.player = undefined;
12179 options.tracks[i] = track;
12186 * Creates a simple modal dialog (an instance of the {@link ModalDialog}
12187 * component) that immediately overlays the player with arbitrary
12188 * content and removes itself when closed.
12190 * @param {string|Function|Element|Array|null} content
12191 * Same as {@link ModalDialog#content}'s param of the same name.
12192 * The most straight-forward usage is to provide a string or DOM
12195 * @param {Object} [options]
12196 * Extra options which will be passed on to the {@link ModalDialog}.
12198 * @return {ModalDialog}
12199 * the {@link ModalDialog} that was created
12203 Player.prototype.createModal = function createModal(content, options) {
12206 options = options || {};
12207 options.content = content || '';
12209 var modal = new _modalDialog2['default'](this, options);
12211 this.addChild(modal);
12212 modal.on('dispose', function () {
12213 _this5.removeChild(modal);
12216 return modal.open();
12220 * Gets tag settings
12222 * @param {Element} tag
12226 * An object containing all of the settings
12231 Player.getTagSettings = function getTagSettings(tag) {
12232 var baseOptions = {
12237 var tagOptions = Dom.getElAttributes(tag);
12238 var dataSetup = tagOptions['data-setup'];
12240 if (Dom.hasElClass(tag, 'vjs-fluid')) {
12241 tagOptions.fluid = true;
12244 // Check if data-setup attr exists.
12245 if (dataSetup !== null) {
12246 // Parse options JSON
12247 // If empty string, make it a parsable json object.
12248 var _safeParseTuple = (0, _tuple2['default'])(dataSetup || '{}'),
12249 err = _safeParseTuple[0],
12250 data = _safeParseTuple[1];
12253 _log2['default'].error(err);
12255 (0, _obj.assign)(tagOptions, data);
12258 (0, _obj.assign)(baseOptions, tagOptions);
12260 // Get tag children settings
12261 if (tag.hasChildNodes()) {
12262 var children = tag.childNodes;
12264 for (var i = 0, j = children.length; i < j; i++) {
12265 var child = children[i];
12266 // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/
12267 var childName = child.nodeName.toLowerCase();
12269 if (childName === 'source') {
12270 baseOptions.sources.push(Dom.getElAttributes(child));
12271 } else if (childName === 'track') {
12272 baseOptions.tracks.push(Dom.getElAttributes(child));
12277 return baseOptions;
12281 * Determine wether or not flexbox is supported
12283 * @return {boolean}
12284 * - true if flexbox is supported
12285 * - false if flexbox is not supported
12289 Player.prototype.flexNotSupported_ = function flexNotSupported_() {
12290 var elem = _document2['default'].createElement('i');
12292 // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more
12293 // common flex features that we can rely on when checking for flex support.
12294 return !('flexBasis' in elem.style || 'webkitFlexBasis' in elem.style || 'mozFlexBasis' in elem.style || 'msFlexBasis' in elem.style ||
12295 // IE10-specific (2012 flex spec)
12296 'msFlexOrder' in elem.style);
12300 }(_component2['default']);
12303 * Global player list
12309 Player.players = {};
12311 var navigator = _window2['default'].navigator;
12314 * Player instance options, surfaced using options
12315 * options = Player.prototype.options_
12316 * Make changes in options, not here.
12321 Player.prototype.options_ = {
12322 // Default order of fallback technology
12323 techOrder: ['html5', 'flash'],
12324 // techOrder: ['flash','html5'],
12329 // defaultVolume: 0.85,
12330 defaultVolume: 0.00,
12332 // default inactivity timeout
12333 inactivityTimeout: 2000,
12335 // default playback rates
12337 // Add playback rate selection by adding rates
12338 // 'playbackRates': [0.5, 1, 1.5, 2],
12340 // Included control sets
12341 children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'],
12343 language: navigator && (navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language) || 'en',
12345 // locales and their language translations
12348 // Default message to show when a video cannot be played.
12349 notSupportedMessage: 'No compatible source was found for this media.'
12354 * Returns whether or not the player is in the "ended" state.
12356 * @return {Boolean} True if the player is in the ended state, false if not.
12357 * @method Player#ended
12361 * Returns whether or not the player is in the "seeking" state.
12363 * @return {Boolean} True if the player is in the seeking state, false if not.
12364 * @method Player#seeking
12368 * Returns the TimeRanges of the media that are currently available
12371 * @return {TimeRanges} the seekable intervals of the media timeline
12372 * @method Player#seekable
12376 * Returns the current state of network activity for the element, from
12377 * the codes in the list below.
12378 * - NETWORK_EMPTY (numeric value 0)
12379 * The element has not yet been initialised. All attributes are in
12380 * their initial states.
12381 * - NETWORK_IDLE (numeric value 1)
12382 * The element's resource selection algorithm is active and has
12383 * selected a resource, but it is not actually using the network at
12385 * - NETWORK_LOADING (numeric value 2)
12386 * The user agent is actively trying to download data.
12387 * - NETWORK_NO_SOURCE (numeric value 3)
12388 * The element's resource selection algorithm is active, but it has
12389 * not yet found a resource to use.
12391 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states
12392 * @return {number} the current network activity state
12393 * @method Player#networkState
12397 * Returns a value that expresses the current state of the element
12398 * with respect to rendering the current playback position, from the
12399 * codes in the list below.
12400 * - HAVE_NOTHING (numeric value 0)
12401 * No information regarding the media resource is available.
12402 * - HAVE_METADATA (numeric value 1)
12403 * Enough of the resource has been obtained that the duration of the
12404 * resource is available.
12405 * - HAVE_CURRENT_DATA (numeric value 2)
12406 * Data for the immediate current playback position is available.
12407 * - HAVE_FUTURE_DATA (numeric value 3)
12408 * Data for the immediate current playback position is available, as
12409 * well as enough data for the user agent to advance the current
12410 * playback position in the direction of playback.
12411 * - HAVE_ENOUGH_DATA (numeric value 4)
12412 * The user agent estimates that enough data is available for
12413 * playback to proceed uninterrupted.
12415 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate
12416 * @return {number} the current playback rendering state
12417 * @method Player#readyState
12419 'readyState'].forEach(function (fn) {
12420 Player.prototype[fn] = function () {
12421 return this.techGet_(fn);
12425 TECH_EVENTS_RETRIGGER.forEach(function (event) {
12426 Player.prototype['handleTech' + (0, _toTitleCase2['default'])(event) + '_'] = function () {
12427 return this.trigger(event);
12432 * Fired when the player has initial duration and dimension information
12434 * @event Player#loadedmetadata
12435 * @type {EventTarget~Event}
12439 * Fired when the player has downloaded data at the current playback position
12441 * @event Player#loadeddata
12442 * @type {EventTarget~Event}
12446 * Fired when the current playback position has changed *
12447 * During playback this is fired every 15-250 milliseconds, depending on the
12448 * playback technology in use.
12450 * @event Player#timeupdate
12451 * @type {EventTarget~Event}
12455 * Fired when the volume changes
12457 * @event Player#volumechange
12458 * @type {EventTarget~Event}
12461 _component2['default'].registerComponent('Player', Player);
12462 exports['default'] = Player;
12464 },{"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){
12467 exports.__esModule = true;
12469 var _player = _dereq_(51);
12471 var _player2 = _interopRequireDefault(_player);
12473 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12476 * The method for registering a video.js plugin. {@link videojs:videojs.registerPlugin].
12478 * @param {string} name
12479 * The name of the plugin that is being registered
12481 * @param {plugins:PluginFn} init
12482 * The function that gets run when a `Player` initializes.
12484 var plugin = function plugin(name, init) {
12485 _player2['default'].prototype[name] = init;
12490 exports['default'] = plugin;
12492 },{"51":51}],53:[function(_dereq_,module,exports){
12495 exports.__esModule = true;
12497 var _clickableComponent = _dereq_(3);
12499 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
12501 var _component = _dereq_(5);
12503 var _component2 = _interopRequireDefault(_component);
12505 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12507 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12509 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; }
12511 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; } /**
12512 * @file popup-button.js
12517 * A button class for use with {@link Popup} controls
12519 * @extends ClickableComponent
12521 var PopupButton = function (_ClickableComponent) {
12522 _inherits(PopupButton, _ClickableComponent);
12525 * Create an instance of this class.
12527 * @param {Player} player
12528 * The `Player` that this class should be attached to.
12530 * @param {Object} [options]
12531 * The key/value store of player options.
12533 function PopupButton(player) {
12534 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
12536 _classCallCheck(this, PopupButton);
12538 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
12545 * Update the `Popup` that this button is attached to.
12549 PopupButton.prototype.update = function update() {
12550 var popup = this.createPopup();
12553 this.removeChild(this.popup);
12556 this.popup = popup;
12557 this.addChild(popup);
12559 if (this.items && this.items.length === 0) {
12561 } else if (this.items && this.items.length > 1) {
12567 * Create a `Popup`. - Override with specific functionality for component
12573 PopupButton.prototype.createPopup = function createPopup() {};
12576 * Create the `PopupButton`s DOM element.
12578 * @return {Element}
12579 * The element that gets created.
12583 PopupButton.prototype.createEl = function createEl() {
12584 return _ClickableComponent.prototype.createEl.call(this, 'div', {
12585 className: this.buildCSSClass()
12590 * Builds the default DOM `className`.
12593 * The DOM `className` for this object.
12597 PopupButton.prototype.buildCSSClass = function buildCSSClass() {
12598 var menuButtonClass = 'vjs-menu-button';
12600 // If the inline option is passed, we want to use different styles altogether.
12601 if (this.options_.inline === true) {
12602 menuButtonClass += '-inline';
12604 menuButtonClass += '-popup';
12607 return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
12610 return PopupButton;
12611 }(_clickableComponent2['default']);
12613 _component2['default'].registerComponent('PopupButton', PopupButton);
12614 exports['default'] = PopupButton;
12616 },{"3":3,"5":5}],54:[function(_dereq_,module,exports){
12619 exports.__esModule = true;
12621 var _component = _dereq_(5);
12623 var _component2 = _interopRequireDefault(_component);
12625 var _dom = _dereq_(81);
12627 var Dom = _interopRequireWildcard(_dom);
12629 var _fn = _dereq_(83);
12631 var Fn = _interopRequireWildcard(_fn);
12633 var _events = _dereq_(82);
12635 var Events = _interopRequireWildcard(_events);
12637 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; } }
12639 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12641 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12643 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; }
12645 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; } /**
12651 * The Popup component is used to build pop up controls.
12653 * @extends Component
12655 var Popup = function (_Component) {
12656 _inherits(Popup, _Component);
12659 _classCallCheck(this, Popup);
12661 return _possibleConstructorReturn(this, _Component.apply(this, arguments));
12665 * Add a popup item to the popup
12667 * @param {Object|string} component
12668 * Component or component type to add
12671 Popup.prototype.addItem = function addItem(component) {
12672 this.addChild(component);
12673 component.on('click', Fn.bind(this, function () {
12674 this.unlockShowing();
12679 * Create the `PopupButton`s DOM element.
12681 * @return {Element}
12682 * The element that gets created.
12686 Popup.prototype.createEl = function createEl() {
12687 var contentElType = this.options_.contentElType || 'ul';
12689 this.contentEl_ = Dom.createEl(contentElType, {
12690 className: 'vjs-menu-content'
12693 var el = _Component.prototype.createEl.call(this, 'div', {
12694 append: this.contentEl_,
12695 className: 'vjs-menu'
12698 el.appendChild(this.contentEl_);
12700 // Prevent clicks from bubbling up. Needed for Popup Buttons,
12701 // where a click on the parent is significant
12702 Events.on(el, 'click', function (event) {
12703 event.preventDefault();
12704 event.stopImmediatePropagation();
12711 }(_component2['default']);
12713 _component2['default'].registerComponent('Popup', Popup);
12714 exports['default'] = Popup;
12716 },{"5":5,"81":81,"82":82,"83":83}],55:[function(_dereq_,module,exports){
12719 exports.__esModule = true;
12721 var _clickableComponent = _dereq_(3);
12723 var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
12725 var _component = _dereq_(5);
12727 var _component2 = _interopRequireDefault(_component);
12729 var _fn = _dereq_(83);
12731 var Fn = _interopRequireWildcard(_fn);
12733 var _dom = _dereq_(81);
12735 var Dom = _interopRequireWildcard(_dom);
12737 var _browser = _dereq_(78);
12739 var browser = _interopRequireWildcard(_browser);
12741 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; } }
12743 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12745 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12747 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; }
12749 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; } /**
12750 * @file poster-image.js
12755 * A `ClickableComponent` that handles showing the poster image for the player.
12757 * @extends ClickableComponent
12759 var PosterImage = function (_ClickableComponent) {
12760 _inherits(PosterImage, _ClickableComponent);
12763 * Create an instance of this class.
12765 * @param {Player} player
12766 * The `Player` that this class should attach to.
12768 * @param {Object} [options]
12769 * The key/value store of player options.
12771 function PosterImage(player, options) {
12772 _classCallCheck(this, PosterImage);
12774 var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
12777 player.on('posterchange', Fn.bind(_this, _this.update));
12782 * Clean up and dispose of the `PosterImage`.
12786 PosterImage.prototype.dispose = function dispose() {
12787 this.player().off('posterchange', this.update);
12788 _ClickableComponent.prototype.dispose.call(this);
12792 * Create the `PosterImage`s DOM element.
12794 * @return {Element}
12795 * The element that gets created.
12799 PosterImage.prototype.createEl = function createEl() {
12800 var el = Dom.createEl('div', {
12801 className: 'vjs-poster',
12803 // Don't want poster to be tabbable.
12807 // To ensure the poster image resizes while maintaining its original aspect
12808 // ratio, use a div with `background-size` when available. For browsers that
12809 // do not support `background-size` (e.g. IE8), fall back on using a regular
12811 if (!browser.BACKGROUND_SIZE_SUPPORTED) {
12812 this.fallbackImg_ = Dom.createEl('img');
12813 el.appendChild(this.fallbackImg_);
12820 * An {@link EventTarget~EventListener} for {@link Player#posterchange} events.
12822 * @listens Player#posterchange
12824 * @param {EventTarget~Event} [event]
12825 * The `Player#posterchange` event that triggered this function.
12829 PosterImage.prototype.update = function update(event) {
12830 var url = this.player().poster();
12834 // If there's no poster source we should display:none on this component
12835 // so it's not still clickable or right-clickable
12844 * Set the source of the `PosterImage` depending on the display method.
12846 * @param {string} url
12847 * The URL to the source for the `PosterImage`.
12851 PosterImage.prototype.setSrc = function setSrc(url) {
12852 if (this.fallbackImg_) {
12853 this.fallbackImg_.src = url;
12855 var backgroundImage = '';
12857 // Any falsey values should stay as an empty string, otherwise
12858 // this will throw an extra error
12860 backgroundImage = 'url("' + url + '")';
12863 this.el_.style.backgroundImage = backgroundImage;
12868 * An {@link EventTarget~EventListener} for clicks on the `PosterImage`. See
12869 * {@link ClickableComponent#handleClick} for instances where this will be triggered.
12875 * @param {EventTarget~Event} event
12876 + The `click`, `tap` or `keydown` event that caused this function to be called.
12880 PosterImage.prototype.handleClick = function handleClick(event) {
12881 // We don't want a click to trigger playback when controls are disabled
12882 if (!this.player_.controls()) {
12886 if (this.player_.paused()) {
12887 this.player_.play();
12889 this.player_.pause();
12893 return PosterImage;
12894 }(_clickableComponent2['default']);
12896 _component2['default'].registerComponent('PosterImage', PosterImage);
12897 exports['default'] = PosterImage;
12899 },{"3":3,"5":5,"78":78,"81":81,"83":83}],56:[function(_dereq_,module,exports){
12902 exports.__esModule = true;
12903 exports.hasLoaded = exports.autoSetupTimeout = exports.autoSetup = undefined;
12905 var _dom = _dereq_(81);
12907 var Dom = _interopRequireWildcard(_dom);
12909 var _events = _dereq_(82);
12911 var Events = _interopRequireWildcard(_events);
12913 var _document = _dereq_(94);
12915 var _document2 = _interopRequireDefault(_document);
12917 var _window = _dereq_(95);
12919 var _window2 = _interopRequireDefault(_window);
12921 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
12923 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; } }
12926 * @file setup.js - Functions for setting up a player without
12927 * user interaction based on the data-setup `attribute` of the video tag.
12931 var _windowLoaded = false;
12932 var videojs = void 0;
12935 * Set up any tags that have a data-setup `attribute` when the player is started.
12937 var autoSetup = function autoSetup() {
12939 // Protect against breakage in non-browser environments.
12940 if (!Dom.isReal()) {
12944 // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack*
12945 // var vids = Array.prototype.slice.call(document.getElementsByTagName('video'));
12946 // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio'));
12947 // var mediaEls = vids.concat(audios);
12949 // Because IE8 doesn't support calling slice on a node list, we need to loop
12950 // through each list of elements to build up a new, combined list of elements.
12951 var vids = _document2['default'].getElementsByTagName('video');
12952 var audios = _document2['default'].getElementsByTagName('audio');
12955 if (vids && vids.length > 0) {
12956 for (var i = 0, e = vids.length; i < e; i++) {
12957 mediaEls.push(vids[i]);
12961 if (audios && audios.length > 0) {
12962 for (var _i = 0, _e = audios.length; _i < _e; _i++) {
12963 mediaEls.push(audios[_i]);
12967 // Check if any media elements exist
12968 if (mediaEls && mediaEls.length > 0) {
12970 for (var _i2 = 0, _e2 = mediaEls.length; _i2 < _e2; _i2++) {
12971 var mediaEl = mediaEls[_i2];
12973 // Check if element exists, has getAttribute func.
12974 // IE seems to consider typeof el.getAttribute == 'object' instead of
12975 // 'function' like expected, at least when loading the player immediately.
12976 if (mediaEl && mediaEl.getAttribute) {
12978 // Make sure this player hasn't already been set up.
12979 if (mediaEl.player === undefined) {
12980 var options = mediaEl.getAttribute('data-setup');
12982 // Check if data-setup attr exists.
12983 // We only auto-setup if they've added the data-setup attr.
12984 if (options !== null) {
12985 // Create new video.js instance.
12990 // If getAttribute isn't defined, we need to wait for the DOM.
12992 autoSetupTimeout(1);
12997 // No videos were found, so keep looping unless page is finished loading.
12998 } else if (!_windowLoaded) {
12999 autoSetupTimeout(1);
13004 * Wait until the page is loaded before running autoSetup. This will be called in
13005 * autoSetup if `hasLoaded` returns false.
13007 * @param {number} wait
13008 * How long to wait in ms
13010 * @param {videojs} [vjs]
13011 * The videojs library function
13013 function autoSetupTimeout(wait, vjs) {
13018 _window2['default'].setTimeout(autoSetup, wait);
13021 if (Dom.isReal() && _document2['default'].readyState === 'complete') {
13022 _windowLoaded = true;
13025 * Listen for the load event on window, and set _windowLoaded to true.
13029 Events.one(_window2['default'], 'load', function () {
13030 _windowLoaded = true;
13035 * check if the document has been loaded
13037 var hasLoaded = function hasLoaded() {
13038 return _windowLoaded;
13041 exports.autoSetup = autoSetup;
13042 exports.autoSetupTimeout = autoSetupTimeout;
13043 exports.hasLoaded = hasLoaded;
13045 },{"81":81,"82":82,"94":94,"95":95}],57:[function(_dereq_,module,exports){
13048 exports.__esModule = true;
13050 var _component = _dereq_(5);
13052 var _component2 = _interopRequireDefault(_component);
13054 var _dom = _dereq_(81);
13056 var Dom = _interopRequireWildcard(_dom);
13058 var _obj = _dereq_(88);
13060 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; } }
13062 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13064 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
13066 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; }
13068 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; } /**
13074 * The base functionality for a slider. Can be vertical or horizontal.
13075 * For instance the volume bar or the seek bar on a video is a slider.
13077 * @extends Component
13079 var Slider = function (_Component) {
13080 _inherits(Slider, _Component);
13083 * Create an instance of this class
13085 * @param {Player} player
13086 * The `Player` that this class should be attached to.
13088 * @param {Object} [options]
13089 * The key/value store of player options.
13091 function Slider(player, options) {
13092 _classCallCheck(this, Slider);
13094 // Set property names to bar to match with the child Slider class is looking for
13095 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
13097 _this.bar = _this.getChild(_this.options_.barName);
13099 // Set a horizontal or vertical class on the slider depending on the slider type
13100 _this.vertical(!!_this.options_.vertical);
13102 _this.on('mousedown', _this.handleMouseDown);
13103 _this.on('touchstart', _this.handleMouseDown);
13104 _this.on('focus', _this.handleFocus);
13105 _this.on('blur', _this.handleBlur);
13106 _this.on('click', _this.handleClick);
13108 _this.on(player, 'controlsvisible', _this.update);
13109 _this.on(player, _this.playerEvent, _this.update);
13114 * Create the `Button`s DOM element.
13116 * @param {string} type
13117 * Type of element to create.
13119 * @param {Object} [props={}]
13120 * List of properties in Object form.
13122 * @param {Object} [attributes={}]
13123 * list of attributes in Object form.
13125 * @return {Element}
13126 * The element that gets created.
13130 Slider.prototype.createEl = function createEl(type) {
13131 var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
13132 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
13134 // Add the slider element class to all sub classes
13135 props.className = props.className + ' vjs-slider';
13136 props = (0, _obj.assign)({
13140 attributes = (0, _obj.assign)({
13142 'aria-valuenow': 0,
13143 'aria-valuemin': 0,
13144 'aria-valuemax': 100,
13148 return _Component.prototype.createEl.call(this, type, props, attributes);
13152 * Handle `mousedown` or `touchstart` events on the `Slider`.
13154 * @param {EventTarget~Event} event
13155 * `mousedown` or `touchstart` event that triggered this function
13157 * @listens mousedown
13158 * @listens touchstart
13159 * @fires Slider#slideractive
13163 Slider.prototype.handleMouseDown = function handleMouseDown(event) {
13164 var doc = this.bar.el_.ownerDocument;
13166 event.preventDefault();
13167 Dom.blockTextSelection();
13169 this.addClass('vjs-sliding');
13171 * Triggered when the slider is in an active state
13173 * @event Slider#slideractive
13174 * @type {EventTarget~Event}
13176 this.trigger('slideractive');
13178 this.on(doc, 'mousemove', this.handleMouseMove);
13179 this.on(doc, 'mouseup', this.handleMouseUp);
13180 this.on(doc, 'touchmove', this.handleMouseMove);
13181 this.on(doc, 'touchend', this.handleMouseUp);
13183 this.handleMouseMove(event);
13187 * Handle the `mousemove`, `touchmove`, and `mousedown` events on this `Slider`.
13188 * The `mousemove` and `touchmove` events will only only trigger this function during
13189 * `mousedown` and `touchstart`. This is due to {@link Slider#handleMouseDown} and
13190 * {@link Slider#handleMouseUp}.
13192 * @param {EventTarget~Event} event
13193 * `mousedown`, `mousemove`, `touchstart`, or `touchmove` event that triggered
13196 * @listens mousemove
13197 * @listens touchmove
13201 Slider.prototype.handleMouseMove = function handleMouseMove(event) {};
13204 * Handle `mouseup` or `touchend` events on the `Slider`.
13206 * @param {EventTarget~Event} event
13207 * `mouseup` or `touchend` event that triggered this function.
13209 * @listens touchend
13211 * @fires Slider#sliderinactive
13215 Slider.prototype.handleMouseUp = function handleMouseUp() {
13216 var doc = this.bar.el_.ownerDocument;
13218 Dom.unblockTextSelection();
13220 this.removeClass('vjs-sliding');
13222 * Triggered when the slider is no longer in an active state.
13224 * @event Slider#sliderinactive
13225 * @type {EventTarget~Event}
13227 this.trigger('sliderinactive');
13229 this.off(doc, 'mousemove', this.handleMouseMove);
13230 this.off(doc, 'mouseup', this.handleMouseUp);
13231 this.off(doc, 'touchmove', this.handleMouseMove);
13232 this.off(doc, 'touchend', this.handleMouseUp);
13238 * Update the progress bar of the `Slider`.
13242 Slider.prototype.update = function update() {
13243 // In VolumeBar init we have a setTimeout for update that pops and update to the end of the
13244 // execution stack. The player is destroyed before then update will cause an error
13249 // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.
13250 // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.
13251 // var progress = (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration();
13252 var progress = this.getPercent();
13253 var bar = this.bar;
13255 // If there's no bar...
13260 // Protect against no duration and other division issues
13261 if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) {
13265 // Convert to a percentage for setting
13266 var percentage = (progress * 100).toFixed(2) + '%';
13268 // Set the new bar width or height
13269 if (this.vertical()) {
13270 bar.el().style.height = percentage;
13272 bar.el().style.width = percentage;
13277 * Calculate distance for slider
13279 * @param {EventTarget~Event} event
13280 * The event that caused this function to run.
13283 * The current position of the Slider.
13284 * - postition.x for vertical `Slider`s
13285 * - postition.y for horizontal `Slider`s
13289 Slider.prototype.calculateDistance = function calculateDistance(event) {
13290 var position = Dom.getPointerPosition(this.el_, event);
13292 if (this.vertical()) {
13299 * Handle a `focus` event on this `Slider`.
13301 * @param {EventTarget~Event} event
13302 * The `focus` event that caused this function to run.
13308 Slider.prototype.handleFocus = function handleFocus() {
13309 this.on(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
13313 * Handle a `keydown` event on the `Slider`. Watches for left, rigth, up, and down
13314 * arrow keys. This function will only be called when the slider has focus. See
13315 * {@link Slider#handleFocus} and {@link Slider#handleBlur}.
13317 * @param {EventTarget~Event} event
13318 * the `keydown` event that caused this function to run.
13324 Slider.prototype.handleKeyPress = function handleKeyPress(event) {
13325 // Left and Down Arrows
13326 if (event.which === 37 || event.which === 40) {
13327 event.preventDefault();
13330 // Up and Right Arrows
13331 } else if (event.which === 38 || event.which === 39) {
13332 event.preventDefault();
13333 this.stepForward();
13338 * Handle a `blur` event on this `Slider`.
13340 * @param {EventTarget~Event} event
13341 * The `blur` event that caused this function to run.
13346 Slider.prototype.handleBlur = function handleBlur() {
13347 this.off(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
13351 * Listener for click events on slider, used to prevent clicks
13352 * from bubbling up to parent elements like button menus.
13354 * @param {Object} event
13355 * Event that caused this object to run
13359 Slider.prototype.handleClick = function handleClick(event) {
13360 event.stopImmediatePropagation();
13361 event.preventDefault();
13365 * Get/set if slider is horizontal for vertical
13367 * @param {boolean} [bool]
13368 * - true if slider is vertical,
13369 * - false is horizontal
13371 * @return {boolean|Slider}
13372 * - true if slider is vertical, and getting
13373 * - false is horizontal, and getting
13374 * - a reference to this object when setting
13378 Slider.prototype.vertical = function vertical(bool) {
13379 if (bool === undefined) {
13380 return this.vertical_ || false;
13383 this.vertical_ = !!bool;
13385 if (this.vertical_) {
13386 this.addClass('vjs-slider-vertical');
13388 this.addClass('vjs-slider-horizontal');
13395 }(_component2['default']);
13397 _component2['default'].registerComponent('Slider', Slider);
13398 exports['default'] = Slider;
13400 },{"5":5,"81":81,"88":88}],58:[function(_dereq_,module,exports){
13403 exports.__esModule = true;
13405 * @file flash-rtmp.js
13406 * @module flash-rtmp
13410 * Add RTMP properties to the {@link Flash} Tech.
13412 * @param {Flash} Flash
13413 * The flash tech class.
13415 * @mixin FlashRtmpDecorator
13417 function FlashRtmpDecorator(Flash) {
13418 Flash.streamingFormats = {
13424 * Join connection and stream with an ampersand.
13426 * @param {string} connection
13427 * The connection string.
13429 * @param {string} stream
13430 * The stream string.
13432 Flash.streamFromParts = function (connection, stream) {
13433 return connection + '&' + stream;
13437 * The flash parts object that contains connection and stream info.
13439 * @typedef {Object} Flash~PartsObject
13441 * @property {string} connection
13442 * The connection string of a source, defaults to an empty string.
13444 * @property {string} stream
13445 * The stream string of the source, defaults to an empty string.
13449 * Convert a source url into a stream and connection parts.
13451 * @param {string} src
13454 * @return {Flash~PartsObject}
13455 * The parts object that contains a connection and a stream
13457 Flash.streamToParts = function (src) {
13467 // Look for the normal URL separator we expect, '&'.
13468 // If found, we split the URL into two pieces around the
13470 var connEnd = src.search(/&(?!\w+=)/);
13471 var streamBegin = void 0;
13473 if (connEnd !== -1) {
13474 streamBegin = connEnd + 1;
13476 // If there's not a '&', we use the last '/' as the delimiter.
13477 connEnd = streamBegin = src.lastIndexOf('/') + 1;
13478 if (connEnd === 0) {
13479 // really, there's not a '/'?
13480 connEnd = streamBegin = src.length;
13484 parts.connection = src.substring(0, connEnd);
13485 parts.stream = src.substring(streamBegin, src.length);
13491 * Check if the source type is a streaming type.
13493 * @param {string} srcType
13494 * The mime type to check.
13496 * @return {boolean}
13497 * - True if the source type is a streaming type.
13498 * - False if the source type is not a streaming type.
13500 Flash.isStreamingType = function (srcType) {
13501 return srcType in Flash.streamingFormats;
13504 // RTMP has four variations, any string starting
13505 // with one of these protocols should be valid
13508 * Regular expression used to check if the source is an rtmp source.
13510 * @property {RegExp} Flash.RTMP_RE
13512 Flash.RTMP_RE = /^rtmp[set]?:\/\//i;
13515 * Check if the source itself is a streaming type.
13517 * @param {string} src
13518 * The url to the source.
13520 * @return {boolean}
13521 * - True if the source url indicates that the source is streaming.
13522 * - False if the shource url indicates that the source url is not streaming.
13524 Flash.isStreamingSrc = function (src) {
13525 return Flash.RTMP_RE.test(src);
13529 * A source handler for RTMP urls
13532 Flash.rtmpSourceHandler = {};
13535 * Check if Flash can play the given mime type.
13537 * @param {string} type
13538 * The mime type to check
13541 * 'maybe', or '' (empty string)
13543 Flash.rtmpSourceHandler.canPlayType = function (type) {
13544 if (Flash.isStreamingType(type)) {
13552 * Check if Flash can handle the source natively
13554 * @param {Object} source
13555 * The source object
13557 * @param {Object} [options]
13558 * The options passed to the tech
13561 * 'maybe', or '' (empty string)
13563 Flash.rtmpSourceHandler.canHandleSource = function (source, options) {
13564 var can = Flash.rtmpSourceHandler.canPlayType(source.type);
13570 if (Flash.isStreamingSrc(source.src)) {
13578 * Pass the source to the flash object.
13580 * @param {Object} source
13581 * The source object
13583 * @param {Flash} tech
13584 * The instance of the Flash tech
13586 * @param {Object} [options]
13587 * The options to pass to the source
13589 Flash.rtmpSourceHandler.handleSource = function (source, tech, options) {
13590 var srcParts = Flash.streamToParts(source.src);
13592 tech.setRtmpConnection(srcParts.connection);
13593 tech.setRtmpStream(srcParts.stream);
13596 // Register the native source handler
13597 Flash.registerSourceHandler(Flash.rtmpSourceHandler);
13602 exports['default'] = FlashRtmpDecorator;
13604 },{}],59:[function(_dereq_,module,exports){
13607 exports.__esModule = true;
13609 var _tech = _dereq_(62);
13611 var _tech2 = _interopRequireDefault(_tech);
13613 var _dom = _dereq_(81);
13615 var Dom = _interopRequireWildcard(_dom);
13617 var _url = _dereq_(92);
13619 var Url = _interopRequireWildcard(_url);
13621 var _timeRanges = _dereq_(90);
13623 var _flashRtmp = _dereq_(58);
13625 var _flashRtmp2 = _interopRequireDefault(_flashRtmp);
13627 var _component = _dereq_(5);
13629 var _component2 = _interopRequireDefault(_component);
13631 var _window = _dereq_(95);
13633 var _window2 = _interopRequireDefault(_window);
13635 var _obj = _dereq_(88);
13637 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; } }
13639 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
13641 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
13643 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; }
13645 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; } /**
13647 * VideoJS-SWF - Custom Flash Player with HTML5-ish API
13648 * https://github.com/zencoder/video-js-swf
13649 * Not using setupTriggers. Using global onEvent func to distribute events
13652 var navigator = _window2['default'].navigator;
13655 * Flash Media Controller - Wrapper for Flash Media API
13657 * @mixes FlashRtmpDecorator
13658 * @mixes Tech~SouceHandlerAdditions
13662 var Flash = function (_Tech) {
13663 _inherits(Flash, _Tech);
13666 * Create an instance of this Tech.
13668 * @param {Object} [options]
13669 * The key/value store of player options.
13671 * @param {Component~ReadyCallback} ready
13672 * Callback function to call when the `Flash` Tech is ready.
13674 function Flash(options, ready) {
13675 _classCallCheck(this, Flash);
13677 // Set the source when ready
13678 var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready));
13680 if (options.source) {
13681 _this.ready(function () {
13682 this.setSource(options.source);
13686 // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers
13687 // This allows resetting the playhead when we catch the reload
13688 if (options.startTime) {
13689 _this.ready(function () {
13692 this.currentTime(options.startTime);
13696 // Add global window functions that the swf expects
13697 // A 4.x workflow we weren't able to solve for in 5.0
13698 // because of the need to hard code these functions
13699 // into the swf for security reasons
13700 _window2['default'].videojs = _window2['default'].videojs || {};
13701 _window2['default'].videojs.Flash = _window2['default'].videojs.Flash || {};
13702 _window2['default'].videojs.Flash.onReady = Flash.onReady;
13703 _window2['default'].videojs.Flash.onEvent = Flash.onEvent;
13704 _window2['default'].videojs.Flash.onError = Flash.onError;
13706 _this.on('seeked', function () {
13707 this.lastSeekTarget_ = undefined;
13714 * Create the `Flash` Tech's DOM element.
13716 * @return {Element}
13717 * The element that gets created.
13721 Flash.prototype.createEl = function createEl() {
13722 var options = this.options_;
13724 // If video.js is hosted locally you should also set the location
13725 // for the hosted swf, which should be relative to the page (not video.js)
13726 // Otherwise this adds a CDN url.
13727 // The CDN also auto-adds a swf URL for that specific version.
13728 if (!options.swf) {
13731 options.swf = '//vjs.zencdn.net/swf/' + ver + '/video-js.swf';
13734 // Generate ID for swf object
13735 var objId = options.techId;
13737 // Merge default flashvars with ones passed in to init
13738 var flashVars = (0, _obj.assign)({
13740 // SWF Callback Functions
13741 readyFunction: 'videojs.Flash.onReady',
13742 eventProxyFunction: 'videojs.Flash.onEvent',
13743 errorEventProxyFunction: 'videojs.Flash.onError',
13746 autoplay: options.autoplay,
13747 preload: options.preload,
13748 loop: options.loop,
13749 muted: options.muted
13751 }, options.flashVars);
13753 // Merge default parames with ones passed in
13754 var params = (0, _obj.assign)({
13755 // Opaque is needed to overlay controls, but can affect playback performance
13757 // Using bgcolor prevents a white flash when the object is loading
13759 }, options.params);
13761 // Merge default attributes with ones passed in
13762 var attributes = (0, _obj.assign)({
13763 // Both ID and Name needed or swf to identify itself
13766 'class': 'vjs-tech'
13767 }, options.attributes);
13769 this.el_ = Flash.embed(options.swf, flashVars, params, attributes);
13770 this.el_.tech = this;
13776 * Called by {@link Player#play} to play using the `Flash` `Tech`.
13780 Flash.prototype.play = function play() {
13781 if (this.ended()) {
13782 this.setCurrentTime(0);
13784 this.el_.vjs_play();
13788 * Called by {@link Player#pause} to pause using the `Flash` `Tech`.
13792 Flash.prototype.pause = function pause() {
13793 this.el_.vjs_pause();
13797 * A getter/setter for the `Flash` Tech's source object.
13798 * > Note: Please use {@link Flash#setSource}
13800 * @param {Tech~SourceObject} [src]
13801 * The source object you want to set on the `Flash` techs.
13803 * @return {Tech~SourceObject|undefined}
13804 * - The current source object when a source is not passed in.
13805 * - undefined when setting
13807 * @deprecated Since version 5.
13811 Flash.prototype.src = function src(_src) {
13812 if (_src === undefined) {
13813 return this.currentSrc();
13816 // Setting src through `src` not `setSrc` will be deprecated
13817 return this.setSrc(_src);
13821 * A getter/setter for the `Flash` Tech's source object.
13823 * @param {Tech~SourceObject} [src]
13824 * The source object you want to set on the `Flash` techs.
13826 * @return {Tech~SourceObject|undefined}
13827 * - The current source object when a source is not passed in.
13828 * - undefined when setting
13832 Flash.prototype.setSrc = function setSrc(src) {
13835 // Make sure source URL is absolute.
13836 src = Url.getAbsoluteURL(src);
13837 this.el_.vjs_src(src);
13839 // Currently the SWF doesn't autoplay if you load a source later.
13840 // e.g. Load player w/ no source, wait 2s, set src.
13841 if (this.autoplay()) {
13842 this.setTimeout(function () {
13843 return _this2.play();
13849 * Indicates whether the media is currently seeking to a new position or not.
13851 * @return {boolean}
13852 * - True if seeking to a new position
13853 * - False otherwise
13857 Flash.prototype.seeking = function seeking() {
13858 return this.lastSeekTarget_ !== undefined;
13862 * Returns the current time in seconds that the media is at in playback.
13864 * @param {number} time
13865 * Current playtime of the media in seconds.
13869 Flash.prototype.setCurrentTime = function setCurrentTime(time) {
13870 var seekable = this.seekable();
13872 if (seekable.length) {
13873 // clamp to the current seekable range
13874 time = time > seekable.start(0) ? time : seekable.start(0);
13875 time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1);
13877 this.lastSeekTarget_ = time;
13878 this.trigger('seeking');
13879 this.el_.vjs_setProperty('currentTime', time);
13880 _Tech.prototype.setCurrentTime.call(this);
13885 * Get the current playback time in seconds
13888 * The current time of playback in seconds.
13892 Flash.prototype.currentTime = function currentTime() {
13893 // when seeking make the reported time keep up with the requested time
13894 // by reading the time we're seeking to
13895 if (this.seeking()) {
13896 return this.lastSeekTarget_ || 0;
13898 return this.el_.vjs_getProperty('currentTime');
13902 * Get the current source
13904 * @method currentSrc
13905 * @return {Tech~SourceObject}
13906 * The current source
13910 Flash.prototype.currentSrc = function currentSrc() {
13911 if (this.currentSource_) {
13912 return this.currentSource_.src;
13914 return this.el_.vjs_getProperty('currentSrc');
13918 * Get the total duration of the current media.
13921 8 The total duration of the current media.
13925 Flash.prototype.duration = function duration() {
13926 if (this.readyState() === 0) {
13929 var duration = this.el_.vjs_getProperty('duration');
13931 return duration >= 0 ? duration : Infinity;
13935 * Load media into Tech.
13939 Flash.prototype.load = function load() {
13940 this.el_.vjs_load();
13944 * Get the poster image that was set on the tech.
13948 Flash.prototype.poster = function poster() {
13949 this.el_.vjs_getProperty('poster');
13953 * Poster images are not handled by the Flash tech so make this is a no-op.
13957 Flash.prototype.setPoster = function setPoster() {};
13960 * Determine the time ranges that can be seeked to in the media.
13962 * @return {TimeRange}
13963 * Returns the time ranges that can be seeked to.
13967 Flash.prototype.seekable = function seekable() {
13968 var duration = this.duration();
13970 if (duration === 0) {
13971 return (0, _timeRanges.createTimeRange)();
13973 return (0, _timeRanges.createTimeRange)(0, duration);
13977 * Get and create a `TimeRange` object for buffering.
13979 * @return {TimeRange}
13980 * The time range object that was created.
13984 Flash.prototype.buffered = function buffered() {
13985 var ranges = this.el_.vjs_getProperty('buffered');
13987 if (ranges.length === 0) {
13988 return (0, _timeRanges.createTimeRange)();
13990 return (0, _timeRanges.createTimeRange)(ranges[0][0], ranges[0][1]);
13994 * Get fullscreen support -
13996 * Flash does not allow fullscreen through javascript
13997 * so this always returns false.
13999 * @return {boolean}
14000 * The Flash tech does not support fullscreen, so it will always return false.
14004 Flash.prototype.supportsFullScreen = function supportsFullScreen() {
14005 // Flash does not allow fullscreen through javascript
14010 * Flash does not allow fullscreen through javascript
14011 * so this always returns false.
14013 * @return {boolean}
14014 * The Flash tech does not support fullscreen, so it will always return false.
14018 Flash.prototype.enterFullScreen = function enterFullScreen() {
14023 }(_tech2['default']);
14025 // Create setters and getters for attributes
14028 var _api = Flash.prototype;
14029 var _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(',');
14030 var _readOnly = 'networkState,readyState,initialTime,startOffsetTime,paused,ended,videoWidth,videoHeight'.split(',');
14032 function _createSetter(attr) {
14033 var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
14035 _api['set' + attrUpper] = function (val) {
14036 return this.el_.vjs_setProperty(attr, val);
14040 function _createGetter(attr) {
14041 _api[attr] = function () {
14042 return this.el_.vjs_getProperty(attr);
14046 // Create getter and setters for all read/write attributes
14047 for (var i = 0; i < _readWrite.length; i++) {
14048 _createGetter(_readWrite[i]);
14049 _createSetter(_readWrite[i]);
14052 // Create getters for read-only attributes
14053 for (var _i = 0; _i < _readOnly.length; _i++) {
14054 _createGetter(_readOnly[_i]);
14057 /** ------------------------------ Getters ------------------------------ **/
14059 * Get the value of `rtmpConnection` from the swf.
14061 * @method Flash#rtmpConnection
14063 * The current value of `rtmpConnection` on the swf.
14067 * Get the value of `rtmpStream` from the swf.
14069 * @method Flash#rtmpStream
14071 * The current value of `rtmpStream` on the swf.
14075 * Get the value of `preload` from the swf. `preload` indicates
14076 * what should download before the media is interacted with. It can have the following
14078 * - none: nothing should be downloaded
14079 * - metadata: poster and the first few frames of the media may be downloaded to get
14080 * media dimensions and other metadata
14081 * - auto: allow the media and metadata for the media to be downloaded before
14084 * @method Flash#preload
14086 * The value of `preload` from the swf. Will be 'none', 'metadata',
14091 * Get the value of `defaultPlaybackRate` from the swf.
14093 * @method Flash#defaultPlaybackRate
14095 * The current value of `defaultPlaybackRate` on the swf.
14099 * Get the value of `playbackRate` from the swf. `playbackRate` indicates
14100 * the rate at which the media is currently playing back. Examples:
14101 * - if playbackRate is set to 2, media will play twice as fast.
14102 * - if playbackRate is set to 0.5, media will play half as fast.
14104 * @method Flash#playbackRate
14106 * The value of `playbackRate` from the swf. A number indicating
14107 * the current playback speed of the media, where 1 is normal speed.
14111 * Get the value of `autoplay` from the swf. `autoplay` indicates
14112 * that the media should start to play as soon as the page is ready.
14114 * @method Flash#autoplay
14115 * @return {boolean}
14116 * - The value of `autoplay` from the swf.
14117 * - True indicates that the media ashould start as soon as the page loads.
14118 * - False indicates that the media should not start as soon as the page loads.
14122 * Get the value of `loop` from the swf. `loop` indicates
14123 * that the media should return to the start of the media and continue playing once
14124 * it reaches the end.
14126 * @method Flash#loop
14127 * @return {boolean}
14128 * - The value of `loop` from the swf.
14129 * - True indicates that playback should seek back to start once
14130 * the end of a media is reached.
14131 * - False indicates that playback should not loop back to the start when the
14132 * end of the media is reached.
14136 * Get the value of `mediaGroup` from the swf.
14138 * @method Flash#mediaGroup
14140 * The current value of `mediaGroup` on the swf.
14144 * Get the value of `controller` from the swf.
14146 * @method Flash#controller
14148 * The current value of `controller` on the swf.
14152 * Get the value of `controls` from the swf. `controls` indicates
14153 * whether the native flash controls should be shown or hidden.
14155 * @method Flash#controls
14156 * @return {boolean}
14157 * - The value of `controls` from the swf.
14158 * - True indicates that native controls should be showing.
14159 * - False indicates that native controls should be hidden.
14163 * Get the value of the `volume` from the swf. `volume` indicates the current
14164 * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
14167 * @method Flash#volume
14169 * The volume percent as a decimal. Value will be between 0-1.
14173 * Get the value of the `muted` from the swf. `muted` indicates the current
14174 * audio level should be silent.
14176 * @method Flash#muted
14177 * @return {boolean}
14178 * - True if the audio should be set to silent
14179 * - False otherwise
14183 * Get the value of `defaultMuted` from the swf. `defaultMuted` indicates
14184 * whether the media should start muted or not. Only changes the default state of the
14185 * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
14188 * @method Flash#defaultMuted
14189 * @return {boolean}
14190 * - The value of `defaultMuted` from the swf.
14191 * - True indicates that the media should start muted.
14192 * - False indicates that the media should not start muted.
14196 * Get the value of `networkState` from the swf. `networkState` indicates
14197 * the current network state. It returns an enumeration from the following list:
14198 * - 0: NETWORK_EMPTY
14200 * - 2: NETWORK_LOADING
14201 * - 3: NETWORK_NO_SOURCE
14203 * @method Flash#networkState
14205 * The value of `networkState` from the swf. This will be a number
14206 * from the list in the description.
14210 * Get the value of `readyState` from the swf. `readyState` indicates
14211 * the current state of the media element. It returns an enumeration from the
14213 * - 0: HAVE_NOTHING
14214 * - 1: HAVE_METADATA
14215 * - 2: HAVE_CURRENT_DATA
14216 * - 3: HAVE_FUTURE_DATA
14217 * - 4: HAVE_ENOUGH_DATA
14219 * @method Flash#readyState
14221 * The value of `readyState` from the swf. This will be a number
14222 * from the list in the description.
14226 * Get the value of `readyState` from the swf. `readyState` indicates
14227 * the current state of the media element. It returns an enumeration from the
14229 * - 0: HAVE_NOTHING
14230 * - 1: HAVE_METADATA
14231 * - 2: HAVE_CURRENT_DATA
14232 * - 3: HAVE_FUTURE_DATA
14233 * - 4: HAVE_ENOUGH_DATA
14235 * @method Flash#readyState
14237 * The value of `readyState` from the swf. This will be a number
14238 * from the list in the description.
14242 * Get the value of `initialTime` from the swf.
14244 * @method Flash#initialTime
14246 * The `initialTime` proprety on the swf.
14250 * Get the value of `startOffsetTime` from the swf.
14252 * @method Flash#startOffsetTime
14254 * The `startOffsetTime` proprety on the swf.
14258 * Get the value of `paused` from the swf. `paused` indicates whether the swf
14259 * is current paused or not.
14261 * @method Flash#paused
14262 * @return {boolean}
14263 * The value of `paused` from the swf.
14267 * Get the value of `ended` from the swf. `ended` indicates whether
14268 * the media has reached the end or not.
14270 * @method Flash#ended
14271 * @return {boolean}
14272 * - True indicates that the media has ended.
14273 * - False indicates that the media has not ended.
14275 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended}
14279 * Get the value of `videoWidth` from the swf. `videoWidth` indicates
14280 * the current width of the media in css pixels.
14282 * @method Flash#videoWidth
14284 * The value of `videoWidth` from the swf. This will be a number
14289 * Get the value of `videoHeight` from the swf. `videoHeigth` indicates
14290 * the current height of the media in css pixels.
14292 * @method Flassh.prototype.videoHeight
14294 * The value of `videoHeight` from the swf. This will be a number
14297 /** ------------------------------ Setters ------------------------------ **/
14300 * Set the value of `rtmpConnection` on the swf.
14302 * @method Flash#setRtmpConnection
14303 * @param {string} rtmpConnection
14304 * New value to set the `rtmpConnection` property to.
14308 * Set the value of `rtmpStream` on the swf.
14310 * @method Flash#setRtmpStream
14311 * @param {string} rtmpStream
14312 * New value to set the `rtmpStream` property to.
14316 * Set the value of `preload` on the swf. `preload` indicates
14317 * what should download before the media is interacted with. It can have the following
14319 * - none: nothing should be downloaded
14320 * - metadata: poster and the first few frames of the media may be downloaded to get
14321 * media dimensions and other metadata
14322 * - auto: allow the media and metadata for the media to be downloaded before
14325 * @method Flash#setPreload
14326 * @param {string} preload
14327 * The value of `preload` to set on the swf. Should be 'none', 'metadata',
14332 * Set the value of `defaultPlaybackRate` on the swf.
14334 * @method Flash#setDefaultPlaybackRate
14335 * @param {number} defaultPlaybackRate
14336 * New value to set the `defaultPlaybackRate` property to.
14340 * Set the value of `playbackRate` on the swf. `playbackRate` indicates
14341 * the rate at which the media is currently playing back. Examples:
14342 * - if playbackRate is set to 2, media will play twice as fast.
14343 * - if playbackRate is set to 0.5, media will play half as fast.
14345 * @method Flash#setPlaybackRate
14346 * @param {number} playbackRate
14347 * New value of `playbackRate` on the swf. A number indicating
14348 * the current playback speed of the media, where 1 is normal speed.
14352 * Set the value of `autoplay` on the swf. `autoplay` indicates
14353 * that the media should start to play as soon as the page is ready.
14355 * @method Flash#setAutoplay
14356 * @param {boolean} autoplay
14357 * - The value of `autoplay` from the swf.
14358 * - True indicates that the media ashould start as soon as the page loads.
14359 * - False indicates that the media should not start as soon as the page loads.
14363 * Set the value of `loop` on the swf. `loop` indicates
14364 * that the media should return to the start of the media and continue playing once
14365 * it reaches the end.
14367 * @method Flash#setLoop
14368 * @param {boolean} loop
14369 * - True indicates that playback should seek back to start once
14370 * the end of a media is reached.
14371 * - False indicates that playback should not loop back to the start when the
14372 * end of the media is reached.
14376 * Set the value of `mediaGroup` on the swf.
14378 * @method Flash#setMediaGroup
14379 * @param {string} mediaGroup
14380 * New value of `mediaGroup` to set on the swf.
14384 * Set the value of `controller` on the swf.
14386 * @method Flash#setController
14387 * @param {string} controller
14388 * New value the current value of `controller` on the swf.
14392 * Get the value of `controls` from the swf. `controls` indicates
14393 * whether the native flash controls should be shown or hidden.
14395 * @method Flash#controls
14396 * @return {boolean}
14397 * - The value of `controls` from the swf.
14398 * - True indicates that native controls should be showing.
14399 * - False indicates that native controls should be hidden.
14403 * Set the value of the `volume` on the swf. `volume` indicates the current
14404 * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
14407 * @method Flash#setVolume
14408 * @param {number} percentAsDecimal
14409 * The volume percent as a decimal. Value will be between 0-1.
14413 * Set the value of the `muted` on the swf. `muted` indicates that the current
14414 * audio level should be silent.
14416 * @method Flash#setMuted
14417 * @param {boolean} muted
14418 * - True if the audio should be set to silent
14419 * - False otherwise
14423 * Set the value of `defaultMuted` on the swf. `defaultMuted` indicates
14424 * whether the media should start muted or not. Only changes the default state of the
14425 * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
14428 * @method Flash#setDefaultMuted
14429 * @param {boolean} defaultMuted
14430 * - True indicates that the media should start muted.
14431 * - False indicates that the media should not start muted.
14434 /* Flash Support Testing -------------------------------------------------------- */
14437 * Check if the Flash tech is currently supported.
14439 * @return {boolean}
14440 * - True if the flash tech is supported.
14441 * - False otherwise.
14443 Flash.isSupported = function () {
14444 return Flash.version()[0] >= 10;
14445 // return swfobject.hasFlashPlayerVersion('10');
14448 // Add Source Handler pattern functions to this tech
14449 _tech2['default'].withSourceHandlers(Flash);
14452 * Native source handler for flash, simply passes the source to the swf element.
14454 * @property {Tech~SourceObject} source
14455 * The source object
14457 * @property {Flash} tech
14458 * The instance of the Flash tech
14460 Flash.nativeSourceHandler = {};
14463 * Check if the Flash can play the given mime type.
14465 * @param {string} type
14466 * The mimetype to check
14469 * 'maybe', or '' (empty string)
14471 Flash.nativeSourceHandler.canPlayType = function (type) {
14472 if (type in Flash.formats) {
14480 * Check if the media element can handle a source natively.
14482 * @param {Tech~SourceObject} source
14483 * The source object
14485 * @param {Object} [options]
14486 * Options to be passed to the tech.
14489 * 'maybe', or '' (empty string).
14491 Flash.nativeSourceHandler.canHandleSource = function (source, options) {
14494 function guessMimeType(src) {
14495 var ext = Url.getFileExtension(src);
14498 return 'video/' + ext;
14503 if (!source.type) {
14504 type = guessMimeType(source.src);
14506 // Strip code information from the type because we don't get that specific
14507 type = source.type.replace(/;.*/, '').toLowerCase();
14510 return Flash.nativeSourceHandler.canPlayType(type);
14514 * Pass the source to the swf.
14516 * @param {Tech~SourceObject} source
14517 * The source object
14519 * @param {Flash} tech
14520 * The instance of the Flash tech
14522 * @param {Object} [options]
14523 * The options to pass to the source
14525 Flash.nativeSourceHandler.handleSource = function (source, tech, options) {
14526 tech.setSrc(source.src);
14530 * noop for native source handler dispose, as cleanup will happen automatically.
14532 Flash.nativeSourceHandler.dispose = function () {};
14534 // Register the native source handler
14535 Flash.registerSourceHandler(Flash.nativeSourceHandler);
14538 * Flash supported mime types.
14540 * @constant {Object}
14543 'video/flv': 'FLV',
14544 'video/x-flv': 'FLV',
14545 'video/mp4': 'MP4',
14550 * Called when the the swf is "ready", and makes sure that the swf is really
14551 * ready using {@link Flash#checkReady}
14553 Flash.onReady = function (currSwf) {
14554 var el = Dom.getEl(currSwf);
14555 var tech = el && el.tech;
14557 // if there is no el then the tech has been disposed
14558 // and the tech element was removed from the player div
14559 if (tech && tech.el()) {
14560 // check that the flash object is really ready
14561 Flash.checkReady(tech);
14566 * The SWF isn't always ready when it says it is. Sometimes the API functions still
14567 * need to be added to the object. If it's not ready, we set a timeout to check again
14570 * @param {Flash} tech
14571 * The instance of the flash tech to check.
14573 Flash.checkReady = function (tech) {
14574 // stop worrying if the tech has been disposed
14579 // check if API property exists
14580 if (tech.el().vjs_getProperty) {
14581 // tell tech it's ready
14582 tech.triggerReady();
14585 this.setTimeout(function () {
14586 Flash.checkReady(tech);
14592 * Trigger events from the swf on the Flash Tech.
14594 * @param {number} swfID
14595 * The id of the swf that had the event
14597 * @param {string} eventName
14598 * The name of the event to trigger
14600 Flash.onEvent = function (swfID, eventName) {
14601 var tech = Dom.getEl(swfID).tech;
14602 var args = Array.prototype.slice.call(arguments, 2);
14604 // dispatch Flash events asynchronously for two reasons:
14605 // - Flash swallows any exceptions generated by javascript it
14607 // - Flash is suspended until the javascript returns which may cause
14608 // playback performance issues
14609 tech.setTimeout(function () {
14610 tech.trigger(eventName, args);
14615 * Log errors from the swf on the Flash tech.
14617 * @param {number} swfID
14618 * The id of the swf that had an error.
14620 * @param {string} The error string
14621 * The error to set on the Flash Tech.
14623 * @return {MediaError|undefined}
14624 * - Returns a MediaError when err is 'srcnotfound'
14625 * - Returns undefined otherwise.
14627 Flash.onError = function (swfID, err) {
14628 var tech = Dom.getEl(swfID).tech;
14630 // trigger MEDIA_ERR_SRC_NOT_SUPPORTED
14631 if (err === 'srcnotfound') {
14632 return tech.error(4);
14635 // trigger a custom error
14636 tech.error('FLASH: ' + err);
14640 * Get the current version of Flash that is in use on the page.
14643 * an array of versions that are available.
14645 Flash.version = function () {
14646 var version = '0,0,0';
14650 version = new _window2['default'].ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
14655 if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) {
14656 version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
14662 return version.split(',');
14666 * Only use for non-iframe embeds.
14668 * @param {Object} swf
14669 * The videojs-swf object.
14671 * @param {Object} flashVars
14672 * Names and values to use as flash option variables.
14674 * @param {Object} params
14675 * Style parameters to set on the object.
14677 * @param {Object} attributes
14678 * Attributes to set on the element.
14680 * @return {Element}
14681 * The embeded Flash DOM element.
14683 Flash.embed = function (swf, flashVars, params, attributes) {
14684 var code = Flash.getEmbedCode(swf, flashVars, params, attributes);
14686 // Get element by embedding code and retrieving created element
14687 var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0];
14693 * Only use for non-iframe embeds.
14695 * @param {Object} swf
14696 * The videojs-swf object.
14698 * @param {Object} flashVars
14699 * Names and values to use as flash option variables.
14701 * @param {Object} params
14702 * Style parameters to set on the object.
14704 * @param {Object} attributes
14705 * Attributes to set on the element.
14707 * @return {Element}
14708 * The embeded Flash DOM element.
14710 Flash.getEmbedCode = function (swf, flashVars, params, attributes) {
14711 var objTag = '<object type="application/x-shockwave-flash" ';
14712 var flashVarsString = '';
14713 var paramsString = '';
14714 var attrsString = '';
14716 // Convert flash vars to string
14718 Object.getOwnPropertyNames(flashVars).forEach(function (key) {
14719 flashVarsString += key + '=' + flashVars[key] + '&';
14723 // Add swf, flashVars, and other default params
14724 params = (0, _obj.assign)({
14726 flashvars: flashVarsString,
14727 // Required to talk to swf
14728 allowScriptAccess: 'always',
14729 // All should be default, but having security issues.
14730 allowNetworking: 'all'
14733 // Create param tags string
14734 Object.getOwnPropertyNames(params).forEach(function (key) {
14735 paramsString += '<param name="' + key + '" value="' + params[key] + '" />';
14738 attributes = (0, _obj.assign)({
14739 // Add swf to attributes (need both for IE and Others to work)
14742 // Default to 100% width/height
14748 // Create Attributes string
14749 Object.getOwnPropertyNames(attributes).forEach(function (key) {
14750 attrsString += key + '="' + attributes[key] + '" ';
14753 return '' + objTag + attrsString + '>' + paramsString + '</object>';
14756 // Run Flash through the RTMP decorator
14757 (0, _flashRtmp2['default'])(Flash);
14759 _component2['default'].registerComponent('Flash', Flash);
14760 _tech2['default'].registerTech('Flash', Flash);
14761 exports['default'] = Flash;
14763 },{"5":5,"58":58,"62":62,"81":81,"88":88,"90":90,"92":92,"95":95}],60:[function(_dereq_,module,exports){
14766 exports.__esModule = true;
14768 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.']);
14770 var _tech = _dereq_(62);
14772 var _tech2 = _interopRequireDefault(_tech);
14774 var _component = _dereq_(5);
14776 var _component2 = _interopRequireDefault(_component);
14778 var _dom = _dereq_(81);
14780 var Dom = _interopRequireWildcard(_dom);
14782 var _url = _dereq_(92);
14784 var Url = _interopRequireWildcard(_url);
14786 var _fn = _dereq_(83);
14788 var Fn = _interopRequireWildcard(_fn);
14790 var _log = _dereq_(86);
14792 var _log2 = _interopRequireDefault(_log);
14794 var _tsml = _dereq_(98);
14796 var _tsml2 = _interopRequireDefault(_tsml);
14798 var _browser = _dereq_(78);
14800 var browser = _interopRequireWildcard(_browser);
14802 var _document = _dereq_(94);
14804 var _document2 = _interopRequireDefault(_document);
14806 var _window = _dereq_(95);
14808 var _window2 = _interopRequireDefault(_window);
14810 var _obj = _dereq_(88);
14812 var _mergeOptions = _dereq_(87);
14814 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
14816 var _toTitleCase = _dereq_(91);
14818 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
14820 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; } }
14822 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
14824 function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
14826 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
14828 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; }
14830 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; } /**
14836 * HTML5 Media Controller - Wrapper for HTML5 Media API
14838 * @mixes Tech~SouceHandlerAdditions
14841 var Html5 = function (_Tech) {
14842 _inherits(Html5, _Tech);
14845 * Create an instance of this Tech.
14847 * @param {Object} [options]
14848 * The key/value store of player options.
14850 * @param {Component~ReadyCallback} ready
14851 * Callback function to call when the `HTML5` Tech is ready.
14853 function Html5(options, ready) {
14854 _classCallCheck(this, Html5);
14856 var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready));
14858 var source = options.source;
14859 var crossoriginTracks = false;
14861 // Set the source if one is provided
14862 // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted)
14863 // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source
14864 // anyway so the error gets fired.
14865 if (source && (_this.el_.currentSrc !== source.src || options.tag && options.tag.initNetworkState_ === 3)) {
14866 _this.setSource(source);
14868 _this.handleLateInit_(_this.el_);
14871 if (_this.el_.hasChildNodes()) {
14873 var nodes = _this.el_.childNodes;
14874 var nodesLength = nodes.length;
14875 var removeNodes = [];
14877 while (nodesLength--) {
14878 var node = nodes[nodesLength];
14879 var nodeName = node.nodeName.toLowerCase();
14881 if (nodeName === 'track') {
14882 if (!_this.featuresNativeTextTracks) {
14883 // Empty video tag tracks so the built-in player doesn't use them also.
14884 // This may not be fast enough to stop HTML5 browsers from reading the tags
14885 // so we'll need to turn off any default tracks if we're manually doing
14886 // captions and subtitles. videoElement.textTracks
14887 removeNodes.push(node);
14889 // store HTMLTrackElement and TextTrack to remote list
14890 _this.remoteTextTrackEls().addTrackElement_(node);
14891 _this.remoteTextTracks().addTrack_(node.track);
14892 if (!crossoriginTracks && !_this.el_.hasAttribute('crossorigin') && Url.isCrossOrigin(node.src)) {
14893 crossoriginTracks = true;
14899 for (var i = 0; i < removeNodes.length; i++) {
14900 _this.el_.removeChild(removeNodes[i]);
14904 // TODO: add text tracks into this list
14905 var trackTypes = ['audio', 'video'];
14907 // ProxyNative Video/Audio Track
14908 trackTypes.forEach(function (type) {
14909 var elTracks = _this.el()[type + 'Tracks'];
14910 var techTracks = _this[type + 'Tracks']();
14911 var capitalType = (0, _toTitleCase2['default'])(type);
14913 if (!_this['featuresNative' + capitalType + 'Tracks'] || !elTracks || !elTracks.addEventListener) {
14917 _this['handle' + capitalType + 'TrackChange_'] = function (e) {
14918 techTracks.trigger({
14920 target: techTracks,
14921 currentTarget: techTracks,
14922 srcElement: techTracks
14926 _this['handle' + capitalType + 'TrackAdd_'] = function (e) {
14927 return techTracks.addTrack(e.track);
14929 _this['handle' + capitalType + 'TrackRemove_'] = function (e) {
14930 return techTracks.removeTrack(e.track);
14933 elTracks.addEventListener('change', _this['handle' + capitalType + 'TrackChange_']);
14934 elTracks.addEventListener('addtrack', _this['handle' + capitalType + 'TrackAdd_']);
14935 elTracks.addEventListener('removetrack', _this['handle' + capitalType + 'TrackRemove_']);
14936 _this['removeOld' + capitalType + 'Tracks_'] = function (e) {
14937 return _this.removeOldTracks_(techTracks, elTracks);
14940 // Remove (native) tracks that are not used anymore
14941 _this.on('loadstart', _this['removeOld' + capitalType + 'Tracks_']);
14944 if (_this.featuresNativeTextTracks) {
14945 if (crossoriginTracks) {
14946 _log2['default'].warn((0, _tsml2['default'])(_templateObject));
14949 _this.handleTextTrackChange_ = Fn.bind(_this, _this.handleTextTrackChange);
14950 _this.handleTextTrackAdd_ = Fn.bind(_this, _this.handleTextTrackAdd);
14951 _this.handleTextTrackRemove_ = Fn.bind(_this, _this.handleTextTrackRemove);
14952 _this.proxyNativeTextTracks_();
14955 // Determine if native controls should be used
14956 // Our goal should be to get the custom controls on mobile solid everywhere
14957 // so we can remove this all together. Right now this will block custom
14958 // controls on touch enabled laptops like the Chrome Pixel
14959 if ((browser.TOUCH_ENABLED || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) && options.nativeControlsForTouch === true) {
14960 _this.setControls(true);
14963 // on iOS, we want to proxy `webkitbeginfullscreen` and `webkitendfullscreen`
14964 // into a `fullscreenchange` event
14965 _this.proxyWebkitFullscreen_();
14967 _this.triggerReady();
14972 * Dispose of `HTML5` media element and remove all tracks.
14976 Html5.prototype.dispose = function dispose() {
14979 // Un-ProxyNativeTracks
14980 ['audio', 'video', 'text'].forEach(function (type) {
14981 var capitalType = (0, _toTitleCase2['default'])(type);
14982 var tl = _this2.el_[type + 'Tracks'];
14984 if (tl && tl.removeEventListener) {
14985 tl.removeEventListener('change', _this2['handle' + capitalType + 'TrackChange_']);
14986 tl.removeEventListener('addtrack', _this2['handle' + capitalType + 'TrackAdd_']);
14987 tl.removeEventListener('removetrack', _this2['handle' + capitalType + 'TrackRemove_']);
14990 // Stop removing old text tracks
14992 _this2.off('loadstart', _this2['removeOld' + capitalType + 'Tracks_']);
14996 Html5.disposeMediaElement(this.el_);
14997 // tech will handle clearing of the emulated track list
14998 _Tech.prototype.dispose.call(this);
15002 * Create the `Html5` Tech's DOM element.
15004 * @return {Element}
15005 * The element that gets created.
15009 Html5.prototype.createEl = function createEl() {
15010 var el = this.options_.tag;
15012 // Check if this browser supports moving the element into the box.
15013 // On the iPhone video will break if you move the element,
15014 // So we have to create a brand new element.
15015 // If we ingested the player div, we do not need to move the media element.
15016 if (!el || !(this.options_.playerElIngest || this.movingMediaElementInDOM)) {
15018 // If the original tag is still there, clone and remove it.
15020 var clone = el.cloneNode(true);
15022 if (el.parentNode) {
15023 el.parentNode.insertBefore(clone, el);
15025 Html5.disposeMediaElement(el);
15028 el = _document2['default'].createElement('video');
15030 // determine if native controls should be used
15031 var tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag);
15032 var attributes = (0, _mergeOptions2['default'])({}, tagAttributes);
15034 if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) {
15035 delete attributes.controls;
15038 Dom.setElAttributes(el, (0, _obj.assign)(attributes, {
15039 id: this.options_.techId,
15040 'class': 'vjs-tech'
15044 el.playerId = this.options_.playerId;
15047 // Update specific tag settings, in case they were overridden
15048 var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted'];
15050 for (var i = settingsAttrs.length - 1; i >= 0; i--) {
15051 var attr = settingsAttrs[i];
15052 var overwriteAttrs = {};
15054 if (typeof this.options_[attr] !== 'undefined') {
15055 overwriteAttrs[attr] = this.options_[attr];
15057 Dom.setElAttributes(el, overwriteAttrs);
15064 * This will be triggered if the loadstart event has already fired, before videojs was
15065 * ready. Two known examples of when this can happen are:
15066 * 1. If we're loading the playback object after it has started loading
15067 * 2. The media is already playing the (often with autoplay on) then
15069 * This function will fire another loadstart so that videojs can catchup.
15071 * @fires Tech#loadstart
15073 * @return {undefined}
15078 Html5.prototype.handleLateInit_ = function handleLateInit_(el) {
15079 if (el.networkState === 0 || el.networkState === 3) {
15080 // The video element hasn't started loading the source yet
15081 // or didn't find a source
15085 if (el.readyState === 0) {
15086 // NetworkState is set synchronously BUT loadstart is fired at the
15087 // end of the current stack, usually before setInterval(fn, 0).
15088 // So at this point we know loadstart may have already fired or is
15089 // about to fire, and either way the player hasn't seen it yet.
15090 // We don't want to fire loadstart prematurely here and cause a
15091 // double loadstart so we'll wait and see if it happens between now
15092 // and the next loop, and fire it if not.
15093 // HOWEVER, we also want to make sure it fires before loadedmetadata
15094 // which could also happen between now and the next loop, so we'll
15095 // watch for that also.
15096 var loadstartFired = false;
15097 var setLoadstartFired = function setLoadstartFired() {
15098 loadstartFired = true;
15101 this.on('loadstart', setLoadstartFired);
15103 var triggerLoadstart = function triggerLoadstart() {
15104 // We did miss the original loadstart. Make sure the player
15105 // sees loadstart before loadedmetadata
15106 if (!loadstartFired) {
15107 this.trigger('loadstart');
15111 this.on('loadedmetadata', triggerLoadstart);
15113 this.ready(function () {
15114 this.off('loadstart', setLoadstartFired);
15115 this.off('loadedmetadata', triggerLoadstart);
15117 if (!loadstartFired) {
15118 // We did miss the original native loadstart. Fire it now.
15119 this.trigger('loadstart');
15126 // From here on we know that loadstart already fired and we missed it.
15127 // The other readyState events aren't as much of a problem if we double
15128 // them, so not going to go to as much trouble as loadstart to prevent
15129 // that unless we find reason to.
15130 var eventsToTrigger = ['loadstart'];
15132 // loadedmetadata: newly equal to HAVE_METADATA (1) or greater
15133 eventsToTrigger.push('loadedmetadata');
15135 // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater
15136 if (el.readyState >= 2) {
15137 eventsToTrigger.push('loadeddata');
15140 // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater
15141 if (el.readyState >= 3) {
15142 eventsToTrigger.push('canplay');
15145 // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4)
15146 if (el.readyState >= 4) {
15147 eventsToTrigger.push('canplaythrough');
15150 // We still need to give the player time to add event listeners
15151 this.ready(function () {
15152 eventsToTrigger.forEach(function (type) {
15153 this.trigger(type);
15159 * Add event listeners to native text track events. This adds the native text tracks
15160 * to our emulated {@link TextTrackList}.
15164 Html5.prototype.proxyNativeTextTracks_ = function proxyNativeTextTracks_() {
15165 var tt = this.el().textTracks;
15168 // Add tracks - if player is initialised after DOM loaded, textTracks
15169 // will not trigger addtrack
15170 for (var i = 0; i < tt.length; i++) {
15171 this.textTracks().addTrack_(tt[i]);
15174 if (tt.addEventListener) {
15175 tt.addEventListener('change', this.handleTextTrackChange_);
15176 tt.addEventListener('addtrack', this.handleTextTrackAdd_);
15177 tt.addEventListener('removetrack', this.handleTextTrackRemove_);
15180 // Remove (native) texttracks that are not used anymore
15181 this.on('loadstart', this.removeOldTextTracks_);
15186 * Handle any {@link TextTrackList} `change` event.
15188 * @param {EventTarget~Event} e
15189 * The `change` event that caused this to run.
15191 * @listens TextTrackList#change
15195 Html5.prototype.handleTextTrackChange = function handleTextTrackChange(e) {
15196 var tt = this.textTracks();
15198 this.textTracks().trigger({
15207 * Handle any {@link TextTrackList} `addtrack` event.
15209 * @param {EventTarget~Event} e
15210 * The `addtrack` event that caused this to run.
15212 * @listens TextTrackList#addtrack
15216 Html5.prototype.handleTextTrackAdd = function handleTextTrackAdd(e) {
15217 this.textTracks().addTrack_(e.track);
15221 * Handle any {@link TextTrackList} `removetrack` event.
15223 * @param {EventTarget~Event} e
15224 * The `removetrack` event that caused this to run.
15226 * @listens TextTrackList#removetrack
15230 Html5.prototype.handleTextTrackRemove = function handleTextTrackRemove(e) {
15231 this.textTracks().removeTrack_(e.track);
15235 * This function removes any {@link AudioTrack}s, {@link VideoTrack}s, or
15236 * {@link TextTrack}s that are not in the media elements TrackList.
15238 * @param {TrackList} techTracks
15239 * HTML5 Tech's TrackList to search through
15241 * @param {TrackList} elTracks
15242 * HTML5 media elements TrackList to search trough.
15248 Html5.prototype.removeOldTracks_ = function removeOldTracks_(techTracks, elTracks) {
15249 // This will loop over the techTracks and check if they are still used by the HTML5 media element
15250 // If not, they will be removed from the emulated list
15251 var removeTracks = [];
15257 for (var i = 0; i < techTracks.length; i++) {
15258 var techTrack = techTracks[i];
15261 for (var j = 0; j < elTracks.length; j++) {
15262 if (elTracks[j] === techTrack) {
15269 removeTracks.push(techTrack);
15273 for (var _i = 0; _i < removeTracks.length; _i++) {
15274 var track = removeTracks[_i];
15276 techTracks.removeTrack_(track);
15281 * Remove {@link TextTrack}s that dont exist in the native track list from our
15282 * emulated {@link TextTrackList}.
15284 * @listens Tech#loadstart
15288 Html5.prototype.removeOldTextTracks_ = function removeOldTextTracks_(e) {
15289 var techTracks = this.textTracks();
15290 var elTracks = this.el().textTracks;
15292 this.removeOldTracks_(techTracks, elTracks);
15296 * Called by {@link Player#play} to play using the `Html5` `Tech`.
15300 Html5.prototype.play = function play() {
15301 var playPromise = this.el_.play();
15303 // Catch/silence error when a pause interrupts a play request
15304 // on browsers which return a promise
15305 if (playPromise !== undefined && typeof playPromise.then === 'function') {
15306 playPromise.then(null, function (e) {});
15311 * Set current time for the `HTML5` tech.
15313 * @param {number} seconds
15314 * Set the current time of the media to this.
15318 Html5.prototype.setCurrentTime = function setCurrentTime(seconds) {
15320 this.el_.currentTime = seconds;
15322 (0, _log2['default'])(e, 'Video is not ready. (Video.js)');
15323 // this.warning(VideoJS.warnings.videoNotReady);
15328 * Get the current duration of the HTML5 media element.
15331 * The duration of the media or 0 if there is no duration.
15335 Html5.prototype.duration = function duration() {
15338 // Android Chrome will report duration as Infinity for VOD HLS until after
15339 // playback has started, which triggers the live display erroneously.
15340 // Return NaN if playback has not started and trigger a durationupdate once
15341 // the duration can be reliably known.
15342 if (this.el_.duration === Infinity && browser.IS_ANDROID && browser.IS_CHROME) {
15343 if (this.el_.currentTime === 0) {
15344 // Wait for the first `timeupdate` with currentTime > 0 - there may be
15346 var checkProgress = function checkProgress() {
15347 if (_this3.el_.currentTime > 0) {
15348 // Trigger durationchange for genuinely live video
15349 if (_this3.el_.duration === Infinity) {
15350 _this3.trigger('durationchange');
15352 _this3.off('timeupdate', checkProgress);
15356 this.on('timeupdate', checkProgress);
15360 return this.el_.duration || NaN;
15364 * Get the current width of the HTML5 media element.
15367 * The width of the HTML5 media element.
15371 Html5.prototype.width = function width() {
15372 return this.el_.offsetWidth;
15376 * Get the current height of the HTML5 media element.
15379 * The heigth of the HTML5 media element.
15383 Html5.prototype.height = function height() {
15384 return this.el_.offsetHeight;
15388 * Proxy iOS `webkitbeginfullscreen` and `webkitendfullscreen` into
15389 * `fullscreenchange` event.
15392 * @fires fullscreenchange
15393 * @listens webkitendfullscreen
15394 * @listens webkitbeginfullscreen
15395 * @listens webkitbeginfullscreen
15399 Html5.prototype.proxyWebkitFullscreen_ = function proxyWebkitFullscreen_() {
15402 if (!('webkitDisplayingFullscreen' in this.el_)) {
15406 var endFn = function endFn() {
15407 this.trigger('fullscreenchange', { isFullscreen: false });
15410 var beginFn = function beginFn() {
15411 this.one('webkitendfullscreen', endFn);
15413 this.trigger('fullscreenchange', { isFullscreen: true });
15416 this.on('webkitbeginfullscreen', beginFn);
15417 this.on('dispose', function () {
15418 _this4.off('webkitbeginfullscreen', beginFn);
15419 _this4.off('webkitendfullscreen', endFn);
15424 * Check if fullscreen is supported on the current playback device.
15426 * @return {boolean}
15427 * - True if fullscreen is supported.
15428 * - False if fullscreen is not supported.
15432 Html5.prototype.supportsFullScreen = function supportsFullScreen() {
15433 if (typeof this.el_.webkitEnterFullScreen === 'function') {
15434 var userAgent = _window2['default'].navigator && _window2['default'].navigator.userAgent || '';
15436 // Seems to be broken in Chromium/Chrome && Safari in Leopard
15437 if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) {
15445 * Request that the `HTML5` Tech enter fullscreen.
15449 Html5.prototype.enterFullScreen = function enterFullScreen() {
15450 var video = this.el_;
15452 if (video.paused && video.networkState <= video.HAVE_METADATA) {
15453 // attempt to prime the video element for programmatic access
15454 // this isn't necessary on the desktop but shouldn't hurt
15457 // playing and pausing synchronously during the transition to fullscreen
15458 // can get iOS ~6.1 devices into a play/pause loop
15459 this.setTimeout(function () {
15461 video.webkitEnterFullScreen();
15464 video.webkitEnterFullScreen();
15469 * Request that the `HTML5` Tech exit fullscreen.
15473 Html5.prototype.exitFullScreen = function exitFullScreen() {
15474 this.el_.webkitExitFullScreen();
15478 * A getter/setter for the `Html5` Tech's source object.
15479 * > Note: Please use {@link Html5#setSource}
15481 * @param {Tech~SourceObject} [src]
15482 * The source object you want to set on the `HTML5` techs element.
15484 * @return {Tech~SourceObject|undefined}
15485 * - The current source object when a source is not passed in.
15486 * - undefined when setting
15488 * @deprecated Since version 5.
15492 Html5.prototype.src = function src(_src) {
15493 if (_src === undefined) {
15494 return this.el_.src;
15497 // Setting src through `src` instead of `setSrc` will be deprecated
15502 * Reset the tech by removing all sources and then calling
15503 * {@link Html5.resetMediaElement}.
15507 Html5.prototype.reset = function reset() {
15508 Html5.resetMediaElement(this.el_);
15512 * Get the current source on the `HTML5` Tech. Falls back to returning the source from
15513 * the HTML5 media element.
15515 * @return {Tech~SourceObject}
15516 * The current source object from the HTML5 tech. With a fallback to the
15521 Html5.prototype.currentSrc = function currentSrc() {
15522 if (this.currentSource_) {
15523 return this.currentSource_.src;
15525 return this.el_.currentSrc;
15529 * Set controls attribute for the HTML5 media Element.
15531 * @param {string} val
15532 * Value to set the controls attribute to
15536 Html5.prototype.setControls = function setControls(val) {
15537 this.el_.controls = !!val;
15541 * Create and returns a remote {@link TextTrack} object.
15543 * @param {string} kind
15544 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
15546 * @param {string} [label]
15547 * Label to identify the text track
15549 * @param {string} [language]
15550 * Two letter language abbreviation
15552 * @return {TextTrack}
15553 * The TextTrack that gets created.
15557 Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) {
15558 if (!this.featuresNativeTextTracks) {
15559 return _Tech.prototype.addTextTrack.call(this, kind, label, language);
15562 return this.el_.addTextTrack(kind, label, language);
15566 * Creates either native TextTrack or an emulated TextTrack depending
15567 * on the value of `featuresNativeTextTracks`
15569 * @param {Object} options
15570 * The object should contain the options to intialize the TextTrack with.
15572 * @param {string} [options.kind]
15573 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
15575 * @param {string} [options.label].
15576 * Label to identify the text track
15578 * @param {string} [options.language]
15579 * Two letter language abbreviation.
15581 * @param {boolean} [options.default]
15582 * Default this track to on.
15584 * @param {string} [options.id]
15585 * The internal id to assign this track.
15587 * @param {string} [options.src]
15588 * A source url for the track.
15590 * @return {HTMLTrackElement}
15591 * The track element that gets created.
15595 Html5.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) {
15596 if (!this.featuresNativeTextTracks) {
15597 return _Tech.prototype.createRemoteTextTrack.call(this, options);
15599 var htmlTrackElement = _document2['default'].createElement('track');
15601 if (options.kind) {
15602 htmlTrackElement.kind = options.kind;
15604 if (options.label) {
15605 htmlTrackElement.label = options.label;
15607 if (options.language || options.srclang) {
15608 htmlTrackElement.srclang = options.language || options.srclang;
15610 if (options['default']) {
15611 htmlTrackElement['default'] = options['default'];
15614 htmlTrackElement.id = options.id;
15617 htmlTrackElement.src = options.src;
15620 return htmlTrackElement;
15624 * Creates a remote text track object and returns an html track element.
15626 * @param {Object} options The object should contain values for
15627 * kind, language, label, and src (location of the WebVTT file)
15628 * @param {Boolean} [manualCleanup=true] if set to false, the TextTrack will be
15629 * automatically removed from the video element whenever the source changes
15630 * @return {HTMLTrackElement} An Html Track Element.
15631 * This can be an emulated {@link HTMLTrackElement} or a native one.
15632 * @deprecated The default value of the "manualCleanup" parameter will default
15633 * to "false" in upcoming versions of Video.js
15637 Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) {
15638 var htmlTrackElement = _Tech.prototype.addRemoteTextTrack.call(this, options, manualCleanup);
15640 if (this.featuresNativeTextTracks) {
15641 this.el().appendChild(htmlTrackElement);
15644 return htmlTrackElement;
15648 * Remove remote `TextTrack` from `TextTrackList` object
15650 * @param {TextTrack} track
15651 * `TextTrack` object to remove
15655 Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
15656 _Tech.prototype.removeRemoteTextTrack.call(this, track);
15658 if (this.featuresNativeTextTracks) {
15659 var tracks = this.$$('track');
15661 var i = tracks.length;
15664 if (track === tracks[i] || track === tracks[i].track) {
15665 this.el().removeChild(tracks[i]);
15672 }(_tech2['default']);
15674 /* HTML5 Support Testing ---------------------------------------------------- */
15676 if (Dom.isReal()) {
15679 * Element for testing browser HTML5 media capabilities
15685 Html5.TEST_VID = _document2['default'].createElement('video');
15686 var track = _document2['default'].createElement('track');
15688 track.kind = 'captions';
15689 track.srclang = 'en';
15690 track.label = 'English';
15691 Html5.TEST_VID.appendChild(track);
15695 * Check if HTML5 media is supported by this browser/device.
15697 * @return {boolean}
15698 * - True if HTML5 media is supported.
15699 * - False if HTML5 media is not supported.
15701 Html5.isSupported = function () {
15702 // IE9 with no Media Player is a LIAR! (#984)
15704 Html5.TEST_VID.volume = 0.5;
15709 return !!(Html5.TEST_VID && Html5.TEST_VID.canPlayType);
15713 * Check if the volume can be changed in this browser/device.
15714 * Volume cannot be changed in a lot of mobile devices.
15715 * Specifically, it can't be changed from 1 on iOS.
15717 * @return {boolean}
15718 * - True if volume can be controlled
15719 * - False otherwise
15721 Html5.canControlVolume = function () {
15722 // IE will error if Windows Media Player not installed #3315
15724 var volume = Html5.TEST_VID.volume;
15726 Html5.TEST_VID.volume = volume / 2 + 0.1;
15727 return volume !== Html5.TEST_VID.volume;
15734 * Check if the playback rate can be changed in this browser/device.
15736 * @return {boolean}
15737 * - True if playback rate can be controlled
15738 * - False otherwise
15740 Html5.canControlPlaybackRate = function () {
15741 // Playback rate API is implemented in Android Chrome, but doesn't do anything
15742 // https://github.com/videojs/video.js/issues/3180
15743 if (browser.IS_ANDROID && browser.IS_CHROME) {
15746 // IE will error if Windows Media Player not installed #3315
15748 var playbackRate = Html5.TEST_VID.playbackRate;
15750 Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1;
15751 return playbackRate !== Html5.TEST_VID.playbackRate;
15758 * Check to see if native `TextTrack`s are supported by this browser/device.
15760 * @return {boolean}
15761 * - True if native `TextTrack`s are supported.
15762 * - False otherwise
15764 Html5.supportsNativeTextTracks = function () {
15765 return browser.IS_ANY_SAFARI;
15769 * Check to see if native `VideoTrack`s are supported by this browser/device
15771 * @return {boolean}
15772 * - True if native `VideoTrack`s are supported.
15773 * - False otherwise
15775 Html5.supportsNativeVideoTracks = function () {
15776 return !!(Html5.TEST_VID && Html5.TEST_VID.videoTracks);
15780 * Check to see if native `AudioTrack`s are supported by this browser/device
15782 * @return {boolean}
15783 * - True if native `AudioTrack`s are supported.
15784 * - False otherwise
15786 Html5.supportsNativeAudioTracks = function () {
15787 return !!(Html5.TEST_VID && Html5.TEST_VID.audioTracks);
15791 * An array of events available on the Html5 tech.
15796 Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'volumechange'];
15799 * Boolean indicating whether the `Tech` supports volume control.
15802 * @default {@link Html5.canControlVolume}
15804 Html5.prototype.featuresVolumeControl = Html5.canControlVolume();
15807 * Boolean indicating whether the `Tech` supports changing the speed at which the media
15809 * - Set player to play 2x (twice) as fast
15810 * - Set player to play 0.5x (half) as fast
15813 * @default {@link Html5.canControlPlaybackRate}
15815 Html5.prototype.featuresPlaybackRate = Html5.canControlPlaybackRate();
15818 * Boolean indicating whether the `HTML5` tech currently supports the media element
15819 * moving in the DOM. iOS breaks if you move the media element, so this is set this to
15820 * false there. Everywhere else this should be true.
15825 Html5.prototype.movingMediaElementInDOM = !browser.IS_IOS;
15827 // TODO: Previous comment: No longer appears to be used. Can probably be removed.
15830 * Boolean indicating whether the `HTML5` tech currently supports automatic media resize
15831 * when going into fullscreen.
15836 Html5.prototype.featuresFullscreenResize = true;
15839 * Boolean indicating whether the `HTML5` tech currently supports the progress event.
15840 * If this is false, manual `progress` events will be triggred instead.
15845 Html5.prototype.featuresProgressEvents = true;
15848 * Boolean indicating whether the `HTML5` tech currently supports the timeupdate event.
15849 * If this is false, manual `timeupdate` events will be triggred instead.
15853 Html5.prototype.featuresTimeupdateEvents = true;
15856 * Boolean indicating whether the `HTML5` tech currently supports native `TextTrack`s.
15859 * @default {@link Html5.supportsNativeTextTracks}
15861 Html5.prototype.featuresNativeTextTracks = Html5.supportsNativeTextTracks();
15864 * Boolean indicating whether the `HTML5` tech currently supports native `VideoTrack`s.
15867 * @default {@link Html5.supportsNativeVideoTracks}
15869 Html5.prototype.featuresNativeVideoTracks = Html5.supportsNativeVideoTracks();
15872 * Boolean indicating whether the `HTML5` tech currently supports native `AudioTrack`s.
15875 * @default {@link Html5.supportsNativeAudioTracks}
15877 Html5.prototype.featuresNativeAudioTracks = Html5.supportsNativeAudioTracks();
15879 // HTML5 Feature detection and Device Fixes --------------------------------- //
15880 var canPlayType = Html5.TEST_VID && Html5.TEST_VID.constructor.prototype.canPlayType;
15881 var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i;
15882 var mp4RE = /^video\/mp4/i;
15884 Html5.patchCanPlayType = function () {
15886 // Android 4.0 and above can play HLS to some extent but it reports being unable to do so
15887 if (browser.ANDROID_VERSION >= 4.0 && !browser.IS_FIREFOX) {
15888 Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
15889 if (type && mpegurlRE.test(type)) {
15892 return canPlayType.call(this, type);
15895 // Override Android 2.2 and less canPlayType method which is broken
15896 } else if (browser.IS_OLD_ANDROID) {
15897 Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
15898 if (type && mp4RE.test(type)) {
15901 return canPlayType.call(this, type);
15906 Html5.unpatchCanPlayType = function () {
15907 var r = Html5.TEST_VID.constructor.prototype.canPlayType;
15909 Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType;
15913 // by default, patch the media element
15914 Html5.patchCanPlayType();
15916 Html5.disposeMediaElement = function (el) {
15921 if (el.parentNode) {
15922 el.parentNode.removeChild(el);
15925 // remove any child track or source nodes to prevent their loading
15926 while (el.hasChildNodes()) {
15927 el.removeChild(el.firstChild);
15930 // remove any src reference. not setting `src=''` because that causes a warning
15932 el.removeAttribute('src');
15934 // force the media element to update its loading state by calling load()
15935 // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793)
15936 if (typeof el.load === 'function') {
15937 // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
15948 Html5.resetMediaElement = function (el) {
15953 var sources = el.querySelectorAll('source');
15954 var i = sources.length;
15957 el.removeChild(sources[i]);
15960 // remove any src reference.
15961 // not setting `src=''` because that throws an error
15962 el.removeAttribute('src');
15964 if (typeof el.load === 'function') {
15965 // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
15976 /* Native HTML5 element property wrapping ----------------------------------- */
15977 // Wrap native properties with a getter
15980 * Get the value of `paused` from the media element. `paused` indicates whether the media element
15981 * is currently paused or not.
15983 * @method Html5#paused
15984 * @return {boolean}
15985 * The value of `paused` from the media element.
15987 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-paused}
15992 * Get the value of `currentTime` from the media element. `currentTime` indicates
15993 * the current second that the media is at in playback.
15995 * @method Html5#currentTime
15997 * The value of `currentTime` from the media element.
15999 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-currenttime}
16004 * Get the value of `buffered` from the media element. `buffered` is a `TimeRange`
16005 * object that represents the parts of the media that are already downloaded and
16006 * available for playback.
16008 * @method Html5#buffered
16009 * @return {TimeRange}
16010 * The value of `buffered` from the media element.
16012 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-buffered}
16017 * Get the value of `volume` from the media element. `volume` indicates
16018 * the current playback volume of audio for a media. `volume` will be a value from 0
16019 * (silent) to 1 (loudest and default).
16021 * @method Html5#volume
16023 * The value of `volume` from the media element. Value will be between 0-1.
16025 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume}
16030 * Get the value of `muted` from the media element. `muted` indicates
16031 * that the volume for the media should be set to silent. This does not actually change
16032 * the `volume` attribute.
16034 * @method Html5#muted
16035 * @return {boolean}
16036 * - True if the value of `volume` should be ignored and the audio set to silent.
16037 * - False if the value of `volume` should be used.
16039 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
16044 * Get the value of `poster` from the media element. `poster` indicates
16045 * that the url of an image file that can/will be shown when no media data is available.
16047 * @method Html5#poster
16049 * The value of `poster` from the media element. Value will be a url to an
16052 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-video-poster}
16057 * Get the value of `preload` from the media element. `preload` indicates
16058 * what should download before the media is interacted with. It can have the following
16060 * - none: nothing should be downloaded
16061 * - metadata: poster and the first few frames of the media may be downloaded to get
16062 * media dimensions and other metadata
16063 * - auto: allow the media and metadata for the media to be downloaded before
16066 * @method Html5#preload
16068 * The value of `preload` from the media element. Will be 'none', 'metadata',
16071 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload}
16076 * Get the value of `autoplay` from the media element. `autoplay` indicates
16077 * that the media should start to play as soon as the page is ready.
16079 * @method Html5#autoplay
16080 * @return {boolean}
16081 * - The value of `autoplay` from the media element.
16082 * - True indicates that the media should start as soon as the page loads.
16083 * - False indicates that the media should not start as soon as the page loads.
16085 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
16090 * Get the value of `controls` from the media element. `controls` indicates
16091 * whether the native media controls should be shown or hidden.
16093 * @method Html5#controls
16094 * @return {boolean}
16095 * - The value of `controls` from the media element.
16096 * - True indicates that native controls should be showing.
16097 * - False indicates that native controls should be hidden.
16099 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-controls}
16104 * Get the value of `loop` from the media element. `loop` indicates
16105 * that the media should return to the start of the media and continue playing once
16106 * it reaches the end.
16108 * @method Html5#loop
16109 * @return {boolean}
16110 * - The value of `loop` from the media element.
16111 * - True indicates that playback should seek back to start once
16112 * the end of a media is reached.
16113 * - False indicates that playback should not loop back to the start when the
16114 * end of the media is reached.
16116 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
16121 * Get the value of the `error` from the media element. `error` indicates any
16122 * MediaError that may have occured during playback. If error returns null there is no
16125 * @method Html5#error
16126 * @return {MediaError|null}
16127 * The value of `error` from the media element. Will be `MediaError` if there
16128 * is a current error and null otherwise.
16130 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-error}
16135 * Get the value of `seeking` from the media element. `seeking` indicates whether the
16136 * media is currently seeking to a new position or not.
16138 * @method Html5#seeking
16139 * @return {boolean}
16140 * - The value of `seeking` from the media element.
16141 * - True indicates that the media is currently seeking to a new position.
16142 * - Flase indicates that the media is not seeking to a new position at this time.
16144 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seeking}
16149 * Get the value of `seekable` from the media element. `seekable` returns a
16150 * `TimeRange` object indicating ranges of time that can currently be `seeked` to.
16152 * @method Html5#seekable
16153 * @return {TimeRange}
16154 * The value of `seekable` from the media element. A `TimeRange` object
16155 * indicating the current ranges of time that can be seeked to.
16157 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seekable}
16162 * Get the value of `ended` from the media element. `ended` indicates whether
16163 * the media has reached the end or not.
16165 * @method Html5#ended
16166 * @return {boolean}
16167 * - The value of `ended` from the media element.
16168 * - True indicates that the media has ended.
16169 * - False indicates that the media has not ended.
16171 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended}
16176 * Get the value of `defaultMuted` from the media element. `defaultMuted` indicates
16177 * whether the media should start muted or not. Only changes the default state of the
16178 * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
16181 * @method Html5#defaultMuted
16182 * @return {boolean}
16183 * - The value of `defaultMuted` from the media element.
16184 * - True indicates that the media should start muted.
16185 * - False indicates that the media should not start muted
16187 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
16192 * Get the value of `playbackRate` from the media element. `playbackRate` indicates
16193 * the rate at which the media is currently playing back. Examples:
16194 * - if playbackRate is set to 2, media will play twice as fast.
16195 * - if playbackRate is set to 0.5, media will play half as fast.
16197 * @method Html5#playbackRate
16199 * The value of `playbackRate` from the media element. A number indicating
16200 * the current playback speed of the media, where 1 is normal speed.
16202 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
16207 * Get the value of `played` from the media element. `played` returns a `TimeRange`
16208 * object representing points in the media timeline that have been played.
16210 * @method Html5#played
16211 * @return {TimeRange}
16212 * The value of `played` from the media element. A `TimeRange` object indicating
16213 * the ranges of time that have been played.
16215 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-played}
16220 * Get the value of `networkState` from the media element. `networkState` indicates
16221 * the current network state. It returns an enumeration from the following list:
16222 * - 0: NETWORK_EMPTY
16224 * - 2: NETWORK_LOADING
16225 * - 3: NETWORK_NO_SOURCE
16227 * @method Html5#networkState
16229 * The value of `networkState` from the media element. This will be a number
16230 * from the list in the description.
16232 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-networkstate}
16237 * Get the value of `readyState` from the media element. `readyState` indicates
16238 * the current state of the media element. It returns an enumeration from the
16240 * - 0: HAVE_NOTHING
16241 * - 1: HAVE_METADATA
16242 * - 2: HAVE_CURRENT_DATA
16243 * - 3: HAVE_FUTURE_DATA
16244 * - 4: HAVE_ENOUGH_DATA
16246 * @method Html5#readyState
16248 * The value of `readyState` from the media element. This will be a number
16249 * from the list in the description.
16251 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#ready-states}
16256 * Get the value of `videoWidth` from the video element. `videoWidth` indicates
16257 * the current width of the video in css pixels.
16259 * @method Html5#videoWidth
16261 * The value of `videoWidth` from the video element. This will be a number
16264 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth}
16269 * Get the value of `videoHeight` from the video element. `videoHeigth` indicates
16270 * the current height of the video in css pixels.
16272 * @method Html5#videoHeight
16274 * The value of `videoHeight` from the video element. This will be a number
16277 * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth}
16279 'videoHeight'].forEach(function (prop) {
16280 Html5.prototype[prop] = function () {
16281 return this.el_[prop];
16285 // Wrap native properties with a setter in this format:
16286 // set + toTitleCase(name)
16289 * Set the value of `volume` on the media element. `volume` indicates the current
16290 * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
16293 * @method Html5#setVolume
16294 * @param {number} percentAsDecimal
16295 * The volume percent as a decimal. Valid range is from 0-1.
16297 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume}
16302 * Set the value of `muted` on the media element. `muted` indicates the current
16303 * audio level should be silent.
16305 * @method Html5#setMuted
16306 * @param {boolean} muted
16307 * - True if the audio should be set to silent
16308 * - False otherwise
16310 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
16315 * Set the value of `src` on the media element. `src` indicates the current
16316 * {@link Tech~SourceObject} for the media.
16318 * @method Html5#setSrc
16319 * @param {Tech~SourceObject} src
16320 * The source object to set as the current source.
16322 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-src}
16327 * Set the value of `poster` on the media element. `poster` is the url to
16328 * an image file that can/will be shown when no media data is available.
16330 * @method Html5#setPoster
16331 * @param {string} poster
16332 * The url to an image that should be used as the `poster` for the media
16335 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-poster}
16340 * Set the value of `preload` on the media element. `preload` indicates
16341 * what should download before the media is interacted with. It can have the following
16343 * - none: nothing should be downloaded
16344 * - metadata: poster and the first few frames of the media may be downloaded to get
16345 * media dimensions and other metadata
16346 * - auto: allow the media and metadata for the media to be downloaded before
16349 * @method Html5#setPreload
16350 * @param {string} preload
16351 * The value of `preload` to set on the media element. Must be 'none', 'metadata',
16354 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload}
16359 * Set the value of `autoplay` on the media element. `autoplay` indicates
16360 * that the media should start to play as soon as the page is ready.
16362 * @method Html5#setAutoplay
16363 * @param {boolean} autoplay
16364 * - True indicates that the media should start as soon as the page loads.
16365 * - False indicates that the media should not start as soon as the page loads.
16367 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
16372 * Set the value of `loop` on the media element. `loop` indicates
16373 * that the media should return to the start of the media and continue playing once
16374 * it reaches the end.
16376 * @method Html5#setLoop
16377 * @param {boolean} loop
16378 * - True indicates that playback should seek back to start once
16379 * the end of a media is reached.
16380 * - False indicates that playback should not loop back to the start when the
16381 * end of the media is reached.
16383 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
16388 * Set the value of `playbackRate` on the media element. `playbackRate` indicates
16389 * the rate at which the media should play back. Examples:
16390 * - if playbackRate is set to 2, media will play twice as fast.
16391 * - if playbackRate is set to 0.5, media will play half as fast.
16393 * @method Html5#setPlaybackRate
16395 * The value of `playbackRate` from the media element. A number indicating
16396 * the current playback speed of the media, where 1 is normal speed.
16398 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
16400 'playbackRate'].forEach(function (prop) {
16401 Html5.prototype['set' + (0, _toTitleCase2['default'])(prop)] = function (v) {
16402 this.el_[prop] = v;
16406 // wrap native functions with a function
16409 * A wrapper around the media elements `pause` function. This will call the `HTML5`
16410 * media elements `pause` function.
16412 * @method Html5#pause
16413 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-pause}
16418 * A wrapper around the media elements `load` function. This will call the `HTML5`s
16419 * media element `load` function.
16421 * @method Html5#load
16422 * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-load}
16424 'load'].forEach(function (prop) {
16425 Html5.prototype[prop] = function () {
16426 return this.el_[prop]();
16430 _tech2['default'].withSourceHandlers(Html5);
16433 * Native source handler for Html5, simply passes the source to the media element.
16435 * @proprety {Tech~SourceObject} source
16436 * The source object
16438 * @proprety {Html5} tech
16439 * The instance of the HTML5 tech.
16441 Html5.nativeSourceHandler = {};
16444 * Check if the media element can play the given mime type.
16446 * @param {string} type
16447 * The mimetype to check
16450 * 'probably', 'maybe', or '' (empty string)
16452 Html5.nativeSourceHandler.canPlayType = function (type) {
16453 // IE9 on Windows 7 without MediaPlayer throws an error here
16454 // https://github.com/videojs/video.js/issues/519
16456 return Html5.TEST_VID.canPlayType(type);
16463 * Check if the media element can handle a source natively.
16465 * @param {Tech~SourceObject} source
16466 * The source object
16468 * @param {Object} [options]
16469 * Options to be passed to the tech.
16472 * 'probably', 'maybe', or '' (empty string).
16474 Html5.nativeSourceHandler.canHandleSource = function (source, options) {
16476 // If a type was provided we should rely on that
16478 return Html5.nativeSourceHandler.canPlayType(source.type);
16480 // If no type, fall back to checking 'video/[EXTENSION]'
16481 } else if (source.src) {
16482 var ext = Url.getFileExtension(source.src);
16484 return Html5.nativeSourceHandler.canPlayType('video/' + ext);
16491 * Pass the source to the native media element.
16493 * @param {Tech~SourceObject} source
16494 * The source object
16496 * @param {Html5} tech
16497 * The instance of the Html5 tech
16499 * @param {Object} [options]
16500 * The options to pass to the source
16502 Html5.nativeSourceHandler.handleSource = function (source, tech, options) {
16503 tech.setSrc(source.src);
16507 * A noop for the native dispose function, as cleanup is not needed.
16509 Html5.nativeSourceHandler.dispose = function () {};
16511 // Register the native source handler
16512 Html5.registerSourceHandler(Html5.nativeSourceHandler);
16514 _component2['default'].registerComponent('Html5', Html5);
16515 _tech2['default'].registerTech('Html5', Html5);
16516 exports['default'] = Html5;
16518 },{"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){
16521 exports.__esModule = true;
16523 var _component = _dereq_(5);
16525 var _component2 = _interopRequireDefault(_component);
16527 var _tech = _dereq_(62);
16529 var _tech2 = _interopRequireDefault(_tech);
16531 var _toTitleCase = _dereq_(91);
16533 var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
16535 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16537 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16539 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; }
16541 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; } /**
16547 * The `MediaLoader` is the `Component` that decides which playback technology to load
16548 * when a player is initialized.
16550 * @extends Component
16552 var MediaLoader = function (_Component) {
16553 _inherits(MediaLoader, _Component);
16556 * Create an instance of this class.
16558 * @param {Player} player
16559 * The `Player` that this class should attach to.
16561 * @param {Object} [options]
16562 * The key/value stroe of player options.
16564 * @param {Component~ReadyCallback} [ready]
16565 * The function that is run when this component is ready.
16567 function MediaLoader(player, options, ready) {
16568 _classCallCheck(this, MediaLoader);
16570 // If there are no sources when the player is initialized,
16571 // load the first supported playback technology.
16573 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready));
16575 if (!options.playerOptions.sources || options.playerOptions.sources.length === 0) {
16576 for (var i = 0, j = options.playerOptions.techOrder; i < j.length; i++) {
16577 var techName = (0, _toTitleCase2['default'])(j[i]);
16578 var tech = _tech2['default'].getTech(techName);
16580 // Support old behavior of techs being registered as components.
16581 // Remove once that deprecated behavior is removed.
16583 tech = _component2['default'].getComponent(techName);
16586 // Check if the browser supports this technology
16587 if (tech && tech.isSupported()) {
16588 player.loadTech_(techName);
16593 // Loop through playback technologies (HTML5, Flash) and check for support.
16594 // Then load the best source.
16595 // A few assumptions here:
16596 // All playback technologies respect preload false.
16597 player.src(options.playerOptions.sources);
16602 return MediaLoader;
16603 }(_component2['default']);
16605 _component2['default'].registerComponent('MediaLoader', MediaLoader);
16606 exports['default'] = MediaLoader;
16608 },{"5":5,"62":62,"91":91}],62:[function(_dereq_,module,exports){
16611 exports.__esModule = true;
16613 var _component = _dereq_(5);
16615 var _component2 = _interopRequireDefault(_component);
16617 var _htmlTrackElement = _dereq_(66);
16619 var _htmlTrackElement2 = _interopRequireDefault(_htmlTrackElement);
16621 var _htmlTrackElementList = _dereq_(65);
16623 var _htmlTrackElementList2 = _interopRequireDefault(_htmlTrackElementList);
16625 var _mergeOptions = _dereq_(87);
16627 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
16629 var _textTrack = _dereq_(72);
16631 var _textTrack2 = _interopRequireDefault(_textTrack);
16633 var _textTrackList = _dereq_(70);
16635 var _textTrackList2 = _interopRequireDefault(_textTrackList);
16637 var _videoTrackList = _dereq_(76);
16639 var _videoTrackList2 = _interopRequireDefault(_videoTrackList);
16641 var _audioTrackList = _dereq_(63);
16643 var _audioTrackList2 = _interopRequireDefault(_audioTrackList);
16645 var _fn = _dereq_(83);
16647 var Fn = _interopRequireWildcard(_fn);
16649 var _log = _dereq_(86);
16651 var _log2 = _interopRequireDefault(_log);
16653 var _timeRanges = _dereq_(90);
16655 var _buffer = _dereq_(79);
16657 var _mediaError = _dereq_(46);
16659 var _mediaError2 = _interopRequireDefault(_mediaError);
16661 var _window = _dereq_(95);
16663 var _window2 = _interopRequireDefault(_window);
16665 var _document = _dereq_(94);
16667 var _document2 = _interopRequireDefault(_document);
16669 var _obj = _dereq_(88);
16671 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; } }
16673 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
16675 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16677 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; }
16679 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; } /**
16684 * An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string
16685 * that just contains the src url alone.
16686 * * `var SourceObject = {src: 'http://ex.com/video.mp4', type: 'video/mp4'};`
16687 * `var SourceString = 'http://example.com/some-video.mp4';`
16689 * @typedef {Object|string} Tech~SourceObject
16691 * @property {string} src
16692 * The url to the source
16694 * @property {string} type
16695 * The mime type of the source
16699 * A function used by {@link Tech} to create a new {@link TextTrack}.
16701 * @param {Tech} self
16702 * An instance of the Tech class.
16704 * @param {string} kind
16705 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
16707 * @param {string} [label]
16708 * Label to identify the text track
16710 * @param {string} [language]
16711 * Two letter language abbreviation
16713 * @param {Object} [options={}]
16714 * An object with additional text track options
16716 * @return {TextTrack}
16717 * The text track that was created.
16719 function createTrackHelper(self, kind, label, language) {
16720 var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
16722 var tracks = self.textTracks();
16724 options.kind = kind;
16727 options.label = label;
16730 options.language = language;
16732 options.tech = self;
16734 var track = new _textTrack2['default'](options);
16736 tracks.addTrack_(track);
16742 * This is the base class for media playback technology controllers, such as
16743 * {@link Flash} and {@link HTML5}
16745 * @extends Component
16748 var Tech = function (_Component) {
16749 _inherits(Tech, _Component);
16752 * Create an instance of this Tech.
16754 * @param {Object} [options]
16755 * The key/value store of player options.
16757 * @param {Component~ReadyCallback} ready
16758 * Callback function to call when the `HTML5` Tech is ready.
16761 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
16762 var ready = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
16764 _classCallCheck(this, Tech);
16766 // we don't want the tech to report user activity automatically.
16767 // This is done manually in addControlsListeners
16768 options.reportTouchActivity = false;
16770 // keep track of whether the current source has played at all to
16771 // implement a very limited played()
16772 var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready));
16774 _this.hasStarted_ = false;
16775 _this.on('playing', function () {
16776 this.hasStarted_ = true;
16778 _this.on('loadstart', function () {
16779 this.hasStarted_ = false;
16782 _this.textTracks_ = options.textTracks;
16783 _this.videoTracks_ = options.videoTracks;
16784 _this.audioTracks_ = options.audioTracks;
16786 // Manually track progress in cases where the browser/flash player doesn't report it.
16787 if (!_this.featuresProgressEvents) {
16788 _this.manualProgressOn();
16791 // Manually track timeupdates in cases where the browser/flash player doesn't report it.
16792 if (!_this.featuresTimeupdateEvents) {
16793 _this.manualTimeUpdatesOn();
16796 ['Text', 'Audio', 'Video'].forEach(function (track) {
16797 if (options['native' + track + 'Tracks'] === false) {
16798 _this['featuresNative' + track + 'Tracks'] = false;
16802 if (options.nativeCaptions === false) {
16803 _this.featuresNativeTextTracks = false;
16806 if (!_this.featuresNativeTextTracks) {
16807 _this.emulateTextTracks();
16810 _this.autoRemoteTextTracks_ = new _textTrackList2['default']();
16812 _this.initTextTrackListeners();
16813 _this.initTrackListeners();
16815 // Turn on component tap events only if not using native controls
16816 if (!options.nativeControlsForTouch) {
16817 _this.emitTapEvents();
16820 if (_this.constructor) {
16821 _this.name_ = _this.constructor.name || 'Unknown Tech';
16826 /* Fallbacks for unsupported event types
16827 ================================================================================ */
16830 * Polyfill the `progress` event for browsers that don't support it natively.
16832 * @see {@link Tech#trackProgress}
16836 Tech.prototype.manualProgressOn = function manualProgressOn() {
16837 this.on('durationchange', this.onDurationChange);
16839 this.manualProgress = true;
16841 // Trigger progress watching when a source begins loading
16842 this.one('ready', this.trackProgress);
16846 * Turn off the polyfill for `progress` events that was created in
16847 * {@link Tech#manualProgressOn}
16851 Tech.prototype.manualProgressOff = function manualProgressOff() {
16852 this.manualProgress = false;
16853 this.stopTrackingProgress();
16855 this.off('durationchange', this.onDurationChange);
16859 * This is used to trigger a `progress` event when the buffered percent changes. It
16860 * sets an interval function that will be called every 500 milliseconds to check if the
16861 * buffer end percent has changed.
16863 * > This function is called by {@link Tech#manualProgressOn}
16865 * @param {EventTarget~Event} event
16866 * The `ready` event that caused this to run.
16868 * @listens Tech#ready
16869 * @fires Tech#progress
16873 Tech.prototype.trackProgress = function trackProgress(event) {
16874 this.stopTrackingProgress();
16875 this.progressInterval = this.setInterval(Fn.bind(this, function () {
16876 // Don't trigger unless buffered amount is greater than last time
16878 var numBufferedPercent = this.bufferedPercent();
16880 if (this.bufferedPercent_ !== numBufferedPercent) {
16882 * See {@link Player#progress}
16884 * @event Tech#progress
16885 * @type {EventTarget~Event}
16887 this.trigger('progress');
16890 this.bufferedPercent_ = numBufferedPercent;
16892 if (numBufferedPercent === 1) {
16893 this.stopTrackingProgress();
16899 * Update our internal duration on a `durationchange` event by calling
16900 * {@link Tech#duration}.
16902 * @param {EventTarget~Event} event
16903 * The `durationchange` event that caused this to run.
16905 * @listens Tech#durationchange
16909 Tech.prototype.onDurationChange = function onDurationChange(event) {
16910 this.duration_ = this.duration();
16914 * Get and create a `TimeRange` object for buffering.
16916 * @return {TimeRange}
16917 * The time range object that was created.
16921 Tech.prototype.buffered = function buffered() {
16922 return (0, _timeRanges.createTimeRange)(0, 0);
16926 * Get the percentage of the current video that is currently buffered.
16929 * A number from 0 to 1 that represents the decimal percentage of the
16930 * video that is buffered.
16935 Tech.prototype.bufferedPercent = function bufferedPercent() {
16936 return (0, _buffer.bufferedPercent)(this.buffered(), this.duration_);
16940 * Turn off the polyfill for `progress` events that was created in
16941 * {@link Tech#manualProgressOn}
16942 * Stop manually tracking progress events by clearing the interval that was set in
16943 * {@link Tech#trackProgress}.
16947 Tech.prototype.stopTrackingProgress = function stopTrackingProgress() {
16948 this.clearInterval(this.progressInterval);
16952 * Polyfill the `timeupdate` event for browsers that don't support it.
16954 * @see {@link Tech#trackCurrentTime}
16958 Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() {
16959 this.manualTimeUpdates = true;
16961 this.on('play', this.trackCurrentTime);
16962 this.on('pause', this.stopTrackingCurrentTime);
16966 * Turn off the polyfill for `timeupdate` events that was created in
16967 * {@link Tech#manualTimeUpdatesOn}
16971 Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() {
16972 this.manualTimeUpdates = false;
16973 this.stopTrackingCurrentTime();
16974 this.off('play', this.trackCurrentTime);
16975 this.off('pause', this.stopTrackingCurrentTime);
16979 * Sets up an interval function to track current time and trigger `timeupdate` every
16980 * 250 milliseconds.
16982 * @listens Tech#play
16983 * @triggers Tech#timeupdate
16987 Tech.prototype.trackCurrentTime = function trackCurrentTime() {
16988 if (this.currentTimeInterval) {
16989 this.stopTrackingCurrentTime();
16991 this.currentTimeInterval = this.setInterval(function () {
16993 * Triggered at an interval of 250ms to indicated that time is passing in the video.
16995 * @event Tech#timeupdate
16996 * @type {EventTarget~Event}
16998 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
17000 // 42 = 24 fps // 250 is what Webkit uses // FF uses 15
17005 * Stop the interval function created in {@link Tech#trackCurrentTime} so that the
17006 * `timeupdate` event is no longer triggered.
17008 * @listens {Tech#pause}
17012 Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() {
17013 this.clearInterval(this.currentTimeInterval);
17015 // #1002 - if the video ends right before the next timeupdate would happen,
17016 // the progress bar won't make it all the way to the end
17017 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
17021 * Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList},
17022 * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech.
17024 * @fires Component#dispose
17028 Tech.prototype.dispose = function dispose() {
17030 // clear out all tracks because we can't reuse them between techs
17031 this.clearTracks(['audio', 'video', 'text']);
17033 // Turn off any manual progress or timeupdate tracking
17034 if (this.manualProgress) {
17035 this.manualProgressOff();
17038 if (this.manualTimeUpdates) {
17039 this.manualTimeUpdatesOff();
17042 _Component.prototype.dispose.call(this);
17046 * Clear out a single `TrackList` or an array of `TrackLists` given their names.
17048 * > Note: Techs without source handlers should call this between sources for `video`
17049 * & `audio` tracks. You don't want to use them between tracks!
17051 * @param {string[]|string} types
17052 * TrackList names to clear, valid names are `video`, `audio`, and
17057 Tech.prototype.clearTracks = function clearTracks(types) {
17060 types = [].concat(types);
17061 // clear out all tracks because we can't reuse them between techs
17062 types.forEach(function (type) {
17063 var list = _this2[type + 'Tracks']() || [];
17064 var i = list.length;
17067 var track = list[i];
17069 if (type === 'text') {
17070 _this2.removeRemoteTextTrack(track);
17072 list.removeTrack_(track);
17078 * Remove any TextTracks added via addRemoteTextTrack that are
17079 * flagged for automatic garbage collection
17083 Tech.prototype.cleanupAutoTextTracks = function cleanupAutoTextTracks() {
17084 var list = this.autoRemoteTextTracks_ || [];
17085 var i = list.length;
17088 var track = list[i];
17090 this.removeRemoteTextTrack(track);
17095 * Reset the tech, which will removes all sources and reset the internal readyState.
17101 Tech.prototype.reset = function reset() {};
17104 * Get or set an error on the Tech.
17106 * @param {MediaError} [err]
17107 * Error to set on the Tech
17109 * @return {MediaError|null}
17110 * The current error object on the tech, or null if there isn't one.
17114 Tech.prototype.error = function error(err) {
17115 if (err !== undefined) {
17116 this.error_ = new _mediaError2['default'](err);
17117 this.trigger('error');
17119 return this.error_;
17123 * Returns the `TimeRange`s that have been played through for the current source.
17125 * > NOTE: This implementation is incomplete. It does not track the played `TimeRange`.
17126 * It only checks wether the source has played at all or not.
17128 * @return {TimeRange}
17129 * - A single time range if this video has played
17130 * - An empty set of ranges if not.
17134 Tech.prototype.played = function played() {
17135 if (this.hasStarted_) {
17136 return (0, _timeRanges.createTimeRange)(0, 0);
17138 return (0, _timeRanges.createTimeRange)();
17142 * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was
17143 * previously called.
17145 * @fires Tech#timeupdate
17149 Tech.prototype.setCurrentTime = function setCurrentTime() {
17150 // improve the accuracy of manual timeupdates
17151 if (this.manualTimeUpdates) {
17153 * A manual `timeupdate` event.
17155 * @event Tech#timeupdate
17156 * @type {EventTarget~Event}
17158 this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
17163 * Turn on listeners for {@link TextTrackList} events. This adds
17164 * {@link EventTarget~EventListeners} for `texttrackchange`, `addtrack` and
17167 * @fires Tech#texttrackchange
17171 Tech.prototype.initTextTrackListeners = function initTextTrackListeners() {
17172 var textTrackListChanges = Fn.bind(this, function () {
17174 * Triggered when tracks are added or removed on the Tech {@link TextTrackList}
17176 * @event Tech#texttrackchange
17177 * @type {EventTarget~Event}
17179 this.trigger('texttrackchange');
17182 var tracks = this.textTracks();
17188 tracks.addEventListener('removetrack', textTrackListChanges);
17189 tracks.addEventListener('addtrack', textTrackListChanges);
17191 this.on('dispose', Fn.bind(this, function () {
17192 tracks.removeEventListener('removetrack', textTrackListChanges);
17193 tracks.removeEventListener('addtrack', textTrackListChanges);
17198 * Turn on listeners for {@link VideoTrackList} and {@link {AudioTrackList} events.
17199 * This adds {@link EventTarget~EventListeners} for `addtrack`, and `removetrack`.
17201 * @fires Tech#audiotrackchange
17202 * @fires Tech#videotrackchange
17206 Tech.prototype.initTrackListeners = function initTrackListeners() {
17209 var trackTypes = ['video', 'audio'];
17211 trackTypes.forEach(function (type) {
17213 * Triggered when tracks are added or removed on the Tech {@link AudioTrackList}
17215 * @event Tech#audiotrackchange
17216 * @type {EventTarget~Event}
17220 * Triggered when tracks are added or removed on the Tech {@link VideoTrackList}
17222 * @event Tech#videotrackchange
17223 * @type {EventTarget~Event}
17225 var trackListChanges = function trackListChanges() {
17226 _this3.trigger(type + 'trackchange');
17229 var tracks = _this3[type + 'Tracks']();
17231 tracks.addEventListener('removetrack', trackListChanges);
17232 tracks.addEventListener('addtrack', trackListChanges);
17234 _this3.on('dispose', function () {
17235 tracks.removeEventListener('removetrack', trackListChanges);
17236 tracks.removeEventListener('addtrack', trackListChanges);
17242 * Emulate TextTracks using vtt.js if necessary
17244 * @fires Tech#vttjsloaded
17245 * @fires Tech#vttjserror
17249 Tech.prototype.addWebVttScript_ = function addWebVttScript_() {
17252 if (_window2['default'].WebVTT) {
17256 // Initially, Tech.el_ is a child of a dummy-div wait until the Component system
17257 // signals that the Tech is ready at which point Tech.el_ is part of the DOM
17258 // before inserting the WebVTT script
17259 if (_document2['default'].body.contains(this.el())) {
17260 var vtt = _dereq_(105);
17262 // load via require if available and vtt.js script location was not passed in
17263 // as an option. novtt builds will turn the above require call into an empty object
17264 // which will cause this if check to always fail.
17265 if (!this.options_['vtt.js'] && (0, _obj.isPlain)(vtt) && Object.keys(vtt).length > 0) {
17266 this.trigger('vttjsloaded');
17270 // load vtt.js via the script location option or the cdn of no location was
17272 var script = _document2['default'].createElement('script');
17274 script.src = this.options_['vtt.js'] || 'https://vjs.zencdn.net/vttjs/0.12.3/vtt.min.js';
17275 script.onload = function () {
17277 * Fired when vtt.js is loaded.
17279 * @event Tech#vttjsloaded
17280 * @type {EventTarget~Event}
17282 _this4.trigger('vttjsloaded');
17284 script.onerror = function () {
17286 * Fired when vtt.js was not loaded due to an error
17288 * @event Tech#vttjsloaded
17289 * @type {EventTarget~Event}
17291 _this4.trigger('vttjserror');
17293 this.on('dispose', function () {
17294 script.onload = null;
17295 script.onerror = null;
17297 // but have not loaded yet and we set it to true before the inject so that
17298 // we don't overwrite the injected window.WebVTT if it loads right away
17299 _window2['default'].WebVTT = true;
17300 this.el().parentNode.appendChild(script);
17302 this.ready(this.addWebVttScript_);
17307 * Emulate texttracks
17309 * @method emulateTextTracks
17313 Tech.prototype.emulateTextTracks = function emulateTextTracks() {
17316 var tracks = this.textTracks();
17322 var remoteTracks = this.remoteTextTracks();
17323 var handleAddTrack = function handleAddTrack(e) {
17324 return tracks.addTrack_(e.track);
17326 var handleRemoveTrack = function handleRemoveTrack(e) {
17327 return tracks.removeTrack_(e.track);
17330 remoteTracks.on('addtrack', handleAddTrack);
17331 remoteTracks.on('removetrack', handleRemoveTrack);
17333 this.addWebVttScript_();
17335 var updateDisplay = function updateDisplay() {
17336 return _this5.trigger('texttrackchange');
17339 var textTracksChanges = function textTracksChanges() {
17342 for (var i = 0; i < tracks.length; i++) {
17343 var track = tracks[i];
17345 track.removeEventListener('cuechange', updateDisplay);
17346 if (track.mode === 'showing') {
17347 track.addEventListener('cuechange', updateDisplay);
17352 textTracksChanges();
17353 tracks.addEventListener('change', textTracksChanges);
17354 tracks.addEventListener('addtrack', textTracksChanges);
17355 tracks.addEventListener('removetrack', textTracksChanges);
17357 this.on('dispose', function () {
17358 remoteTracks.off('addtrack', handleAddTrack);
17359 remoteTracks.off('removetrack', handleRemoveTrack);
17360 tracks.removeEventListener('change', textTracksChanges);
17361 tracks.removeEventListener('addtrack', textTracksChanges);
17362 tracks.removeEventListener('removetrack', textTracksChanges);
17364 for (var i = 0; i < tracks.length; i++) {
17365 var track = tracks[i];
17367 track.removeEventListener('cuechange', updateDisplay);
17373 * Get the `Tech`s {@link VideoTrackList}.
17375 * @return {VideoTrackList}
17376 * The video track list that the Tech is currently using.
17380 Tech.prototype.videoTracks = function videoTracks() {
17381 this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default']();
17382 return this.videoTracks_;
17386 * Get the `Tech`s {@link AudioTrackList}.
17388 * @return {AudioTrackList}
17389 * The audio track list that the Tech is currently using.
17393 Tech.prototype.audioTracks = function audioTracks() {
17394 this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default']();
17395 return this.audioTracks_;
17399 * Get the `Tech`s {@link TextTrackList}.
17401 * @return {TextTrackList}
17402 * The text track list that the Tech is currently using.
17406 Tech.prototype.textTracks = function textTracks() {
17407 this.textTracks_ = this.textTracks_ || new _textTrackList2['default']();
17408 return this.textTracks_;
17412 * Get the `Tech`s remote {@link TextTrackList}, which is created from elements
17413 * that were added to the DOM.
17415 * @return {TextTrackList}
17416 * The remote text track list that the Tech is currently using.
17420 Tech.prototype.remoteTextTracks = function remoteTextTracks() {
17421 this.remoteTextTracks_ = this.remoteTextTracks_ || new _textTrackList2['default']();
17422 return this.remoteTextTracks_;
17426 * Get The `Tech`s {HTMLTrackElementList}, which are the elements in the DOM that are
17427 * being used as TextTracks.
17429 * @return {HTMLTrackElementList}
17430 * The current HTML track elements that exist for the tech.
17434 Tech.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
17435 this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new _htmlTrackElementList2['default']();
17436 return this.remoteTextTrackEls_;
17440 * Create and returns a remote {@link TextTrack} object.
17442 * @param {string} kind
17443 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
17445 * @param {string} [label]
17446 * Label to identify the text track
17448 * @param {string} [language]
17449 * Two letter language abbreviation
17451 * @return {TextTrack}
17452 * The TextTrack that gets created.
17456 Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) {
17458 throw new Error('TextTrack kind is required but was not provided');
17461 return createTrackHelper(this, kind, label, language);
17465 * Create an emulated TextTrack for use by addRemoteTextTrack
17467 * This is intended to be overridden by classes that inherit from
17468 * Tech in order to create native or custom TextTracks.
17470 * @param {Object} options
17471 * The object should contain the options to initialize the TextTrack with.
17473 * @param {string} [options.kind]
17474 * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
17476 * @param {string} [options.label].
17477 * Label to identify the text track
17479 * @param {string} [options.language]
17480 * Two letter language abbreviation.
17482 * @return {HTMLTrackElement}
17483 * The track element that gets created.
17487 Tech.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) {
17488 var track = (0, _mergeOptions2['default'])(options, {
17492 return new _htmlTrackElement2['default'](track);
17496 * Creates a remote text track object and returns an html track element.
17498 * > Note: This can be an emulated {@link HTMLTrackElement} or a native one.
17500 * @param {Object} options
17501 * See {@link Tech#createRemoteTextTrack} for more detailed properties.
17503 * @param {boolean} [manualCleanup=true]
17504 * - When false: the TextTrack will be automatically removed from the video
17505 * element whenever the source changes
17506 * - When True: The TextTrack will have to be cleaned up manually
17508 * @return {HTMLTrackElement}
17509 * An Html Track Element.
17511 * @deprecated The default functionality for this function will be equivalent
17512 * to "manualCleanup=false" in the future. The manualCleanup parameter will
17517 Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack() {
17518 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
17519 var manualCleanup = arguments[1];
17521 var htmlTrackElement = this.createRemoteTextTrack(options);
17523 if (manualCleanup !== true && manualCleanup !== false) {
17524 // deprecation warning
17525 _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');
17526 manualCleanup = true;
17529 // store HTMLTrackElement and TextTrack to remote list
17530 this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
17531 this.remoteTextTracks().addTrack_(htmlTrackElement.track);
17533 if (manualCleanup !== true) {
17534 // create the TextTrackList if it doesn't exist
17535 this.autoRemoteTextTracks_.addTrack_(htmlTrackElement.track);
17538 return htmlTrackElement;
17542 * Remove a remote text track from the remote `TextTrackList`.
17544 * @param {TextTrack} track
17545 * `TextTrack` to remove from the `TextTrackList`
17549 Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
17550 var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
17552 // remove HTMLTrackElement and TextTrack from remote list
17553 this.remoteTextTrackEls().removeTrackElement_(trackElement);
17554 this.remoteTextTracks().removeTrack_(track);
17555 this.autoRemoteTextTracks_.removeTrack_(track);
17559 * A method to set a poster from a `Tech`.
17565 Tech.prototype.setPoster = function setPoster() {};
17568 * Check if the tech can support the given mime-type.
17570 * The base tech does not support any type, but source handlers might
17573 * @param {string} type
17574 * The mimetype to check for support
17577 * 'probably', 'maybe', or empty string
17579 * @see [Spec]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType}
17585 Tech.prototype.canPlayType = function canPlayType() {
17590 * Return whether the argument is a Tech or not.
17591 * Can be passed either a Class like `Html5` or a instance like `player.tech_`
17593 * @param {Object} component
17594 * The item to check
17596 * @return {boolean}
17597 * Whether it is a tech or not
17598 * - True if it is a tech
17599 * - False if it is not
17603 Tech.isTech = function isTech(component) {
17604 return component.prototype instanceof Tech || component instanceof Tech || component === Tech;
17608 * Registers a `Tech` into a shared list for videojs.
17610 * @param {string} name
17611 * Name of the `Tech` to register.
17613 * @param {Object} tech
17614 * The `Tech` class to register.
17618 Tech.registerTech = function registerTech(name, tech) {
17619 if (!Tech.techs_) {
17623 if (!Tech.isTech(tech)) {
17624 throw new Error('Tech ' + name + ' must be a Tech');
17627 Tech.techs_[name] = tech;
17632 * Get a `Tech` from the shared list by name.
17634 * @param {string} name
17635 * Name of the component to get
17637 * @return {Tech|undefined}
17638 * The `Tech` or undefined if there was no tech with the name requsted.
17642 Tech.getTech = function getTech(name) {
17643 if (Tech.techs_ && Tech.techs_[name]) {
17644 return Tech.techs_[name];
17647 if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) {
17648 _log2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)');
17649 return _window2['default'].videojs[name];
17654 }(_component2['default']);
17657 * List of associated text tracks.
17659 * @type {TextTrackList}
17664 Tech.prototype.textTracks_; // eslint-disable-line
17667 * List of associated audio tracks.
17669 * @type {AudioTrackList}
17672 Tech.prototype.audioTracks_; // eslint-disable-line
17675 * List of associated video tracks.
17677 * @type {VideoTrackList}
17680 Tech.prototype.videoTracks_; // eslint-disable-line
17683 * Boolean indicating wether the `Tech` supports volume control.
17688 Tech.prototype.featuresVolumeControl = true;
17691 * Boolean indicating wether the `Tech` support fullscreen resize control.
17692 * Resizing plugins using request fullscreen reloads the plugin
17697 Tech.prototype.featuresFullscreenResize = false;
17700 * Boolean indicating wether the `Tech` supports changing the speed at which the video
17702 * - Set player to play 2x (twice) as fast
17703 * - Set player to play 0.5x (half) as fast
17708 Tech.prototype.featuresPlaybackRate = false;
17711 * Boolean indicating wether the `Tech` supports the `progress` event. This is currently
17712 * not triggered by video-js-swf. This will be used to determine if
17713 * {@link Tech#manualProgressOn} should be called.
17718 Tech.prototype.featuresProgressEvents = false;
17721 * Boolean indicating wether the `Tech` supports the `timeupdate` event. This is currently
17722 * not triggered by video-js-swf. This will be used to determine if
17723 * {@link Tech#manualTimeUpdates} should be called.
17728 Tech.prototype.featuresTimeupdateEvents = false;
17731 * Boolean indicating wether the `Tech` supports the native `TextTrack`s.
17732 * This will help us integrate with native `TextTrack`s if the browser supports them.
17737 Tech.prototype.featuresNativeTextTracks = false;
17740 * A functional mixin for techs that want to use the Source Handler pattern.
17741 * Source handlers are scripts for handling specific formats.
17742 * The source handler pattern is used for adaptive formats (HLS, DASH) that
17743 * manually load video data and feed it into a Source Buffer (Media Source Extensions)
17744 * Example: `Tech.withSourceHandlers.call(MyTech);`
17746 * @param {Tech} _Tech
17747 * The tech to add source handler functions to.
17749 * @mixes Tech~SourceHandlerAdditions
17751 Tech.withSourceHandlers = function (_Tech) {
17754 * Register a source handler
17756 * @param {Function} handler
17757 * The source handler class
17759 * @param {number} [index]
17760 * Register it at the following index
17762 _Tech.registerSourceHandler = function (handler, index) {
17763 var handlers = _Tech.sourceHandlers;
17766 handlers = _Tech.sourceHandlers = [];
17769 if (index === undefined) {
17770 // add to the end of the list
17771 index = handlers.length;
17774 handlers.splice(index, 0, handler);
17778 * Check if the tech can support the given type. Also checks the
17779 * Techs sourceHandlers.
17781 * @param {string} type
17782 * The mimetype to check.
17785 * 'probably', 'maybe', or '' (empty string)
17787 _Tech.canPlayType = function (type) {
17788 var handlers = _Tech.sourceHandlers || [];
17791 for (var i = 0; i < handlers.length; i++) {
17792 can = handlers[i].canPlayType(type);
17803 * Returns the first source handler that supports the source.
17805 * TODO: Answer question: should 'probably' be prioritized over 'maybe'
17807 * @param {Tech~SourceObject} source
17808 * The source object
17810 * @param {Object} options
17811 * The options passed to the tech
17813 * @return {SourceHandler|null}
17814 * The first source handler that supports the source or null if
17815 * no SourceHandler supports the source
17817 _Tech.selectSourceHandler = function (source, options) {
17818 var handlers = _Tech.sourceHandlers || [];
17821 for (var i = 0; i < handlers.length; i++) {
17822 can = handlers[i].canHandleSource(source, options);
17825 return handlers[i];
17833 * Check if the tech can support the given source.
17835 * @param {Tech~SourceObject} srcObj
17836 * The source object
17838 * @param {Object} options
17839 * The options passed to the tech
17842 * 'probably', 'maybe', or '' (empty string)
17844 _Tech.canPlaySource = function (srcObj, options) {
17845 var sh = _Tech.selectSourceHandler(srcObj, options);
17848 return sh.canHandleSource(srcObj, options);
17855 * When using a source handler, prefer its implementation of
17856 * any function normally provided by the tech.
17858 var deferrable = ['seekable', 'duration'];
17861 * A wrapper around {@link Tech#seekable} that will call a `SourceHandler`s seekable
17862 * function if it exists, with a fallback to the Techs seekable function.
17864 * @method _Tech.seekable
17868 * A wrapper around {@link Tech#duration} that will call a `SourceHandler`s duration
17869 * function if it exists, otherwise it will fallback to the techs duration function.
17871 * @method _Tech.duration
17874 deferrable.forEach(function (fnName) {
17875 var originalFn = this[fnName];
17877 if (typeof originalFn !== 'function') {
17881 this[fnName] = function () {
17882 if (this.sourceHandler_ && this.sourceHandler_[fnName]) {
17883 return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments);
17885 return originalFn.apply(this, arguments);
17887 }, _Tech.prototype);
17890 * Create a function for setting the source using a source object
17891 * and source handlers.
17892 * Should never be called unless a source handler was found.
17894 * @param {Tech~SourceObject} source
17895 * A source object with src and type keys
17898 * Returns itself; this method is chainable
17900 _Tech.prototype.setSource = function (source) {
17901 var sh = _Tech.selectSourceHandler(source, this.options_);
17904 // Fall back to a native source hander when unsupported sources are
17905 // deliberately set
17906 if (_Tech.nativeSourceHandler) {
17907 sh = _Tech.nativeSourceHandler;
17909 _log2['default'].error('No source hander found for the current source.');
17913 // Dispose any existing source handler
17914 this.disposeSourceHandler();
17915 this.off('dispose', this.disposeSourceHandler);
17917 if (sh !== _Tech.nativeSourceHandler) {
17918 this.currentSource_ = source;
17920 // Catch if someone replaced the src without calling setSource.
17921 // If they do, set currentSource_ to null and dispose our source handler.
17922 this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17923 this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17924 this.one(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17927 this.sourceHandler_ = sh.handleSource(source, this, this.options_);
17928 this.on('dispose', this.disposeSourceHandler);
17934 * Called once for the first loadstart of a video.
17936 * @listens Tech#loadstart
17938 _Tech.prototype.firstLoadStartListener_ = function () {
17939 this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17942 // On successive loadstarts when setSource has not been called again
17944 * Called after the first loadstart for a video occurs.
17946 * @listens Tech#loadstart
17948 _Tech.prototype.successiveLoadStartListener_ = function () {
17949 this.disposeSourceHandler();
17950 this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17954 * Clean up any existing SourceHandlers and listeners when the Tech is disposed.
17956 * @listens Tech#dispose
17958 _Tech.prototype.disposeSourceHandler = function () {
17959 // if we have a source and get another one
17960 // then we are loading something new
17961 // than clear all of our current tracks
17962 if (this.currentSource_) {
17963 this.clearTracks(['audio', 'video']);
17964 this.currentSource_ = null;
17967 // always clean up auto-text tracks
17968 this.cleanupAutoTextTracks();
17970 if (this.sourceHandler_) {
17971 this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
17972 this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
17974 if (this.sourceHandler_.dispose) {
17975 this.sourceHandler_.dispose();
17978 this.sourceHandler_ = null;
17983 _component2['default'].registerComponent('Tech', Tech);
17984 // Old name for Tech
17986 _component2['default'].registerComponent('MediaTechController', Tech);
17987 Tech.registerTech('Tech', Tech);
17988 exports['default'] = Tech;
17990 },{"105":105,"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){
17993 exports.__esModule = true;
17995 var _trackList = _dereq_(74);
17997 var _trackList2 = _interopRequireDefault(_trackList);
17999 var _browser = _dereq_(78);
18001 var browser = _interopRequireWildcard(_browser);
18003 var _document = _dereq_(94);
18005 var _document2 = _interopRequireDefault(_document);
18007 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; } }
18009 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18011 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18013 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; }
18015 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; } /**
18016 * @file audio-track-list.js
18021 * Anywhere we call this function we diverge from the spec
18022 * as we only support one enabled audiotrack at a time
18024 * @param {AudioTrackList} list
18027 * @param {AudioTrack} track
18028 * The track to skip
18032 var disableOthers = function disableOthers(list, track) {
18033 for (var i = 0; i < list.length; i++) {
18034 if (track.id === list[i].id) {
18037 // another audio track is enabled, disable it
18038 list[i].enabled = false;
18043 * The current list of {@link AudioTrack} for a media file.
18045 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist}
18046 * @extends TrackList
18049 var AudioTrackList = function (_TrackList) {
18050 _inherits(AudioTrackList, _TrackList);
18053 * Create an instance of this class.
18055 * @param {AudioTrack[]} [tracks=[]]
18056 * A list of `AudioTrack` to instantiate the list with.
18058 function AudioTrackList() {
18061 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
18063 _classCallCheck(this, AudioTrackList);
18067 // make sure only 1 track is enabled
18068 // sorted from last index to first index
18069 for (var i = tracks.length - 1; i >= 0; i--) {
18070 if (tracks[i].enabled) {
18071 disableOthers(tracks, tracks[i]);
18076 // IE8 forces us to implement inheritance ourselves
18077 // as it does not support Object.defineProperty properly
18078 if (browser.IS_IE8) {
18079 list = _document2['default'].createElement('custom');
18080 for (var prop in _trackList2['default'].prototype) {
18081 if (prop !== 'constructor') {
18082 list[prop] = _trackList2['default'].prototype[prop];
18085 for (var _prop in AudioTrackList.prototype) {
18086 if (_prop !== 'constructor') {
18087 list[_prop] = AudioTrackList.prototype[_prop];
18092 list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
18093 list.changing_ = false;
18095 return _ret = list, _possibleConstructorReturn(_this, _ret);
18099 * Add an {@link AudioTrack} to the `AudioTrackList`.
18101 * @param {AudioTrack} track
18102 * The AudioTrack to add to the list
18104 * @fires Track#addtrack
18109 AudioTrackList.prototype.addTrack_ = function addTrack_(track) {
18112 if (track.enabled) {
18113 disableOthers(this, track);
18116 _TrackList.prototype.addTrack_.call(this, track);
18117 // native tracks don't have this
18118 if (!track.addEventListener) {
18123 * @listens AudioTrack#enabledchange
18124 * @fires TrackList#change
18126 track.addEventListener('enabledchange', function () {
18127 // when we are disabling other tracks (since we don't support
18128 // more than one track at a time) we will set changing_
18129 // to true so that we don't trigger additional change events
18130 if (_this2.changing_) {
18133 _this2.changing_ = true;
18134 disableOthers(_this2, track);
18135 _this2.changing_ = false;
18136 _this2.trigger('change');
18141 * Add an {@link AudioTrack} to the `AudioTrackList`.
18143 * @param {AudioTrack} track
18144 * The AudioTrack to add to the list
18146 * @fires Track#addtrack
18150 AudioTrackList.prototype.addTrack = function addTrack(track) {
18151 this.addTrack_(track);
18155 * Remove an {@link AudioTrack} from the `AudioTrackList`.
18157 * @param {AudioTrack} track
18158 * The AudioTrack to remove from the list
18160 * @fires Track#removetrack
18164 AudioTrackList.prototype.removeTrack = function removeTrack(track) {
18165 _TrackList.prototype.removeTrack_.call(this, track);
18168 return AudioTrackList;
18169 }(_trackList2['default']);
18171 exports['default'] = AudioTrackList;
18173 },{"74":74,"78":78,"94":94}],64:[function(_dereq_,module,exports){
18176 exports.__esModule = true;
18178 var _trackEnums = _dereq_(73);
18180 var _track = _dereq_(75);
18182 var _track2 = _interopRequireDefault(_track);
18184 var _mergeOptions = _dereq_(87);
18186 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
18188 var _browser = _dereq_(78);
18190 var browser = _interopRequireWildcard(_browser);
18192 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; } }
18194 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18196 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18198 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; }
18200 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; }
18203 * A representation of a single `AudioTrack`. If it is part of an {@link AudioTrackList}
18204 * only one `AudioTrack` in the list will be enabled at a time.
18206 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack}
18209 var AudioTrack = function (_Track) {
18210 _inherits(AudioTrack, _Track);
18213 * Create an instance of this class.
18215 * @param {Object} [options={}]
18216 * Object of option names and values
18218 * @param {AudioTrack~Kind} [options.kind='']
18219 * A valid audio track kind
18221 * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
18222 * A unique id for this AudioTrack.
18224 * @param {string} [options.label='']
18225 * The menu label for this track.
18227 * @param {string} [options.language='']
18228 * A valid two character language code.
18230 * @param {boolean} [options.enabled]
18231 * If this track is the one that is currently playing. If this track is part of
18232 * an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled.
18234 function AudioTrack() {
18237 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
18239 _classCallCheck(this, AudioTrack);
18241 var settings = (0, _mergeOptions2['default'])(options, {
18242 kind: _trackEnums.AudioTrackKind[options.kind] || ''
18244 // on IE8 this will be a document element
18245 // for every other browser this will be a normal object
18246 var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
18247 var enabled = false;
18249 if (browser.IS_IE8) {
18250 for (var prop in AudioTrack.prototype) {
18251 if (prop !== 'constructor') {
18252 track[prop] = AudioTrack.prototype[prop];
18257 * @member {boolean} enabled
18258 * If this `AudioTrack` is enabled or not. When setting this will
18259 * fire {@link AudioTrack#enabledchange} if the state of enabled is changed.
18261 * @fires VideoTrack#selectedchange
18263 Object.defineProperty(track, 'enabled', {
18264 get: function get() {
18267 set: function set(newEnabled) {
18268 // an invalid or unchanged value
18269 if (typeof newEnabled !== 'boolean' || newEnabled === enabled) {
18272 enabled = newEnabled;
18275 * An event that fires when enabled changes on this track. This allows
18276 * the AudioTrackList that holds this track to act accordingly.
18278 * > Note: This is not part of the spec! Native tracks will do
18279 * this internally without an event.
18281 * @event AudioTrack#enabledchange
18282 * @type {EventTarget~Event}
18284 this.trigger('enabledchange');
18288 // if the user sets this track to selected then
18289 // set selected to that true value otherwise
18290 // we keep it false
18291 if (settings.enabled) {
18292 track.enabled = settings.enabled;
18294 track.loaded_ = true;
18296 return _ret = track, _possibleConstructorReturn(_this, _ret);
18300 }(_track2['default']);
18302 exports['default'] = AudioTrack;
18304 },{"73":73,"75":75,"78":78,"87":87}],65:[function(_dereq_,module,exports){
18307 exports.__esModule = true;
18309 var _browser = _dereq_(78);
18311 var browser = _interopRequireWildcard(_browser);
18313 var _document = _dereq_(94);
18315 var _document2 = _interopRequireDefault(_document);
18317 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18319 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; } }
18321 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
18322 * @file html-track-element-list.js
18326 * The current list of {@link HtmlTrackElement}s.
18328 var HtmlTrackElementList = function () {
18331 * Create an instance of this class.
18333 * @param {HtmlTrackElement[]} [tracks=[]]
18334 * A list of `HtmlTrackElement` to instantiate the list with.
18336 function HtmlTrackElementList() {
18337 var trackElements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
18339 _classCallCheck(this, HtmlTrackElementList);
18341 var list = this; // eslint-disable-line
18343 if (browser.IS_IE8) {
18344 list = _document2['default'].createElement('custom');
18346 for (var prop in HtmlTrackElementList.prototype) {
18347 if (prop !== 'constructor') {
18348 list[prop] = HtmlTrackElementList.prototype[prop];
18353 list.trackElements_ = [];
18356 * @member {number} length
18357 * The current number of `Track`s in the this Trackist.
18359 Object.defineProperty(list, 'length', {
18360 get: function get() {
18361 return this.trackElements_.length;
18365 for (var i = 0, length = trackElements.length; i < length; i++) {
18366 list.addTrackElement_(trackElements[i]);
18369 if (browser.IS_IE8) {
18375 * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList`
18377 * @param {HtmlTrackElement} trackElement
18378 * The track element to add to the list.
18384 HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) {
18385 var index = this.trackElements_.length;
18387 if (!('' + index in this)) {
18388 Object.defineProperty(this, index, {
18389 get: function get() {
18390 return this.trackElements_[index];
18395 // Do not add duplicate elements
18396 if (this.trackElements_.indexOf(trackElement) === -1) {
18397 this.trackElements_.push(trackElement);
18402 * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an
18403 * {@link TextTrack}.
18405 * @param {TextTrack} track
18406 * The track associated with a track element.
18408 * @return {HtmlTrackElement|undefined}
18409 * The track element that was found or undefined.
18415 HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) {
18416 var trackElement_ = void 0;
18418 for (var i = 0, length = this.trackElements_.length; i < length; i++) {
18419 if (track === this.trackElements_[i].track) {
18420 trackElement_ = this.trackElements_[i];
18426 return trackElement_;
18430 * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList`
18432 * @param {HtmlTrackElement} trackElement
18433 * The track element to remove from the list.
18439 HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) {
18440 for (var i = 0, length = this.trackElements_.length; i < length; i++) {
18441 if (trackElement === this.trackElements_[i]) {
18442 this.trackElements_.splice(i, 1);
18449 return HtmlTrackElementList;
18452 exports['default'] = HtmlTrackElementList;
18454 },{"78":78,"94":94}],66:[function(_dereq_,module,exports){
18457 exports.__esModule = true;
18459 var _browser = _dereq_(78);
18461 var browser = _interopRequireWildcard(_browser);
18463 var _document = _dereq_(94);
18465 var _document2 = _interopRequireDefault(_document);
18467 var _eventTarget = _dereq_(42);
18469 var _eventTarget2 = _interopRequireDefault(_eventTarget);
18471 var _textTrack = _dereq_(72);
18473 var _textTrack2 = _interopRequireDefault(_textTrack);
18475 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18477 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; } }
18479 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18481 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; }
18483 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; } /**
18484 * @file html-track-element.js
18488 * @typedef {HTMLTrackElement~ReadyState}
18497 * A single track represented in the DOM.
18499 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement}
18500 * @extends EventTarget
18503 var HTMLTrackElement = function (_EventTarget) {
18504 _inherits(HTMLTrackElement, _EventTarget);
18507 * Create an instance of this class.
18509 * @param {Object} options={}
18510 * Object of option names and values
18512 * @param {Tech} options.tech
18513 * A reference to the tech that owns this HTMLTrackElement.
18515 * @param {TextTrack~Kind} [options.kind='subtitles']
18516 * A valid text track kind.
18518 * @param {TextTrack~Mode} [options.mode='disabled']
18519 * A valid text track mode.
18521 * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
18522 * A unique id for this TextTrack.
18524 * @param {string} [options.label='']
18525 * The menu label for this track.
18527 * @param {string} [options.language='']
18528 * A valid two character language code.
18530 * @param {string} [options.srclang='']
18531 * A valid two character language code. An alternative, but deprioritized
18532 * vesion of `options.language`
18534 * @param {string} [options.src]
18535 * A url to TextTrack cues.
18537 * @param {boolean} [options.default]
18538 * If this track should default to on or off.
18540 function HTMLTrackElement() {
18541 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
18543 _classCallCheck(this, HTMLTrackElement);
18545 var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
18547 var readyState = void 0;
18548 var trackElement = _this; // eslint-disable-line
18550 if (browser.IS_IE8) {
18551 trackElement = _document2['default'].createElement('custom');
18553 for (var prop in HTMLTrackElement.prototype) {
18554 if (prop !== 'constructor') {
18555 trackElement[prop] = HTMLTrackElement.prototype[prop];
18560 var track = new _textTrack2['default'](options);
18562 trackElement.kind = track.kind;
18563 trackElement.src = track.src;
18564 trackElement.srclang = track.language;
18565 trackElement.label = track.label;
18566 trackElement['default'] = track['default'];
18569 * @member {HTMLTrackElement~ReadyState} readyState
18570 * The current ready state of the track element.
18572 Object.defineProperty(trackElement, 'readyState', {
18573 get: function get() {
18579 * @member {TextTrack} track
18580 * The underlying TextTrack object.
18582 Object.defineProperty(trackElement, 'track', {
18583 get: function get() {
18591 * @listens TextTrack#loadeddata
18592 * @fires HTMLTrackElement#load
18594 track.addEventListener('loadeddata', function () {
18595 readyState = LOADED;
18597 trackElement.trigger({
18599 target: trackElement
18603 if (browser.IS_IE8) {
18606 return _ret = trackElement, _possibleConstructorReturn(_this, _ret);
18611 return HTMLTrackElement;
18612 }(_eventTarget2['default']);
18614 HTMLTrackElement.prototype.allowedEvents_ = {
18618 HTMLTrackElement.NONE = NONE;
18619 HTMLTrackElement.LOADING = LOADING;
18620 HTMLTrackElement.LOADED = LOADED;
18621 HTMLTrackElement.ERROR = ERROR;
18623 exports['default'] = HTMLTrackElement;
18625 },{"42":42,"72":72,"78":78,"94":94}],67:[function(_dereq_,module,exports){
18628 exports.__esModule = true;
18630 var _browser = _dereq_(78);
18632 var browser = _interopRequireWildcard(_browser);
18634 var _document = _dereq_(94);
18636 var _document2 = _interopRequireDefault(_document);
18638 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18640 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; } }
18642 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
18643 * @file text-track-cue-list.js
18648 * @typedef {Object} TextTrackCue
18650 * @property {string} id
18651 * The unique id for this text track cue
18653 * @property {number} startTime
18654 * The start time for this text track cue
18656 * @property {number} endTime
18657 * The end time for this text track cue
18659 * @property {boolean} pauseOnExit
18660 * Pause when the end time is reached if true.
18662 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcue}
18666 * A List of TextTrackCues.
18668 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist}
18670 var TextTrackCueList = function () {
18673 * Create an instance of this class..
18675 * @param {Array} cues
18676 * A list of cues to be initialized with
18678 function TextTrackCueList(cues) {
18679 _classCallCheck(this, TextTrackCueList);
18681 var list = this; // eslint-disable-line
18683 if (browser.IS_IE8) {
18684 list = _document2['default'].createElement('custom');
18686 for (var prop in TextTrackCueList.prototype) {
18687 if (prop !== 'constructor') {
18688 list[prop] = TextTrackCueList.prototype[prop];
18693 TextTrackCueList.prototype.setCues_.call(list, cues);
18696 * @member {number} length
18697 * The current number of `TextTrackCue`s in the TextTrackCueList.
18699 Object.defineProperty(list, 'length', {
18700 get: function get() {
18701 return this.length_;
18705 if (browser.IS_IE8) {
18711 * A setter for cues in this list. Creates getters
18712 * an an index for the cues.
18714 * @param {Array} cues
18715 * An array of cues to set
18721 TextTrackCueList.prototype.setCues_ = function setCues_(cues) {
18722 var oldLength = this.length || 0;
18724 var l = cues.length;
18727 this.length_ = cues.length;
18729 var defineProp = function defineProp(index) {
18730 if (!('' + index in this)) {
18731 Object.defineProperty(this, '' + index, {
18732 get: function get() {
18733 return this.cues_[index];
18739 if (oldLength < l) {
18742 for (; i < l; i++) {
18743 defineProp.call(this, i);
18749 * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id.
18751 * @param {string} id
18752 * The id of the cue that should be searched for.
18754 * @return {TextTrackCue|null}
18755 * A single cue or null if none was found.
18759 TextTrackCueList.prototype.getCueById = function getCueById(id) {
18762 for (var i = 0, l = this.length; i < l; i++) {
18765 if (cue.id === id) {
18774 return TextTrackCueList;
18777 exports['default'] = TextTrackCueList;
18779 },{"78":78,"94":94}],68:[function(_dereq_,module,exports){
18782 exports.__esModule = true;
18784 var _component = _dereq_(5);
18786 var _component2 = _interopRequireDefault(_component);
18788 var _fn = _dereq_(83);
18790 var Fn = _interopRequireWildcard(_fn);
18792 var _window = _dereq_(95);
18794 var _window2 = _interopRequireDefault(_window);
18796 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; } }
18798 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
18800 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18802 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; }
18804 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; } /**
18805 * @file text-track-display.js
18809 var darkGray = '#222';
18810 var lightGray = '#ccc';
18812 monospace: 'monospace',
18813 sansSerif: 'sans-serif',
18815 monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace',
18816 monospaceSerif: '"Courier New", monospace',
18817 proportionalSansSerif: 'sans-serif',
18818 proportionalSerif: 'serif',
18819 casual: '"Comic Sans MS", Impact, fantasy',
18820 script: '"Monotype Corsiva", cursive',
18821 smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif'
18825 * Construct an rgba color from a given hex color code.
18827 * @param {number} color
18828 * Hex number for color, like #f0e.
18830 * @param {number} opacity
18831 * Value for opacity, 0.0 - 1.0.
18834 * The rgba color that was created, like 'rgba(255, 0, 0, 0.3)'.
18838 function constructColor(color, opacity) {
18840 // color looks like "#f0e"
18841 parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')';
18845 * Try to update the style of a DOM element. Some style changes will throw an error,
18846 * particularly in IE8. Those should be noops.
18848 * @param {Element} el
18849 * The DOM element to be styled.
18851 * @param {string} style
18852 * The CSS property on the element that should be styled.
18854 * @param {string} rule
18855 * The style rule that should be applied to the property.
18857 function tryUpdateStyle(el, style, rule) {
18859 el.style[style] = rule;
18862 // Satisfies linter.
18868 * The component for displaying text track cues.
18870 * @extends Component
18873 var TextTrackDisplay = function (_Component) {
18874 _inherits(TextTrackDisplay, _Component);
18877 * Creates an instance of this class.
18879 * @param {Player} player
18880 * The `Player` that this class should be attached to.
18882 * @param {Object} [options]
18883 * The key/value store of player options.
18885 * @param {Component~ReadyCallback} [ready]
18886 * The function to call when `TextTrackDisplay` is ready.
18888 function TextTrackDisplay(player, options, ready) {
18889 _classCallCheck(this, TextTrackDisplay);
18891 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready));
18893 player.on('loadstart', Fn.bind(_this, _this.toggleDisplay));
18894 player.on('texttrackchange', Fn.bind(_this, _this.updateDisplay));
18896 // This used to be called during player init, but was causing an error
18897 // if a track should show by default and the display hadn't loaded yet.
18898 // Should probably be moved to an external track loader when we support
18899 // tracks that don't need a display.
18900 player.ready(Fn.bind(_this, function () {
18901 if (player.tech_ && player.tech_.featuresNativeTextTracks) {
18906 player.on('fullscreenchange', Fn.bind(this, this.updateDisplay));
18908 var tracks = this.options_.playerOptions.tracks || [];
18910 for (var i = 0; i < tracks.length; i++) {
18911 this.player_.addRemoteTextTrack(tracks[i], true);
18914 var modes = { captions: 1, subtitles: 1 };
18915 var trackList = this.player_.textTracks();
18916 var firstDesc = void 0;
18917 var firstCaptions = void 0;
18920 for (var _i = 0; _i < trackList.length; _i++) {
18921 var track = trackList[_i];
18923 if (track['default']) {
18924 if (track.kind === 'descriptions' && !firstDesc) {
18926 } else if (track.kind in modes && !firstCaptions) {
18927 firstCaptions = track;
18932 // We want to show the first default track but captions and subtitles
18933 // take precedence over descriptions.
18934 // So, display the first default captions or subtitles track
18935 // and otherwise the first default descriptions track.
18936 if (firstCaptions) {
18937 firstCaptions.mode = 'showing';
18938 } else if (firstDesc) {
18939 firstDesc.mode = 'showing';
18947 * Turn display of {@link TextTrack}'s from the current state into the other state.
18948 * There are only two states:
18952 * @listens Player#loadstart
18956 TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() {
18957 if (this.player_.tech_ && this.player_.tech_.featuresNativeTextTracks) {
18965 * Create the {@link Component}'s DOM element.
18967 * @return {Element}
18968 * The element that was created.
18972 TextTrackDisplay.prototype.createEl = function createEl() {
18973 return _Component.prototype.createEl.call(this, 'div', {
18974 className: 'vjs-text-track-display'
18976 'aria-live': 'off',
18977 'aria-atomic': 'true'
18982 * Clear all displayed {@link TextTrack}s.
18986 TextTrackDisplay.prototype.clearDisplay = function clearDisplay() {
18987 if (typeof _window2['default'].WebVTT === 'function') {
18988 _window2['default'].WebVTT.processCues(_window2['default'], [], this.el_);
18993 * Update the displayed TextTrack when a either a {@link Player#texttrackchange} or
18994 * a {@link Player#fullscreenchange} is fired.
18996 * @listens Player#texttrackchange
18997 * @listens Player#fullscreenchange
19001 TextTrackDisplay.prototype.updateDisplay = function updateDisplay() {
19002 var tracks = this.player_.textTracks();
19004 this.clearDisplay();
19010 // Track display prioritization model: if multiple tracks are 'showing',
19011 // display the first 'subtitles' or 'captions' track which is 'showing',
19012 // otherwise display the first 'descriptions' track which is 'showing'
19014 var descriptionsTrack = null;
19015 var captionsSubtitlesTrack = null;
19017 var i = tracks.length;
19020 var track = tracks[i];
19022 if (track.mode === 'showing') {
19023 if (track.kind === 'descriptions') {
19024 descriptionsTrack = track;
19026 captionsSubtitlesTrack = track;
19031 if (captionsSubtitlesTrack) {
19032 if (this.getAttribute('aria-live') !== 'off') {
19033 this.setAttribute('aria-live', 'off');
19035 this.updateForTrack(captionsSubtitlesTrack);
19036 } else if (descriptionsTrack) {
19037 if (this.getAttribute('aria-live') !== 'assertive') {
19038 this.setAttribute('aria-live', 'assertive');
19040 this.updateForTrack(descriptionsTrack);
19045 * Add an {@link Texttrack} to to the {@link Tech}s {@link TextTrackList}.
19047 * @param {TextTrack} track
19048 * Text track object to be added to the list.
19052 TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) {
19053 if (typeof _window2['default'].WebVTT !== 'function' || !track.activeCues) {
19057 var overrides = this.player_.textTrackSettings.getValues();
19060 for (var _i2 = 0; _i2 < track.activeCues.length; _i2++) {
19061 cues.push(track.activeCues[_i2]);
19064 _window2['default'].WebVTT.processCues(_window2['default'], cues, this.el_);
19066 var i = cues.length;
19075 var cueDiv = cue.displayState;
19077 if (overrides.color) {
19078 cueDiv.firstChild.style.color = overrides.color;
19080 if (overrides.textOpacity) {
19081 tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity));
19083 if (overrides.backgroundColor) {
19084 cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor;
19086 if (overrides.backgroundOpacity) {
19087 tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity));
19089 if (overrides.windowColor) {
19090 if (overrides.windowOpacity) {
19091 tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity));
19093 cueDiv.style.backgroundColor = overrides.windowColor;
19096 if (overrides.edgeStyle) {
19097 if (overrides.edgeStyle === 'dropshadow') {
19098 cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray;
19099 } else if (overrides.edgeStyle === 'raised') {
19100 cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray;
19101 } else if (overrides.edgeStyle === 'depressed') {
19102 cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray;
19103 } else if (overrides.edgeStyle === 'uniform') {
19104 cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray;
19107 if (overrides.fontPercent && overrides.fontPercent !== 1) {
19108 var fontSize = _window2['default'].parseFloat(cueDiv.style.fontSize);
19110 cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px';
19111 cueDiv.style.height = 'auto';
19112 cueDiv.style.top = 'auto';
19113 cueDiv.style.bottom = '2px';
19115 if (overrides.fontFamily && overrides.fontFamily !== 'default') {
19116 if (overrides.fontFamily === 'small-caps') {
19117 cueDiv.firstChild.style.fontVariant = 'small-caps';
19119 cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily];
19125 return TextTrackDisplay;
19126 }(_component2['default']);
19128 _component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay);
19129 exports['default'] = TextTrackDisplay;
19131 },{"5":5,"83":83,"95":95}],69:[function(_dereq_,module,exports){
19134 exports.__esModule = true;
19136 * @file text-track-list-converter.js Utilities for capturing text track state and
19137 * re-creating tracks based on a capture.
19139 * @module text-track-list-converter
19143 * Examine a single {@link TextTrack} and return a JSON-compatible javascript object that
19144 * represents the {@link TextTrack}'s state.
19146 * @param {TextTrack} track
19147 * The text track to query.
19150 * A serializable javascript representation of the TextTrack.
19153 var trackToJson_ = function trackToJson_(track) {
19154 var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) {
19157 acc[prop] = track[prop];
19162 cues: track.cues && Array.prototype.map.call(track.cues, function (cue) {
19164 startTime: cue.startTime,
19165 endTime: cue.endTime,
19176 * Examine a {@link Tech} and return a JSON-compatible javascript array that represents the
19177 * state of all {@link TextTrack}s currently configured. The return array is compatible with
19178 * {@link text-track-list-converter:jsonToTextTracks}.
19180 * @param {Tech} tech
19181 * The tech object to query
19184 * A serializable javascript representation of the {@link Tech}s
19185 * {@link TextTrackList}.
19187 var textTracksToJson = function textTracksToJson(tech) {
19189 var trackEls = tech.$$('track');
19191 var trackObjs = Array.prototype.map.call(trackEls, function (t) {
19194 var tracks = Array.prototype.map.call(trackEls, function (trackEl) {
19195 var json = trackToJson_(trackEl.track);
19198 json.src = trackEl.src;
19203 return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) {
19204 return trackObjs.indexOf(track) === -1;
19205 }).map(trackToJson_));
19209 * Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript
19210 * object {@link TextTrack} representations.
19212 * @param {Array} json
19213 * An array of `TextTrack` representation objects, like those that would be
19214 * produced by `textTracksToJson`.
19216 * @param {Tech} tech
19217 * The `Tech` to create the `TextTrack`s on.
19219 var jsonToTextTracks = function jsonToTextTracks(json, tech) {
19220 json.forEach(function (track) {
19221 var addedTrack = tech.addRemoteTextTrack(track).track;
19223 if (!track.src && track.cues) {
19224 track.cues.forEach(function (cue) {
19225 return addedTrack.addCue(cue);
19230 return tech.textTracks();
19233 exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ };
19235 },{}],70:[function(_dereq_,module,exports){
19238 exports.__esModule = true;
19240 var _trackList = _dereq_(74);
19242 var _trackList2 = _interopRequireDefault(_trackList);
19244 var _fn = _dereq_(83);
19246 var Fn = _interopRequireWildcard(_fn);
19248 var _browser = _dereq_(78);
19250 var browser = _interopRequireWildcard(_browser);
19252 var _document = _dereq_(94);
19254 var _document2 = _interopRequireDefault(_document);
19256 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; } }
19258 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19260 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19262 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; }
19264 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; } /**
19265 * @file text-track-list.js
19270 * The current list of {@link TextTrack} for a media file.
19272 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist}
19273 * @extends TrackList
19275 var TextTrackList = function (_TrackList) {
19276 _inherits(TextTrackList, _TrackList);
19279 * Create an instance of this class.
19281 * @param {TextTrack[]} [tracks=[]]
19282 * A list of `TextTrack` to instantiate the list with.
19284 function TextTrackList() {
19287 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
19289 _classCallCheck(this, TextTrackList);
19293 // IE8 forces us to implement inheritance ourselves
19294 // as it does not support Object.defineProperty properly
19295 if (browser.IS_IE8) {
19296 list = _document2['default'].createElement('custom');
19297 for (var prop in _trackList2['default'].prototype) {
19298 if (prop !== 'constructor') {
19299 list[prop] = _trackList2['default'].prototype[prop];
19302 for (var _prop in TextTrackList.prototype) {
19303 if (_prop !== 'constructor') {
19304 list[_prop] = TextTrackList.prototype[_prop];
19309 list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
19310 return _ret = list, _possibleConstructorReturn(_this, _ret);
19314 * Add a {@link TextTrack} to the `TextTrackList`
19316 * @param {TextTrack} track
19317 * The text track to add to the list.
19319 * @fires TrackList#addtrack
19324 TextTrackList.prototype.addTrack_ = function addTrack_(track) {
19325 _TrackList.prototype.addTrack_.call(this, track);
19328 * @listens TextTrack#modechange
19329 * @fires TrackList#change
19331 track.addEventListener('modechange', Fn.bind(this, function () {
19332 this.trigger('change');
19336 return TextTrackList;
19337 }(_trackList2['default']);
19339 exports['default'] = TextTrackList;
19341 },{"74":74,"78":78,"83":83,"94":94}],71:[function(_dereq_,module,exports){
19344 exports.__esModule = true;
19346 var _window = _dereq_(95);
19348 var _window2 = _interopRequireDefault(_window);
19350 var _component = _dereq_(5);
19352 var _component2 = _interopRequireDefault(_component);
19354 var _dom = _dereq_(81);
19356 var _fn = _dereq_(83);
19358 var Fn = _interopRequireWildcard(_fn);
19360 var _obj = _dereq_(88);
19362 var Obj = _interopRequireWildcard(_obj);
19364 var _log = _dereq_(86);
19366 var _log2 = _interopRequireDefault(_log);
19368 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; } }
19370 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19372 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19374 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; }
19376 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; } /**
19377 * @file text-track-settings.js
19381 var LOCAL_STORAGE_KEY = 'vjs-text-track-settings';
19383 var COLOR_BLACK = ['#000', 'Black'];
19384 var COLOR_BLUE = ['#00F', 'Blue'];
19385 var COLOR_CYAN = ['#0FF', 'Cyan'];
19386 var COLOR_GREEN = ['#0F0', 'Green'];
19387 var COLOR_MAGENTA = ['#F0F', 'Magenta'];
19388 var COLOR_RED = ['#F00', 'Red'];
19389 var COLOR_WHITE = ['#FFF', 'White'];
19390 var COLOR_YELLOW = ['#FF0', 'Yellow'];
19392 var OPACITY_OPAQUE = ['1', 'Opaque'];
19393 var OPACITY_SEMI = ['0.5', 'Semi-Transparent'];
19394 var OPACITY_TRANS = ['0', 'Transparent'];
19396 // Configuration for the various <select> elements in the DOM of this component.
19398 // Possible keys include:
19401 // The default option index. Only needs to be provided if not zero.
19403 // A function which is used to parse the value from the selected option in
19404 // a customized way.
19406 // The selector used to find the associated <select> element.
19407 var selectConfigs = {
19409 selector: '.vjs-bg-color > select',
19410 id: 'captions-background-color-%s',
19412 options: [COLOR_BLACK, COLOR_WHITE, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
19415 backgroundOpacity: {
19416 selector: '.vjs-bg-opacity > select',
19417 id: 'captions-background-opacity-%s',
19418 label: 'Transparency',
19419 options: [OPACITY_OPAQUE, OPACITY_SEMI, OPACITY_TRANS]
19423 selector: '.vjs-fg-color > select',
19424 id: 'captions-foreground-color-%s',
19426 options: [COLOR_WHITE, COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
19430 selector: '.vjs-edge-style > select',
19432 label: 'Text Edge Style',
19433 options: [['none', 'None'], ['raised', 'Raised'], ['depressed', 'Depressed'], ['uniform', 'Uniform'], ['dropshadow', 'Dropshadow']]
19437 selector: '.vjs-font-family > select',
19438 id: 'captions-font-family-%s',
19439 label: 'Font Family',
19440 options: [['proportionalSansSerif', 'Proportional Sans-Serif'], ['monospaceSansSerif', 'Monospace Sans-Serif'], ['proportionalSerif', 'Proportional Serif'], ['monospaceSerif', 'Monospace Serif'], ['casual', 'Casual'], ['script', 'Script'], ['small-caps', 'Small Caps']]
19444 selector: '.vjs-font-percent > select',
19445 id: 'captions-font-size-%s',
19446 label: 'Font Size',
19447 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%']],
19449 parser: function parser(v) {
19450 return v === '1.00' ? null : Number(v);
19455 selector: '.vjs-text-opacity > select',
19456 id: 'captions-foreground-opacity-%s',
19457 label: 'Transparency',
19458 options: [OPACITY_OPAQUE, OPACITY_SEMI]
19461 // Options for this object are defined below.
19463 selector: '.vjs-window-color > select',
19464 id: 'captions-window-color-%s',
19468 // Options for this object are defined below.
19470 selector: '.vjs-window-opacity > select',
19471 id: 'captions-window-opacity-%s',
19472 label: 'Transparency',
19473 options: [OPACITY_TRANS, OPACITY_SEMI, OPACITY_OPAQUE]
19477 selectConfigs.windowColor.options = selectConfigs.backgroundColor.options;
19480 * Get the actual value of an option.
19482 * @param {string} value
19485 * @param {Function} [parser]
19486 * Optional function to adjust the value.
19489 * - Will be `undefined` if no value exists
19490 * - Will be `undefined` if the given value is "none".
19491 * - Will be the actual value otherwise.
19495 function parseOptionValue(value, parser) {
19497 value = parser(value);
19500 if (value && value !== 'none') {
19506 * Gets the value of the selected <option> element within a <select> element.
19508 * @param {Element} el
19509 * the element to look in
19511 * @param {Function} [parser]
19512 * Optional function to adjust the value.
19515 * - Will be `undefined` if no value exists
19516 * - Will be `undefined` if the given value is "none".
19517 * - Will be the actual value otherwise.
19521 function getSelectedOptionValue(el, parser) {
19522 var value = el.options[el.options.selectedIndex].value;
19524 return parseOptionValue(value, parser);
19528 * Sets the selected <option> element within a <select> element based on a
19531 * @param {Element} el
19532 * The element to look in.
19534 * @param {string} value
19535 * the property to look on.
19537 * @param {Function} [parser]
19538 * Optional function to adjust the value before comparing.
19542 function setSelectedOption(el, value, parser) {
19547 for (var i = 0; i < el.options.length; i++) {
19548 if (parseOptionValue(el.options[i].value, parser) === value) {
19549 el.selectedIndex = i;
19556 * Manipulate Text Tracks settings.
19558 * @extends Component
19561 var TextTrackSettings = function (_Component) {
19562 _inherits(TextTrackSettings, _Component);
19565 * Creates an instance of this class.
19567 * @param {Player} player
19568 * The `Player` that this class should be attached to.
19570 * @param {Object} [options]
19571 * The key/value store of player options.
19573 function TextTrackSettings(player, options) {
19574 _classCallCheck(this, TextTrackSettings);
19576 var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
19578 _this.setDefaults();
19581 _this.updateDisplay = Fn.bind(_this, _this.updateDisplay);
19583 // Grab `persistTextTrackSettings` from the player options if not passed in child options
19584 if (options.persistTextTrackSettings === undefined) {
19585 _this.options_.persistTextTrackSettings = _this.options_.playerOptions.persistTextTrackSettings;
19588 _this.on(_this.$('.vjs-done-button'), 'click', function () {
19589 _this.saveSettings();
19593 _this.on(_this.$('.vjs-default-button'), 'click', function () {
19594 _this.setDefaults();
19595 _this.updateDisplay();
19598 Obj.each(selectConfigs, function (config) {
19599 _this.on(_this.$(config.selector), 'change', _this.updateDisplay);
19602 if (_this.options_.persistTextTrackSettings) {
19603 _this.restoreSettings();
19609 * Create a <select> element with configured options.
19611 * @param {string} key
19612 * Configuration key to use during creation.
19614 * @return {Element}
19615 * The DOM element that gets created.
19620 TextTrackSettings.prototype.createElSelect_ = function createElSelect_(key) {
19623 var config = selectConfigs[key];
19624 var id = config.id.replace('%s', this.id_);
19626 return [(0, _dom.createEl)('label', {
19627 className: 'vjs-label',
19628 textContent: config.label
19631 }), (0, _dom.createEl)('select', { id: id }, undefined, config.options.map(function (o) {
19632 return (0, _dom.createEl)('option', {
19633 textContent: _this2.localize(o[1]),
19640 * Create foreground color element for the component
19642 * @return {Element}
19643 * The element that was created.
19649 TextTrackSettings.prototype.createElFgColor_ = function createElFgColor_() {
19650 var legend = (0, _dom.createEl)('legend', {
19651 textContent: this.localize('Text')
19654 var select = this.createElSelect_('color');
19656 var opacity = (0, _dom.createEl)('span', {
19657 className: 'vjs-text-opacity vjs-opacity'
19658 }, undefined, this.createElSelect_('textOpacity'));
19660 return (0, _dom.createEl)('fieldset', {
19661 className: 'vjs-fg-color vjs-tracksetting'
19662 }, undefined, [legend].concat(select, opacity));
19666 * Create background color element for the component
19668 * @return {Element}
19669 * The element that was created
19675 TextTrackSettings.prototype.createElBgColor_ = function createElBgColor_() {
19676 var legend = (0, _dom.createEl)('legend', {
19677 textContent: this.localize('Background')
19680 var select = this.createElSelect_('backgroundColor');
19682 var opacity = (0, _dom.createEl)('span', {
19683 className: 'vjs-bg-opacity vjs-opacity'
19684 }, undefined, this.createElSelect_('backgroundOpacity'));
19686 return (0, _dom.createEl)('fieldset', {
19687 className: 'vjs-bg-color vjs-tracksetting'
19688 }, undefined, [legend].concat(select, opacity));
19692 * Create window color element for the component
19694 * @return {Element}
19695 * The element that was created
19701 TextTrackSettings.prototype.createElWinColor_ = function createElWinColor_() {
19702 var legend = (0, _dom.createEl)('legend', {
19703 textContent: this.localize('Window')
19706 var select = this.createElSelect_('windowColor');
19708 var opacity = (0, _dom.createEl)('span', {
19709 className: 'vjs-window-opacity vjs-opacity'
19710 }, undefined, this.createElSelect_('windowOpacity'));
19712 return (0, _dom.createEl)('fieldset', {
19713 className: 'vjs-window-color vjs-tracksetting'
19714 }, undefined, [legend].concat(select, opacity));
19718 * Create color elements for the component
19720 * @return {Element}
19721 * The element that was created
19727 TextTrackSettings.prototype.createElColors_ = function createElColors_() {
19728 return (0, _dom.createEl)('div', {
19729 className: 'vjs-tracksettings-colors'
19730 }, undefined, [this.createElFgColor_(), this.createElBgColor_(), this.createElWinColor_()]);
19734 * Create font elements for the component
19736 * @return {Element}
19737 * The element that was created.
19743 TextTrackSettings.prototype.createElFont_ = function createElFont_() {
19744 var fontPercent = (0, _dom.createEl)('div', {
19745 className: 'vjs-font-percent vjs-tracksetting'
19746 }, undefined, this.createElSelect_('fontPercent'));
19748 var edgeStyle = (0, _dom.createEl)('div', {
19749 className: 'vjs-edge-style vjs-tracksetting'
19750 }, undefined, this.createElSelect_('edgeStyle'));
19752 var fontFamily = (0, _dom.createEl)('div', {
19753 className: 'vjs-font-family vjs-tracksetting'
19754 }, undefined, this.createElSelect_('fontFamily'));
19756 return (0, _dom.createEl)('div', {
19757 className: 'vjs-tracksettings-font'
19758 }, undefined, [fontPercent, edgeStyle, fontFamily]);
19762 * Create controls for the component
19764 * @return {Element}
19765 * The element that was created.
19771 TextTrackSettings.prototype.createElControls_ = function createElControls_() {
19772 var defaultsButton = (0, _dom.createEl)('button', {
19773 className: 'vjs-default-button',
19774 textContent: this.localize('Defaults')
19777 var doneButton = (0, _dom.createEl)('button', {
19778 className: 'vjs-done-button',
19779 textContent: 'Done'
19782 return (0, _dom.createEl)('div', {
19783 className: 'vjs-tracksettings-controls'
19784 }, undefined, [defaultsButton, doneButton]);
19788 * Create the component's DOM element
19790 * @return {Element}
19791 * The element that was created.
19795 TextTrackSettings.prototype.createEl = function createEl() {
19796 var settings = (0, _dom.createEl)('div', {
19797 className: 'vjs-tracksettings'
19798 }, undefined, [this.createElColors_(), this.createElFont_(), this.createElControls_()]);
19800 var heading = (0, _dom.createEl)('div', {
19801 className: 'vjs-control-text',
19802 id: 'TTsettingsDialogLabel-' + this.id_,
19803 textContent: 'Caption Settings Dialog'
19809 var description = (0, _dom.createEl)('div', {
19810 className: 'vjs-control-text',
19811 id: 'TTsettingsDialogDescription-' + this.id_,
19812 textContent: 'Beginning of dialog window. Escape will cancel and close the window.'
19815 var doc = (0, _dom.createEl)('div', undefined, {
19817 }, [heading, description, settings]);
19819 return (0, _dom.createEl)('div', {
19820 className: 'vjs-caption-settings vjs-modal-overlay',
19824 'aria-labelledby': heading.id,
19825 'aria-describedby': description.id
19830 * Gets an object of text track settings (or null).
19833 * An object with config values parsed from the DOM or localStorage.
19837 TextTrackSettings.prototype.getValues = function getValues() {
19840 return Obj.reduce(selectConfigs, function (accum, config, key) {
19841 var value = getSelectedOptionValue(_this3.$(config.selector), config.parser);
19843 if (value !== undefined) {
19844 accum[key] = value;
19852 * Sets text track settings from an object of values.
19854 * @param {Object} values
19855 * An object with config values parsed from the DOM or localStorage.
19859 TextTrackSettings.prototype.setValues = function setValues(values) {
19862 Obj.each(selectConfigs, function (config, key) {
19863 setSelectedOption(_this4.$(config.selector), values[key], config.parser);
19868 * Sets all <select> elements to their default values.
19872 TextTrackSettings.prototype.setDefaults = function setDefaults() {
19875 Obj.each(selectConfigs, function (config) {
19876 var index = config.hasOwnProperty('default') ? config['default'] : 0;
19878 _this5.$(config.selector).selectedIndex = index;
19883 * Restore texttrack settings from localStorage
19887 TextTrackSettings.prototype.restoreSettings = function restoreSettings() {
19888 var values = void 0;
19891 values = JSON.parse(_window2['default'].localStorage.getItem(LOCAL_STORAGE_KEY));
19893 _log2['default'].warn(err);
19897 this.setValues(values);
19902 * Save text track settings to localStorage
19906 TextTrackSettings.prototype.saveSettings = function saveSettings() {
19907 if (!this.options_.persistTextTrackSettings) {
19911 var values = this.getValues();
19914 if (Object.keys(values).length) {
19915 _window2['default'].localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(values));
19917 _window2['default'].localStorage.removeItem(LOCAL_STORAGE_KEY);
19920 _log2['default'].warn(err);
19925 * Update display of text track settings
19929 TextTrackSettings.prototype.updateDisplay = function updateDisplay() {
19930 var ttDisplay = this.player_.getChild('textTrackDisplay');
19933 ttDisplay.updateDisplay();
19937 return TextTrackSettings;
19938 }(_component2['default']);
19940 _component2['default'].registerComponent('TextTrackSettings', TextTrackSettings);
19942 exports['default'] = TextTrackSettings;
19944 },{"5":5,"81":81,"83":83,"86":86,"88":88,"95":95}],72:[function(_dereq_,module,exports){
19947 exports.__esModule = true;
19949 var _textTrackCueList = _dereq_(67);
19951 var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList);
19953 var _fn = _dereq_(83);
19955 var Fn = _interopRequireWildcard(_fn);
19957 var _trackEnums = _dereq_(73);
19959 var _log = _dereq_(86);
19961 var _log2 = _interopRequireDefault(_log);
19963 var _window = _dereq_(95);
19965 var _window2 = _interopRequireDefault(_window);
19967 var _track = _dereq_(75);
19969 var _track2 = _interopRequireDefault(_track);
19971 var _url = _dereq_(92);
19973 var _xhr = _dereq_(99);
19975 var _xhr2 = _interopRequireDefault(_xhr);
19977 var _mergeOptions = _dereq_(87);
19979 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
19981 var _browser = _dereq_(78);
19983 var browser = _interopRequireWildcard(_browser);
19985 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; } }
19987 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19989 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
19991 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; }
19993 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; } /**
19994 * @file text-track.js
19999 * Takes a webvtt file contents and parses it into cues
20001 * @param {string} srcContent
20002 * webVTT file contents
20004 * @param {TextTrack} track
20005 * TextTrack to add cues to. Cues come from the srcContent.
20009 var parseCues = function parseCues(srcContent, track) {
20010 var parser = new _window2['default'].WebVTT.Parser(_window2['default'], _window2['default'].vttjs, _window2['default'].WebVTT.StringDecoder());
20013 parser.oncue = function (cue) {
20017 parser.onparsingerror = function (error) {
20018 errors.push(error);
20021 parser.onflush = function () {
20023 type: 'loadeddata',
20028 parser.parse(srcContent);
20029 if (errors.length > 0) {
20030 if (_window2['default'].console && _window2['default'].console.groupCollapsed) {
20031 _window2['default'].console.groupCollapsed('Text Track parsing errors for ' + track.src);
20033 errors.forEach(function (error) {
20034 return _log2['default'].error(error);
20036 if (_window2['default'].console && _window2['default'].console.groupEnd) {
20037 _window2['default'].console.groupEnd();
20045 * Load a `TextTrack` from a specifed url.
20047 * @param {string} src
20048 * Url to load track from.
20050 * @param {TextTrack} track
20051 * Track to add cues to. Comes from the content at the end of `url`.
20055 var loadTrack = function loadTrack(src, track) {
20059 var crossOrigin = (0, _url.isCrossOrigin)(src);
20062 opts.cors = crossOrigin;
20065 (0, _xhr2['default'])(opts, Fn.bind(this, function (err, response, responseBody) {
20067 return _log2['default'].error(err, response);
20070 track.loaded_ = true;
20072 // Make sure that vttjs has loaded, otherwise, wait till it finished loading
20073 // NOTE: this is only used for the alt/video.novtt.js build
20074 if (typeof _window2['default'].WebVTT !== 'function') {
20076 var loadHandler = function loadHandler() {
20077 return parseCues(responseBody, track);
20080 track.tech_.on('vttjsloaded', loadHandler);
20081 track.tech_.on('vttjserror', function () {
20082 _log2['default'].error('vttjs failed to load, stopping trying to process ' + track.src);
20083 track.tech_.off('vttjsloaded', loadHandler);
20087 parseCues(responseBody, track);
20093 * A representation of a single `TextTrack`.
20095 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack}
20099 var TextTrack = function (_Track) {
20100 _inherits(TextTrack, _Track);
20103 * Create an instance of this class.
20105 * @param {Object} options={}
20106 * Object of option names and values
20108 * @param {Tech} options.tech
20109 * A reference to the tech that owns this TextTrack.
20111 * @param {TextTrack~Kind} [options.kind='subtitles']
20112 * A valid text track kind.
20114 * @param {TextTrack~Mode} [options.mode='disabled']
20115 * A valid text track mode.
20117 * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
20118 * A unique id for this TextTrack.
20120 * @param {string} [options.label='']
20121 * The menu label for this track.
20123 * @param {string} [options.language='']
20124 * A valid two character language code.
20126 * @param {string} [options.srclang='']
20127 * A valid two character language code. An alternative, but deprioritized
20128 * vesion of `options.language`
20130 * @param {string} [options.src]
20131 * A url to TextTrack cues.
20133 * @param {boolean} [options.default]
20134 * If this track should default to on or off.
20136 function TextTrack() {
20139 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
20141 _classCallCheck(this, TextTrack);
20143 if (!options.tech) {
20144 throw new Error('A tech was not provided.');
20147 var settings = (0, _mergeOptions2['default'])(options, {
20148 kind: _trackEnums.TextTrackKind[options.kind] || 'subtitles',
20149 language: options.language || options.srclang || ''
20151 var mode = _trackEnums.TextTrackMode[settings.mode] || 'disabled';
20152 var default_ = settings['default'];
20154 if (settings.kind === 'metadata' || settings.kind === 'chapters') {
20157 // on IE8 this will be a document element
20158 // for every other browser this will be a normal object
20159 var tt = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
20161 tt.tech_ = settings.tech;
20163 if (browser.IS_IE8) {
20164 for (var prop in TextTrack.prototype) {
20165 if (prop !== 'constructor') {
20166 tt[prop] = TextTrack.prototype[prop];
20172 tt.activeCues_ = [];
20174 var cues = new _textTrackCueList2['default'](tt.cues_);
20175 var activeCues = new _textTrackCueList2['default'](tt.activeCues_);
20176 var changed = false;
20177 var timeupdateHandler = Fn.bind(tt, function () {
20179 // Accessing this.activeCues for the side-effects of updating itself
20180 // due to it's nature as a getter function. Do not remove or cues will
20182 /* eslint-disable no-unused-expressions */
20184 /* eslint-enable no-unused-expressions */
20186 this.trigger('cuechange');
20191 if (mode !== 'disabled') {
20192 tt.tech_.ready(function () {
20193 tt.tech_.on('timeupdate', timeupdateHandler);
20198 * @member {boolean} default
20199 * If this track was set to be on or off by default. Cannot be changed after
20204 Object.defineProperty(tt, 'default', {
20205 get: function get() {
20208 set: function set() {}
20212 * @member {string} mode
20213 * Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will
20214 * not be set if setting to an invalid mode.
20216 * @fires TextTrack#modechange
20218 Object.defineProperty(tt, 'mode', {
20219 get: function get() {
20222 set: function set(newMode) {
20225 if (!_trackEnums.TextTrackMode[newMode]) {
20229 if (mode === 'showing') {
20230 this.tech_.ready(function () {
20231 _this2.tech_.on('timeupdate', timeupdateHandler);
20235 * An event that fires when mode changes on this track. This allows
20236 * the TextTrackList that holds this track to act accordingly.
20238 * > Note: This is not part of the spec!
20240 * @event TextTrack#modechange
20241 * @type {EventTarget~Event}
20243 this.trigger('modechange');
20248 * @member {TextTrackCueList} cues
20249 * The text track cue list for this TextTrack.
20251 Object.defineProperty(tt, 'cues', {
20252 get: function get() {
20253 if (!this.loaded_) {
20259 set: function set() {}
20263 * @member {TextTrackCueList} activeCues
20264 * The list text track cues that are currently active for this TextTrack.
20266 Object.defineProperty(tt, 'activeCues', {
20267 get: function get() {
20268 if (!this.loaded_) {
20273 if (this.cues.length === 0) {
20277 var ct = this.tech_.currentTime();
20280 for (var i = 0, l = this.cues.length; i < l; i++) {
20281 var cue = this.cues[i];
20283 if (cue.startTime <= ct && cue.endTime >= ct) {
20285 } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) {
20292 if (active.length !== this.activeCues_.length) {
20295 for (var _i = 0; _i < active.length; _i++) {
20296 if (this.activeCues_.indexOf(active[_i]) === -1) {
20302 this.activeCues_ = active;
20303 activeCues.setCues_(this.activeCues_);
20307 set: function set() {}
20310 if (settings.src) {
20311 tt.src = settings.src;
20312 loadTrack(settings.src, tt);
20317 return _ret = tt, _possibleConstructorReturn(_this, _ret);
20321 * Add a cue to the internal list of cues.
20323 * @param {TextTrack~Cue} cue
20324 * The cue to add to our internal list
20328 TextTrack.prototype.addCue = function addCue(originalCue) {
20329 var cue = originalCue;
20331 if (_window2['default'].vttjs && !(originalCue instanceof _window2['default'].vttjs.VTTCue)) {
20332 cue = new _window2['default'].vttjs.VTTCue(originalCue.startTime, originalCue.endTime, originalCue.text);
20334 for (var prop in originalCue) {
20335 if (!(prop in cue)) {
20336 cue[prop] = originalCue[prop];
20340 // make sure that `id` is copied over
20341 cue.id = originalCue.id;
20342 cue.originalCue_ = originalCue;
20345 var tracks = this.tech_.textTracks();
20348 for (var i = 0; i < tracks.length; i++) {
20349 if (tracks[i] !== this) {
20350 tracks[i].removeCue(cue);
20355 this.cues_.push(cue);
20356 this.cues.setCues_(this.cues_);
20360 * Remove a cue from our internal list
20362 * @param {TextTrack~Cue} removeCue
20363 * The cue to remove from our internal list
20367 TextTrack.prototype.removeCue = function removeCue(_removeCue) {
20368 var i = this.cues_.length;
20371 var cue = this.cues_[i];
20373 if (cue === _removeCue || cue.originalCue_ && cue.originalCue_ === _removeCue) {
20374 this.cues_.splice(i, 1);
20375 this.cues.setCues_(this.cues_);
20382 }(_track2['default']);
20385 * cuechange - One or more cues in the track have become active or stopped being active.
20389 TextTrack.prototype.allowedEvents_ = {
20390 cuechange: 'cuechange'
20393 exports['default'] = TextTrack;
20395 },{"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){
20398 exports.__esModule = true;
20400 * @file track-kinds.js
20404 * All possible `VideoTrackKind`s
20406 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind
20407 * @typedef VideoTrack~Kind
20410 var VideoTrackKind = exports.VideoTrackKind = {
20411 alternative: 'alternative',
20412 captions: 'captions',
20415 subtitles: 'subtitles',
20416 commentary: 'commentary'
20420 * All possible `AudioTrackKind`s
20422 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind
20423 * @typedef AudioTrack~Kind
20426 var AudioTrackKind = exports.AudioTrackKind = {
20427 'alternative': 'alternative',
20428 'descriptions': 'descriptions',
20430 'main-desc': 'main-desc',
20431 'translation': 'translation',
20432 'commentary': 'commentary'
20436 * All possible `TextTrackKind`s
20438 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-texttrack-kind
20439 * @typedef TextTrack~Kind
20442 var TextTrackKind = exports.TextTrackKind = {
20443 subtitles: 'subtitles',
20444 captions: 'captions',
20445 descriptions: 'descriptions',
20446 chapters: 'chapters',
20447 metadata: 'metadata'
20451 * All possible `TextTrackMode`s
20453 * @see https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode
20454 * @typedef TextTrack~Mode
20457 var TextTrackMode = exports.TextTrackMode = {
20458 disabled: 'disabled',
20463 },{}],74:[function(_dereq_,module,exports){
20466 exports.__esModule = true;
20468 var _eventTarget = _dereq_(42);
20470 var _eventTarget2 = _interopRequireDefault(_eventTarget);
20472 var _browser = _dereq_(78);
20474 var browser = _interopRequireWildcard(_browser);
20476 var _document = _dereq_(94);
20478 var _document2 = _interopRequireDefault(_document);
20480 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; } }
20482 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
20484 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20486 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; }
20488 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; } /**
20489 * @file track-list.js
20494 * Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and
20495 * {@link VideoTrackList}
20497 * @extends EventTarget
20499 var TrackList = function (_EventTarget) {
20500 _inherits(TrackList, _EventTarget);
20503 * Create an instance of this class
20505 * @param {Track[]} tracks
20506 * A list of tracks to initialize the list with.
20508 * @param {Object} [list]
20509 * The child object with inheritance done manually for ie8.
20513 function TrackList() {
20514 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
20518 var list = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
20520 _classCallCheck(this, TrackList);
20522 var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
20525 list = _this; // eslint-disable-line
20526 if (browser.IS_IE8) {
20527 list = _document2['default'].createElement('custom');
20528 for (var prop in TrackList.prototype) {
20529 if (prop !== 'constructor') {
20530 list[prop] = TrackList.prototype[prop];
20539 * @member {number} length
20540 * The current number of `Track`s in the this Trackist.
20542 Object.defineProperty(list, 'length', {
20543 get: function get() {
20544 return this.tracks_.length;
20548 for (var i = 0; i < tracks.length; i++) {
20549 list.addTrack_(tracks[i]);
20552 // must return the object, as for ie8 it will not be this
20553 // but a reference to a document object
20554 return _ret = list, _possibleConstructorReturn(_this, _ret);
20558 * Add a {@link Track} to the `TrackList`
20560 * @param {Track} track
20561 * The audio, video, or text track to add to the list.
20563 * @fires TrackList#addtrack
20568 TrackList.prototype.addTrack_ = function addTrack_(track) {
20569 var index = this.tracks_.length;
20571 if (!('' + index in this)) {
20572 Object.defineProperty(this, index, {
20573 get: function get() {
20574 return this.tracks_[index];
20579 // Do not add duplicate tracks
20580 if (this.tracks_.indexOf(track) === -1) {
20581 this.tracks_.push(track);
20583 * Triggered when a track is added to a track list.
20585 * @event TrackList#addtrack
20586 * @type {EventTarget~Event}
20587 * @property {Track} track
20588 * A reference to track that was added.
20598 * Remove a {@link Track} from the `TrackList`
20600 * @param {Track} track
20601 * The audio, video, or text track to remove from the list.
20603 * @fires TrackList#removetrack
20608 TrackList.prototype.removeTrack_ = function removeTrack_(rtrack) {
20609 var track = void 0;
20611 for (var i = 0, l = this.length; i < l; i++) {
20612 if (this[i] === rtrack) {
20618 this.tracks_.splice(i, 1);
20629 * Triggered when a track is removed from track list.
20631 * @event TrackList#removetrack
20632 * @type {EventTarget~Event}
20633 * @property {Track} track
20634 * A reference to track that was removed.
20638 type: 'removetrack'
20643 * Get a Track from the TrackList by a tracks id
20645 * @param {String} id - the id of the track to get
20646 * @method getTrackById
20652 TrackList.prototype.getTrackById = function getTrackById(id) {
20655 for (var i = 0, l = this.length; i < l; i++) {
20656 var track = this[i];
20658 if (track.id === id) {
20668 }(_eventTarget2['default']);
20671 * Triggered when a different track is selected/enabled.
20673 * @event TrackList#change
20674 * @type {EventTarget~Event}
20678 * Events that can be called with on + eventName. See {@link EventHandler}.
20680 * @property {Object} TrackList#allowedEvents_
20685 TrackList.prototype.allowedEvents_ = {
20687 addtrack: 'addtrack',
20688 removetrack: 'removetrack'
20691 // emulate attribute EventHandler support to allow for feature detection
20692 for (var event in TrackList.prototype.allowedEvents_) {
20693 TrackList.prototype['on' + event] = null;
20696 exports['default'] = TrackList;
20698 },{"42":42,"78":78,"94":94}],75:[function(_dereq_,module,exports){
20701 exports.__esModule = true;
20703 var _browser = _dereq_(78);
20705 var browser = _interopRequireWildcard(_browser);
20707 var _document = _dereq_(94);
20709 var _document2 = _interopRequireDefault(_document);
20711 var _guid = _dereq_(85);
20713 var Guid = _interopRequireWildcard(_guid);
20715 var _eventTarget = _dereq_(42);
20717 var _eventTarget2 = _interopRequireDefault(_eventTarget);
20719 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
20721 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; } }
20723 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20725 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; }
20727 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; } /**
20733 * A Track class that contains all of the common functionality for {@link AudioTrack},
20734 * {@link VideoTrack}, and {@link TextTrack}.
20736 * > Note: This class should not be used directly
20738 * @see {@link https://html.spec.whatwg.org/multipage/embedded-content.html}
20739 * @extends EventTarget
20742 var Track = function (_EventTarget) {
20743 _inherits(Track, _EventTarget);
20746 * Create an instance of this class.
20748 * @param {Object} [options={}]
20749 * Object of option names and values
20751 * @param {string} [options.kind='']
20752 * A valid kind for the track type you are creating.
20754 * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
20755 * A unique id for this AudioTrack.
20757 * @param {string} [options.label='']
20758 * The menu label for this track.
20760 * @param {string} [options.language='']
20761 * A valid two character language code.
20768 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
20770 _classCallCheck(this, Track);
20772 var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
20774 var track = _this; // eslint-disable-line
20776 if (browser.IS_IE8) {
20777 track = _document2['default'].createElement('custom');
20778 for (var prop in Track.prototype) {
20779 if (prop !== 'constructor') {
20780 track[prop] = Track.prototype[prop];
20786 id: options.id || 'vjs_track_' + Guid.newGUID(),
20787 kind: options.kind || '',
20788 label: options.label || '',
20789 language: options.language || ''
20793 * @member {string} id
20794 * The id of this track. Cannot be changed after creation.
20800 * @member {string} kind
20801 * The kind of track that this is. Cannot be changed after creation.
20807 * @member {string} label
20808 * The label of this track. Cannot be changed after creation.
20814 * @member {string} language
20815 * The two letter language code for this track. Cannot be changed after
20821 var _loop = function _loop(key) {
20822 Object.defineProperty(track, key, {
20823 get: function get() {
20824 return trackProps[key];
20826 set: function set() {}
20830 for (var key in trackProps) {
20834 return _ret = track, _possibleConstructorReturn(_this, _ret);
20838 }(_eventTarget2['default']);
20840 exports['default'] = Track;
20842 },{"42":42,"78":78,"85":85,"94":94}],76:[function(_dereq_,module,exports){
20845 exports.__esModule = true;
20847 var _trackList = _dereq_(74);
20849 var _trackList2 = _interopRequireDefault(_trackList);
20851 var _browser = _dereq_(78);
20853 var browser = _interopRequireWildcard(_browser);
20855 var _document = _dereq_(94);
20857 var _document2 = _interopRequireDefault(_document);
20859 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; } }
20861 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
20863 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20865 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; }
20867 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; } /**
20868 * @file video-track-list.js
20873 * Un-select all other {@link VideoTrack}s that are selected.
20875 * @param {VideoTrackList} list
20878 * @param {VideoTrack} track
20879 * The track to skip
20883 var disableOthers = function disableOthers(list, track) {
20884 for (var i = 0; i < list.length; i++) {
20885 if (track.id === list[i].id) {
20888 // another video track is enabled, disable it
20889 list[i].selected = false;
20894 * The current list of {@link VideoTrack} for a video.
20896 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist}
20897 * @extends TrackList
20900 var VideoTrackList = function (_TrackList) {
20901 _inherits(VideoTrackList, _TrackList);
20904 * Create an instance of this class.
20906 * @param {VideoTrack[]} [tracks=[]]
20907 * A list of `VideoTrack` to instantiate the list with.
20909 function VideoTrackList() {
20912 var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
20914 _classCallCheck(this, VideoTrackList);
20918 // make sure only 1 track is enabled
20919 // sorted from last index to first index
20920 for (var i = tracks.length - 1; i >= 0; i--) {
20921 if (tracks[i].selected) {
20922 disableOthers(tracks, tracks[i]);
20927 // IE8 forces us to implement inheritance ourselves
20928 // as it does not support Object.defineProperty properly
20929 if (browser.IS_IE8) {
20930 list = _document2['default'].createElement('custom');
20931 for (var prop in _trackList2['default'].prototype) {
20932 if (prop !== 'constructor') {
20933 list[prop] = _trackList2['default'].prototype[prop];
20936 for (var _prop in VideoTrackList.prototype) {
20937 if (_prop !== 'constructor') {
20938 list[_prop] = VideoTrackList.prototype[_prop];
20943 list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
20944 list.changing_ = false;
20947 * @member {number} VideoTrackList#selectedIndex
20948 * The current index of the selected {@link VideoTrack`}.
20950 Object.defineProperty(list, 'selectedIndex', {
20951 get: function get() {
20952 for (var _i = 0; _i < this.length; _i++) {
20953 if (this[_i].selected) {
20959 set: function set() {}
20962 return _ret = list, _possibleConstructorReturn(_this, _ret);
20966 * Add a {@link VideoTrack} to the `VideoTrackList`.
20968 * @param {VideoTrack} track
20969 * The VideoTrack to add to the list
20971 * @fires TrackList#addtrack
20976 VideoTrackList.prototype.addTrack_ = function addTrack_(track) {
20979 if (track.selected) {
20980 disableOthers(this, track);
20983 _TrackList.prototype.addTrack_.call(this, track);
20984 // native tracks don't have this
20985 if (!track.addEventListener) {
20990 * @listens VideoTrack#selectedchange
20991 * @fires TrackList#change
20993 track.addEventListener('selectedchange', function () {
20994 if (_this2.changing_) {
20997 _this2.changing_ = true;
20998 disableOthers(_this2, track);
20999 _this2.changing_ = false;
21000 _this2.trigger('change');
21005 * Add a {@link VideoTrack} to the `VideoTrackList`.
21007 * @param {VideoTrack} track
21008 * The VideoTrack to add to the list
21010 * @fires TrackList#addtrack
21014 VideoTrackList.prototype.addTrack = function addTrack(track) {
21015 this.addTrack_(track);
21019 * Remove a {@link VideoTrack} to the `VideoTrackList`.
21021 * @param {VideoTrack} track
21022 * The VideoTrack to remove from the list.
21024 * @fires TrackList#removetrack
21028 VideoTrackList.prototype.removeTrack = function removeTrack(track) {
21029 _TrackList.prototype.removeTrack_.call(this, track);
21032 return VideoTrackList;
21033 }(_trackList2['default']);
21035 exports['default'] = VideoTrackList;
21037 },{"74":74,"78":78,"94":94}],77:[function(_dereq_,module,exports){
21040 exports.__esModule = true;
21042 var _trackEnums = _dereq_(73);
21044 var _track = _dereq_(75);
21046 var _track2 = _interopRequireDefault(_track);
21048 var _mergeOptions = _dereq_(87);
21050 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
21052 var _browser = _dereq_(78);
21054 var browser = _interopRequireWildcard(_browser);
21056 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; } }
21058 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21060 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
21062 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; }
21064 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; }
21067 * A representation of a single `VideoTrack`.
21069 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack}
21072 var VideoTrack = function (_Track) {
21073 _inherits(VideoTrack, _Track);
21076 * Create an instance of this class.
21078 * @param {Object} [options={}]
21079 * Object of option names and values
21081 * @param {string} [options.kind='']
21082 * A valid {@link VideoTrack~Kind}
21084 * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
21085 * A unique id for this AudioTrack.
21087 * @param {string} [options.label='']
21088 * The menu label for this track.
21090 * @param {string} [options.language='']
21091 * A valid two character language code.
21093 * @param {boolean} [options.selected]
21094 * If this track is the one that is currently playing.
21096 function VideoTrack() {
21099 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
21101 _classCallCheck(this, VideoTrack);
21103 var settings = (0, _mergeOptions2['default'])(options, {
21104 kind: _trackEnums.VideoTrackKind[options.kind] || ''
21107 // on IE8 this will be a document element
21108 // for every other browser this will be a normal object
21109 var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
21110 var selected = false;
21112 if (browser.IS_IE8) {
21113 for (var prop in VideoTrack.prototype) {
21114 if (prop !== 'constructor') {
21115 track[prop] = VideoTrack.prototype[prop];
21121 * @member {boolean} selected
21122 * If this `VideoTrack` is selected or not. When setting this will
21123 * fire {@link VideoTrack#selectedchange} if the state of selected changed.
21125 * @fires VideoTrack#selectedchange
21127 Object.defineProperty(track, 'selected', {
21128 get: function get() {
21131 set: function set(newSelected) {
21132 // an invalid or unchanged value
21133 if (typeof newSelected !== 'boolean' || newSelected === selected) {
21136 selected = newSelected;
21139 * An event that fires when selected changes on this track. This allows
21140 * the VideoTrackList that holds this track to act accordingly.
21142 * > Note: This is not part of the spec! Native tracks will do
21143 * this internally without an event.
21145 * @event VideoTrack#selectedchange
21146 * @type {EventTarget~Event}
21148 this.trigger('selectedchange');
21152 // if the user sets this track to selected then
21153 // set selected to that true value otherwise
21154 // we keep it false
21155 if (settings.selected) {
21156 track.selected = settings.selected;
21159 return _ret = track, _possibleConstructorReturn(_this, _ret);
21163 }(_track2['default']);
21165 exports['default'] = VideoTrack;
21167 },{"73":73,"75":75,"78":78,"87":87}],78:[function(_dereq_,module,exports){
21170 exports.__esModule = true;
21171 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;
21173 var _dom = _dereq_(81);
21175 var Dom = _interopRequireWildcard(_dom);
21177 var _window = _dereq_(95);
21179 var _window2 = _interopRequireDefault(_window);
21181 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21183 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; } }
21189 var USER_AGENT = _window2['default'].navigator && _window2['default'].navigator.userAgent || '';
21190 var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT);
21191 var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null;
21194 * Device is an iPhone
21200 var IS_IPAD = exports.IS_IPAD = /iPad/i.test(USER_AGENT);
21202 // The Facebook app's UIWebView identifies as both an iPhone and iPad, so
21203 // to identify iPhones, we need to exclude iPads.
21204 // http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/
21205 var IS_IPHONE = exports.IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD;
21206 var IS_IPOD = exports.IS_IPOD = /iPod/i.test(USER_AGENT);
21207 var IS_IOS = exports.IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;
21209 var IOS_VERSION = exports.IOS_VERSION = function () {
21210 var match = USER_AGENT.match(/OS (\d+)_/i);
21212 if (match && match[1]) {
21218 var IS_ANDROID = exports.IS_ANDROID = /Android/i.test(USER_AGENT);
21219 var ANDROID_VERSION = exports.ANDROID_VERSION = function () {
21220 // This matches Android Major.Minor.Patch versions
21221 // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
21222 var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);
21228 var major = match[1] && parseFloat(match[1]);
21229 var minor = match[2] && parseFloat(match[2]);
21231 if (major && minor) {
21232 return parseFloat(match[1] + '.' + match[2]);
21233 } else if (major) {
21239 // Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser
21240 var IS_OLD_ANDROID = exports.IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3;
21241 var IS_NATIVE_ANDROID = exports.IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537;
21243 var IS_FIREFOX = exports.IS_FIREFOX = /Firefox/i.test(USER_AGENT);
21244 var IS_EDGE = exports.IS_EDGE = /Edge/i.test(USER_AGENT);
21245 var IS_CHROME = exports.IS_CHROME = !IS_EDGE && /Chrome/i.test(USER_AGENT);
21246 var IS_IE8 = exports.IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT);
21247 var IE_VERSION = exports.IE_VERSION = function () {
21248 var result = /MSIE\s(\d+)\.\d/.exec(USER_AGENT);
21249 var version = result && parseFloat(result[1]);
21251 if (!version && /Trident\/7.0/i.test(USER_AGENT) && /rv:11.0/.test(USER_AGENT)) {
21252 // IE 11 has a different user agent string than other IE versions
21259 var IS_SAFARI = exports.IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE;
21260 var IS_ANY_SAFARI = exports.IS_ANY_SAFARI = IS_SAFARI || IS_IOS;
21262 var TOUCH_ENABLED = exports.TOUCH_ENABLED = Dom.isReal() && ('ontouchstart' in _window2['default'] || _window2['default'].DocumentTouch && _window2['default'].document instanceof _window2['default'].DocumentTouch);
21264 var BACKGROUND_SIZE_SUPPORTED = exports.BACKGROUND_SIZE_SUPPORTED = Dom.isReal() && 'backgroundSize' in _window2['default'].document.createElement('video').style;
21266 },{"81":81,"95":95}],79:[function(_dereq_,module,exports){
21269 exports.__esModule = true;
21270 exports.bufferedPercent = bufferedPercent;
21272 var _timeRanges = _dereq_(90);
21275 * Compute the percentage of the media that has been buffered.
21277 * @param {TimeRange} buffered
21278 * The current `TimeRange` object representing buffered time ranges
21280 * @param {number} duration
21281 * Total duration of the media
21284 * Percent buffered of the total duration in decimal form.
21286 function bufferedPercent(buffered, duration) {
21287 var bufferedDuration = 0;
21288 var start = void 0;
21295 if (!buffered || !buffered.length) {
21296 buffered = (0, _timeRanges.createTimeRange)(0, 0);
21299 for (var i = 0; i < buffered.length; i++) {
21300 start = buffered.start(i);
21301 end = buffered.end(i);
21303 // buffered end can be bigger than duration by a very small fraction
21304 if (end > duration) {
21308 bufferedDuration += end - start;
21311 return bufferedDuration / duration;
21317 },{"90":90}],80:[function(_dereq_,module,exports){
21320 exports.__esModule = true;
21321 exports['default'] = computedStyle;
21323 var _window = _dereq_(95);
21325 var _window2 = _interopRequireDefault(_window);
21327 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21330 * A safe getComputedStyle with an IE8 fallback.
21332 * This is needed because in Firefox, if the player is loaded in an iframe with
21333 * `display:none`, then `getComputedStyle` returns `null`, so, we do a null-check to
21334 * make sure that the player doesn't break in these cases.
21336 * @param {Element} el
21337 * The element you want the computed style of
21339 * @param {string} prop
21340 * The property name you want
21342 * @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397
21344 function computedStyle(el, prop) {
21345 if (!el || !prop) {
21349 if (typeof _window2['default'].getComputedStyle === 'function') {
21350 var cs = _window2['default'].getComputedStyle(el);
21352 return cs ? cs[prop] : '';
21355 return el.currentStyle[prop] || '';
21357 * @file computed-style.js
21358 * @module computed-style
21361 },{"95":95}],81:[function(_dereq_,module,exports){
21364 exports.__esModule = true;
21365 exports.$$ = exports.$ = undefined;
21367 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 ', '.']);
21369 exports.isReal = isReal;
21370 exports.isEl = isEl;
21371 exports.getEl = getEl;
21372 exports.createEl = createEl;
21373 exports.textContent = textContent;
21374 exports.insertElFirst = insertElFirst;
21375 exports.getElData = getElData;
21376 exports.hasElData = hasElData;
21377 exports.removeElData = removeElData;
21378 exports.hasElClass = hasElClass;
21379 exports.addElClass = addElClass;
21380 exports.removeElClass = removeElClass;
21381 exports.toggleElClass = toggleElClass;
21382 exports.setElAttributes = setElAttributes;
21383 exports.getElAttributes = getElAttributes;
21384 exports.getAttribute = getAttribute;
21385 exports.setAttribute = setAttribute;
21386 exports.removeAttribute = removeAttribute;
21387 exports.blockTextSelection = blockTextSelection;
21388 exports.unblockTextSelection = unblockTextSelection;
21389 exports.findElPosition = findElPosition;
21390 exports.getPointerPosition = getPointerPosition;
21391 exports.isTextNode = isTextNode;
21392 exports.emptyEl = emptyEl;
21393 exports.normalizeContent = normalizeContent;
21394 exports.appendContent = appendContent;
21395 exports.insertContent = insertContent;
21397 var _document = _dereq_(94);
21399 var _document2 = _interopRequireDefault(_document);
21401 var _window = _dereq_(95);
21403 var _window2 = _interopRequireDefault(_window);
21405 var _guid = _dereq_(85);
21407 var Guid = _interopRequireWildcard(_guid);
21409 var _log = _dereq_(86);
21411 var _log2 = _interopRequireDefault(_log);
21413 var _tsml = _dereq_(98);
21415 var _tsml2 = _interopRequireDefault(_tsml);
21417 var _obj = _dereq_(88);
21419 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; } }
21421 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
21423 function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } /**
21430 * Detect if a value is a string with any non-whitespace characters.
21432 * @param {string} str
21433 * The string to check
21435 * @return {boolean}
21436 * - True if the string is non-blank
21437 * - False otherwise
21440 function isNonBlankString(str) {
21441 return typeof str === 'string' && /\S/.test(str);
21445 * Throws an error if the passed string has whitespace. This is used by
21446 * class methods to be relatively consistent with the classList API.
21448 * @param {string} str
21449 * The string to check for whitespace.
21452 * Throws an error if there is whitespace in the string.
21455 function throwIfWhitespace(str) {
21456 if (/\s/.test(str)) {
21457 throw new Error('class has illegal whitespace characters');
21462 * Produce a regular expression for matching a className within an elements className.
21464 * @param {string} className
21465 * The className to generate the RegExp for.
21468 * The RegExp that will check for a specific `className` in an elements
21471 function classRegExp(className) {
21472 return new RegExp('(^|\\s)' + className + '($|\\s)');
21476 * Whether the current DOM interface appears to be real.
21478 * @return {Boolean}
21480 function isReal() {
21483 // Both document and window will never be undefined thanks to `global`.
21484 _document2['default'] === _window2['default'].document &&
21486 // In IE < 9, DOM methods return "object" as their type, so all we can
21487 // confidently check is that it exists.
21488 typeof _document2['default'].createElement !== 'undefined'
21493 * Determines, via duck typing, whether or not a value is a DOM element.
21495 * @param {Mixed} value
21496 * The thing to check
21498 * @return {boolean}
21499 * - True if it is a DOM element
21500 * - False otherwise
21502 function isEl(value) {
21503 return (0, _obj.isObject)(value) && value.nodeType === 1;
21507 * Creates functions to query the DOM using a given method.
21509 * @param {string} method
21510 * The method to create the query with.
21512 * @return {Function}
21515 function createQuerier(method) {
21516 return function (selector, context) {
21517 if (!isNonBlankString(selector)) {
21518 return _document2['default'][method](null);
21520 if (isNonBlankString(context)) {
21521 context = _document2['default'].querySelector(context);
21524 var ctx = isEl(context) ? context : _document2['default'];
21526 return ctx[method] && ctx[method](selector);
21531 * Shorthand for document.getElementById()
21532 * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs.
21534 * @param {string} id
21535 * The id of the element to get
21537 * @return {Element|null}
21538 * Element with supplied ID or null if there wasn't one.
21540 function getEl(id) {
21541 if (id.indexOf('#') === 0) {
21545 return _document2['default'].getElementById(id);
21549 * Creates an element and applies properties.
21551 * @param {string} [tagName='div']
21552 * Name of tag to be created.
21554 * @param {Object} [properties={}]
21555 * Element properties to be applied.
21557 * @param {Object} [attributes={}]
21558 * Element attributes to be applied.
21560 * @param {String|Element|TextNode|Array|Function} [content]
21561 * Contents for the element (see: {@link dom:normalizeContent})
21563 * @return {Element}
21564 * The element that was created.
21566 function createEl() {
21567 var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
21568 var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
21569 var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
21570 var content = arguments[3];
21572 var el = _document2['default'].createElement(tagName);
21574 Object.getOwnPropertyNames(properties).forEach(function (propName) {
21575 var val = properties[propName];
21578 // We originally were accepting both properties and attributes in the
21579 // same object, but that doesn't work so well.
21580 if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') {
21581 _log2['default'].warn((0, _tsml2['default'])(_templateObject, propName, val));
21582 el.setAttribute(propName, val);
21584 // Handle textContent since it's not supported everywhere and we have a
21586 } else if (propName === 'textContent') {
21587 textContent(el, val);
21589 el[propName] = val;
21593 Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
21594 el.setAttribute(attrName, attributes[attrName]);
21598 appendContent(el, content);
21605 * Injects text into an element, replacing any existing contents entirely.
21607 * @param {Element} el
21608 * The element to add text content into
21610 * @param {string} text
21611 * The text content to add.
21613 * @return {Element}
21614 * The element with added text content.
21616 function textContent(el, text) {
21617 if (typeof el.textContent === 'undefined') {
21618 el.innerText = text;
21620 el.textContent = text;
21626 * Insert an element as the first child node of another
21628 * @param {Element} child
21629 * Element to insert
21631 * @param {Element} parent
21632 * Element to insert child into
21635 function insertElFirst(child, parent) {
21636 if (parent.firstChild) {
21637 parent.insertBefore(child, parent.firstChild);
21639 parent.appendChild(child);
21644 * Element Data Store. Allows for binding data to an element without putting it directly on the element.
21645 * Ex. Event listeners are stored here.
21646 * (also from jsninja.com, slightly modified and updated for closure compiler)
21654 * Unique attribute name to store an element's guid in
21660 var elIdAttr = 'vdata' + new Date().getTime();
21663 * Returns the cache object where data for an element is stored
21665 * @param {Element} el
21666 * Element to store data for.
21669 * The cache object for that el that was passed in.
21671 function getElData(el) {
21672 var id = el[elIdAttr];
21675 id = el[elIdAttr] = Guid.newGUID();
21686 * Returns whether or not an element has cached data
21688 * @param {Element} el
21689 * Check if this element has cached data.
21691 * @return {boolean}
21692 * - True if the DOM element has cached data.
21693 * - False otherwise.
21695 function hasElData(el) {
21696 var id = el[elIdAttr];
21702 return !!Object.getOwnPropertyNames(elData[id]).length;
21706 * Delete data for the element from the cache and the guid attr from getElementById
21708 * @param {Element} el
21709 * Remove cached data for this element.
21711 function removeElData(el) {
21712 var id = el[elIdAttr];
21718 // Remove all stored data
21721 // Remove the elIdAttr property from the DOM node
21723 delete el[elIdAttr];
21725 if (el.removeAttribute) {
21726 el.removeAttribute(elIdAttr);
21728 // IE doesn't appear to support removeAttribute on the document element
21729 el[elIdAttr] = null;
21735 * Check if an element has a CSS class
21737 * @param {Element} element
21740 * @param {string} classToCheck
21741 * Class name to check for
21743 * @return {boolean}
21744 * - True if the element had the class
21745 * - False otherwise.
21748 * Throws an error if `classToCheck` has white space.
21750 function hasElClass(element, classToCheck) {
21751 throwIfWhitespace(classToCheck);
21752 if (element.classList) {
21753 return element.classList.contains(classToCheck);
21755 return classRegExp(classToCheck).test(element.className);
21759 * Add a CSS class name to an element
21761 * @param {Element} element
21762 * Element to add class name to.
21764 * @param {string} classToAdd
21765 * Class name to add.
21767 * @return {Element}
21768 * The dom element with the added class name.
21770 function addElClass(element, classToAdd) {
21771 if (element.classList) {
21772 element.classList.add(classToAdd);
21774 // Don't need to `throwIfWhitespace` here because `hasElClass` will do it
21775 // in the case of classList not being supported.
21776 } else if (!hasElClass(element, classToAdd)) {
21777 element.className = (element.className + ' ' + classToAdd).trim();
21784 * Remove a CSS class name from an element
21786 * @param {Element} element
21787 * Element to remove a class name from.
21789 * @param {string} classToRemove
21790 * Class name to remove
21792 * @return {Element}
21793 * The dom element with class name removed.
21795 function removeElClass(element, classToRemove) {
21796 if (element.classList) {
21797 element.classList.remove(classToRemove);
21799 throwIfWhitespace(classToRemove);
21800 element.className = element.className.split(/\s+/).filter(function (c) {
21801 return c !== classToRemove;
21809 * The callback definition for toggleElClass.
21811 * @callback Dom~PredicateCallback
21812 * @param {Element} element
21813 * The DOM element of the Component.
21815 * @param {string} classToToggle
21816 * The `className` that wants to be toggled
21818 * @return {boolean|undefined}
21819 * - If true the `classToToggle` will get added to `element`.
21820 * - If false the `classToToggle` will get removed from `element`.
21821 * - If undefined this callback will be ignored
21825 * Adds or removes a CSS class name on an element depending on an optional
21826 * condition or the presence/absence of the class name.
21828 * @param {Element} element
21829 * The element to toggle a class name on.
21831 * @param {string} classToToggle
21832 * The class that should be toggled
21834 * @param {boolean|PredicateCallback} [predicate]
21835 * See the return value for {@link Dom~PredicateCallback}
21837 * @return {Element}
21838 * The element with a class that has been toggled.
21840 function toggleElClass(element, classToToggle, predicate) {
21842 // This CANNOT use `classList` internally because IE does not support the
21843 // second parameter to the `classList.toggle()` method! Which is fine because
21844 // `classList` will be used by the add/remove functions.
21845 var has = hasElClass(element, classToToggle);
21847 if (typeof predicate === 'function') {
21848 predicate = predicate(element, classToToggle);
21851 if (typeof predicate !== 'boolean') {
21855 // If the necessary class operation matches the current state of the
21856 // element, no action is required.
21857 if (predicate === has) {
21862 addElClass(element, classToToggle);
21864 removeElClass(element, classToToggle);
21871 * Apply attributes to an HTML element.
21873 * @param {Element} el
21874 * Element to add attributes to.
21876 * @param {Object} [attributes]
21877 * Attributes to be applied.
21879 function setElAttributes(el, attributes) {
21880 Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
21881 var attrValue = attributes[attrName];
21883 if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
21884 el.removeAttribute(attrName);
21886 el.setAttribute(attrName, attrValue === true ? '' : attrValue);
21892 * Get an element's attribute values, as defined on the HTML tag
21893 * Attributes are not the same as properties. They're defined on the tag
21894 * or with setAttribute (which shouldn't be used with HTML)
21895 * This will return true or false for boolean attributes.
21897 * @param {Element} tag
21898 * Element from which to get tag attributes.
21901 * All attributes of the element.
21903 function getElAttributes(tag) {
21906 // known boolean attributes
21907 // we can check for matching boolean properties, but older browsers
21908 // won't know about HTML5 boolean attributes that we still read from
21909 var knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ',';
21911 if (tag && tag.attributes && tag.attributes.length > 0) {
21912 var attrs = tag.attributes;
21914 for (var i = attrs.length - 1; i >= 0; i--) {
21915 var attrName = attrs[i].name;
21916 var attrVal = attrs[i].value;
21918 // check for known booleans
21919 // the matching element property will return a value for typeof
21920 if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {
21921 // the value of an included boolean attribute is typically an empty
21922 // string ('') which would equal false if we just check for a false value.
21923 // we also don't want support bad code like autoplay='false'
21924 attrVal = attrVal !== null ? true : false;
21927 obj[attrName] = attrVal;
21935 * Get the value of an element's attribute
21937 * @param {Element} el
21940 * @param {string} attribute
21941 * Attribute to get the value of
21944 * value of the attribute
21946 function getAttribute(el, attribute) {
21947 return el.getAttribute(attribute);
21951 * Set the value of an element's attribute
21953 * @param {Element} el
21956 * @param {string} attribute
21959 * @param {string} value
21960 * Value to set the attribute to
21962 function setAttribute(el, attribute, value) {
21963 el.setAttribute(attribute, value);
21967 * Remove an element's attribute
21969 * @param {Element} el
21972 * @param {string} attribute
21973 * Attribute to remove
21975 function removeAttribute(el, attribute) {
21976 el.removeAttribute(attribute);
21980 * Attempt to block the ability to select text while dragging controls
21982 function blockTextSelection() {
21983 _document2['default'].body.focus();
21984 _document2['default'].onselectstart = function () {
21990 * Turn off text selection blocking
21992 function unblockTextSelection() {
21993 _document2['default'].onselectstart = function () {
21999 * The postion of a DOM element on the page.
22001 * @typedef {Object} Dom~Position
22003 * @property {number} left
22004 * Pixels to the left
22006 * @property {number} top
22012 * getBoundingClientRect technique from
22015 * @see http://ejohn.org/blog/getboundingclientrect-is-awesome/
22017 * @param {Element} el
22018 * Element from which to get offset
22020 * @return {Dom~Position}
22021 * The position of the element that was passed in.
22023 function findElPosition(el) {
22026 if (el.getBoundingClientRect && el.parentNode) {
22027 box = el.getBoundingClientRect();
22037 var docEl = _document2['default'].documentElement;
22038 var body = _document2['default'].body;
22040 var clientLeft = docEl.clientLeft || body.clientLeft || 0;
22041 var scrollLeft = _window2['default'].pageXOffset || body.scrollLeft;
22042 var left = box.left + scrollLeft - clientLeft;
22044 var clientTop = docEl.clientTop || body.clientTop || 0;
22045 var scrollTop = _window2['default'].pageYOffset || body.scrollTop;
22046 var top = box.top + scrollTop - clientTop;
22048 // Android sometimes returns slightly off decimal values, so need to round
22050 left: Math.round(left),
22051 top: Math.round(top)
22056 * x and y coordinates for a dom element or mouse pointer
22058 * @typedef {Object} Dom~Coordinates
22060 * @property {number} x
22061 * x coordinate in pixels
22063 * @property {number} y
22064 * y coordinate in pixels
22068 * Get pointer position in element
22069 * Returns an object with x and y coordinates.
22070 * The base on the coordinates are the bottom left of the element.
22072 * @param {Element} el
22073 * Element on which to get the pointer position on
22075 * @param {EventTarget~Event} event
22078 * @return {Dom~Coordinates}
22079 * A Coordinates object corresponding to the mouse position.
22082 function getPointerPosition(el, event) {
22084 var box = findElPosition(el);
22085 var boxW = el.offsetWidth;
22086 var boxH = el.offsetHeight;
22088 var boxY = box.top;
22089 var boxX = box.left;
22090 var pageY = event.pageY;
22091 var pageX = event.pageX;
22093 if (event.changedTouches) {
22094 pageX = event.changedTouches[0].pageX;
22095 pageY = event.changedTouches[0].pageY;
22098 position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH));
22099 position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));
22105 * Determines, via duck typing, whether or not a value is a text node.
22107 * @param {Mixed} value
22108 * Check if this value is a text node.
22110 * @return {boolean}
22111 * - True if it is a text node
22112 * - False otherwise
22114 function isTextNode(value) {
22115 return (0, _obj.isObject)(value) && value.nodeType === 3;
22119 * Empties the contents of an element.
22121 * @param {Element} el
22122 * The element to empty children from
22124 * @return {Element}
22125 * The element with no children
22127 function emptyEl(el) {
22128 while (el.firstChild) {
22129 el.removeChild(el.firstChild);
22135 * Normalizes content for eventual insertion into the DOM.
22137 * This allows a wide range of content definition methods, but protects
22138 * from falling into the trap of simply writing to `innerHTML`, which is
22141 * The content for an element can be passed in multiple types and
22142 * combinations, whose behavior is as follows:
22144 * @param {String|Element|TextNode|Array|Function} content
22145 * - String: Normalized into a text node.
22146 * - Element/TextNode: Passed through.
22147 * - Array: A one-dimensional array of strings, elements, nodes, or functions
22148 * (which return single strings, elements, or nodes).
22149 * - Function: If the sole argument, is expected to produce a string, element,
22150 * node, or array as defined above.
22153 * All of the content that was passed in normalized.
22155 function normalizeContent(content) {
22157 // First, invoke content if it is a function. If it produces an array,
22158 // that needs to happen before normalization.
22159 if (typeof content === 'function') {
22160 content = content();
22163 // Next up, normalize to an array, so one or many items can be normalized,
22164 // filtered, and returned.
22165 return (Array.isArray(content) ? content : [content]).map(function (value) {
22167 // First, invoke value if it is a function to produce a new value,
22168 // which will be subsequently normalized to a Node of some kind.
22169 if (typeof value === 'function') {
22173 if (isEl(value) || isTextNode(value)) {
22177 if (typeof value === 'string' && /\S/.test(value)) {
22178 return _document2['default'].createTextNode(value);
22180 }).filter(function (value) {
22186 * Normalizes and appends content to an element.
22188 * @param {Element} el
22189 * Element to append normalized content to.
22192 * @param {String|Element|TextNode|Array|Function} content
22193 * See the `content` argument of {@link dom:normalizeContent}
22195 * @return {Element}
22196 * The element with appended normalized content.
22198 function appendContent(el, content) {
22199 normalizeContent(content).forEach(function (node) {
22200 return el.appendChild(node);
22206 * Normalizes and inserts content into an element; this is identical to
22207 * `appendContent()`, except it empties the element first.
22209 * @param {Element} el
22210 * Element to insert normalized content into.
22212 * @param {String|Element|TextNode|Array|Function} content
22213 * See the `content` argument of {@link dom:normalizeContent}
22215 * @return {Element}
22216 * The element with inserted normalized content.
22219 function insertContent(el, content) {
22220 return appendContent(emptyEl(el), content);
22224 * Finds a single DOM element matching `selector` within the optional
22225 * `context` of another DOM element (defaulting to `document`).
22227 * @param {string} selector
22228 * A valid CSS selector, which will be passed to `querySelector`.
22230 * @param {Element|String} [context=document]
22231 * A DOM element within which to query. Can also be a selector
22232 * string in which case the first matching element will be used
22233 * as context. If missing (or no element matches selector), falls
22234 * back to `document`.
22236 * @return {Element|null}
22237 * The element that was found or null.
22239 var $ = exports.$ = createQuerier('querySelector');
22242 * Finds a all DOM elements matching `selector` within the optional
22243 * `context` of another DOM element (defaulting to `document`).
22245 * @param {string} selector
22246 * A valid CSS selector, which will be passed to `querySelectorAll`.
22248 * @param {Element|String} [context=document]
22249 * A DOM element within which to query. Can also be a selector
22250 * string in which case the first matching element will be used
22251 * as context. If missing (or no element matches selector), falls
22252 * back to `document`.
22254 * @return {NodeList}
22255 * A element list of elements that were found. Will be empty if none were found.
22258 var $$ = exports.$$ = createQuerier('querySelectorAll');
22260 },{"85":85,"86":86,"88":88,"94":94,"95":95,"98":98}],82:[function(_dereq_,module,exports){
22263 exports.__esModule = true;
22264 exports.fixEvent = fixEvent;
22267 exports.trigger = trigger;
22270 var _dom = _dereq_(81);
22272 var Dom = _interopRequireWildcard(_dom);
22274 var _guid = _dereq_(85);
22276 var Guid = _interopRequireWildcard(_guid);
22278 var _log = _dereq_(86);
22280 var _log2 = _interopRequireDefault(_log);
22282 var _window = _dereq_(95);
22284 var _window2 = _interopRequireDefault(_window);
22286 var _document = _dereq_(94);
22288 var _document2 = _interopRequireDefault(_document);
22290 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
22292 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; } }
22295 * Clean up the listener cache and dispatchers
22297 * @param {Element|Object} elem
22298 * Element to clean up
22300 * @param {string} type
22301 * Type of event to clean up
22303 function _cleanUpEvents(elem, type) {
22304 var data = Dom.getElData(elem);
22306 // Remove the events of a particular type if there are none left
22307 if (data.handlers[type].length === 0) {
22308 delete data.handlers[type];
22309 // data.handlers[type] = null;
22310 // Setting to null was causing an error with data.handlers
22312 // Remove the meta-handler from the element
22313 if (elem.removeEventListener) {
22314 elem.removeEventListener(type, data.dispatcher, false);
22315 } else if (elem.detachEvent) {
22316 elem.detachEvent('on' + type, data.dispatcher);
22320 // Remove the events object if there are no types left
22321 if (Object.getOwnPropertyNames(data.handlers).length <= 0) {
22322 delete data.handlers;
22323 delete data.dispatcher;
22324 delete data.disabled;
22327 // Finally remove the element data if there is no data left
22328 if (Object.getOwnPropertyNames(data).length === 0) {
22329 Dom.removeElData(elem);
22334 * Loops through an array of event types and calls the requested method for each type.
22336 * @param {Function} fn
22337 * The event method we want to use.
22339 * @param {Element|Object} elem
22340 * Element or object to bind listeners to
22342 * @param {string} type
22343 * Type of event to bind to.
22345 * @param {EventTarget~EventListener} callback
22349 * @file events.js. An Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/)
22350 * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible)
22351 * This should work very similarly to jQuery's events, however it's based off the book version which isn't as
22352 * robust as jquery's, so there's probably some differences.
22357 function _handleMultipleEvents(fn, elem, types, callback) {
22358 types.forEach(function (type) {
22359 // Call the event method for each one of the types
22360 fn(elem, type, callback);
22365 * Fix a native event to have standard property values
22367 * @param {Object} event
22368 * Event object to fix.
22371 * Fixed event object.
22373 function fixEvent(event) {
22375 function returnTrue() {
22379 function returnFalse() {
22383 // Test if fixing up is needed
22384 // Used to check if !event.stopPropagation instead of isPropagationStopped
22385 // But native events return true for stopPropagation, but don't have
22386 // other expected methods like isPropagationStopped. Seems to be a problem
22387 // with the Javascript Ninja code. So we're just overriding all events now.
22388 if (!event || !event.isPropagationStopped) {
22389 var old = event || _window2['default'].event;
22392 // Clone the old object so that we can modify the values event = {};
22393 // IE8 Doesn't like when you mess with native event properties
22394 // Firefox returns false for event.hasOwnProperty('type') and other props
22395 // which makes copying more difficult.
22396 // TODO: Probably best to create a whitelist of event props
22397 for (var key in old) {
22398 // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
22399 // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation
22400 // and webkitMovementX/Y
22401 if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') {
22402 // Chrome 32+ warns if you try to copy deprecated returnValue, but
22403 // we still want to if preventDefault isn't supported (IE8).
22404 if (!(key === 'returnValue' && old.preventDefault)) {
22405 event[key] = old[key];
22410 // The event occurred on this element
22411 if (!event.target) {
22412 event.target = event.srcElement || _document2['default'];
22415 // Handle which other element the event is related to
22416 if (!event.relatedTarget) {
22417 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
22420 // Stop the default browser action
22421 event.preventDefault = function () {
22422 if (old.preventDefault) {
22423 old.preventDefault();
22425 event.returnValue = false;
22426 old.returnValue = false;
22427 event.defaultPrevented = true;
22430 event.defaultPrevented = false;
22432 // Stop the event from bubbling
22433 event.stopPropagation = function () {
22434 if (old.stopPropagation) {
22435 old.stopPropagation();
22437 event.cancelBubble = true;
22438 old.cancelBubble = true;
22439 event.isPropagationStopped = returnTrue;
22442 event.isPropagationStopped = returnFalse;
22444 // Stop the event from bubbling and executing other handlers
22445 event.stopImmediatePropagation = function () {
22446 if (old.stopImmediatePropagation) {
22447 old.stopImmediatePropagation();
22449 event.isImmediatePropagationStopped = returnTrue;
22450 event.stopPropagation();
22453 event.isImmediatePropagationStopped = returnFalse;
22455 // Handle mouse position
22456 if (event.clientX !== null && event.clientX !== undefined) {
22457 var doc = _document2['default'].documentElement;
22458 var body = _document2['default'].body;
22460 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
22461 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
22464 // Handle key presses
22465 event.which = event.charCode || event.keyCode;
22467 // Fix button for mouse clicks:
22468 // 0 == left; 1 == middle; 2 == right
22469 if (event.button !== null && event.button !== undefined) {
22471 // The following is disabled because it does not pass videojs-standard
22473 /* eslint-disable */
22474 event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0;
22475 /* eslint-enable */
22479 // Returns fixed-up instance
22484 * Add an event listener to element
22485 * It stores the handler function in a separate cache object
22486 * and adds a generic handler to the element's event,
22487 * along with a unique id (guid) to the element.
22489 * @param {Element|Object} elem
22490 * Element or object to bind listeners to
22492 * @param {string|string[]} type
22493 * Type of event to bind to.
22495 * @param {EventTarget~EventListener} fn
22498 function on(elem, type, fn) {
22499 if (Array.isArray(type)) {
22500 return _handleMultipleEvents(on, elem, type, fn);
22503 var data = Dom.getElData(elem);
22505 // We need a place to store all our handler data
22506 if (!data.handlers) {
22507 data.handlers = {};
22510 if (!data.handlers[type]) {
22511 data.handlers[type] = [];
22515 fn.guid = Guid.newGUID();
22518 data.handlers[type].push(fn);
22520 if (!data.dispatcher) {
22521 data.disabled = false;
22523 data.dispatcher = function (event, hash) {
22525 if (data.disabled) {
22529 event = fixEvent(event);
22531 var handlers = data.handlers[event.type];
22534 // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.
22535 var handlersCopy = handlers.slice(0);
22537 for (var m = 0, n = handlersCopy.length; m < n; m++) {
22538 if (event.isImmediatePropagationStopped()) {
22542 handlersCopy[m].call(elem, event, hash);
22544 _log2['default'].error(e);
22552 if (data.handlers[type].length === 1) {
22553 if (elem.addEventListener) {
22554 elem.addEventListener(type, data.dispatcher, false);
22555 } else if (elem.attachEvent) {
22556 elem.attachEvent('on' + type, data.dispatcher);
22562 * Removes event listeners from an element
22564 * @param {Element|Object} elem
22565 * Object to remove listeners from.
22567 * @param {string|string[]} [type]
22568 * Type of listener to remove. Don't include to remove all events from element.
22570 * @param {EventTarget~EventListener} [fn]
22571 * Specific listener to remove. Don't include to remove listeners for an event
22574 function off(elem, type, fn) {
22575 // Don't want to add a cache object through getElData if not needed
22576 if (!Dom.hasElData(elem)) {
22580 var data = Dom.getElData(elem);
22582 // If no events exist, nothing to unbind
22583 if (!data.handlers) {
22587 if (Array.isArray(type)) {
22588 return _handleMultipleEvents(off, elem, type, fn);
22591 // Utility function
22592 var removeType = function removeType(t) {
22593 data.handlers[t] = [];
22594 _cleanUpEvents(elem, t);
22597 // Are we removing all bound events?
22599 for (var t in data.handlers) {
22605 var handlers = data.handlers[type];
22607 // If no handlers exist, nothing to unbind
22612 // If no listener was provided, remove all listeners for type
22618 // We're only removing a single handler
22620 for (var n = 0; n < handlers.length; n++) {
22621 if (handlers[n].guid === fn.guid) {
22622 handlers.splice(n--, 1);
22627 _cleanUpEvents(elem, type);
22631 * Trigger an event for an element
22633 * @param {Element|Object} elem
22634 * Element to trigger an event on
22636 * @param {EventTarget~Event|string} event
22637 * A string (the type) or an event object with a type attribute
22639 * @param {Object} [hash]
22640 * data hash to pass along with the event
22642 * @return {boolean|undefined}
22643 * - Returns the opposite of `defaultPrevented` if default was prevented
22644 * - Otherwise returns undefined
22646 function trigger(elem, event, hash) {
22647 // Fetches element data and a reference to the parent (for bubbling).
22648 // Don't want to add a data object to cache for every parent,
22649 // so checking hasElData first.
22650 var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {};
22651 var parent = elem.parentNode || elem.ownerDocument;
22652 // type = event.type || event,
22655 // If an event name was passed as a string, creates an event out of it
22656 if (typeof event === 'string') {
22657 event = { type: event, target: elem };
22659 // Normalizes the event properties.
22660 event = fixEvent(event);
22662 // If the passed element has a dispatcher, executes the established handlers.
22663 if (elemData.dispatcher) {
22664 elemData.dispatcher.call(elem, event, hash);
22667 // Unless explicitly stopped or the event does not bubble (e.g. media events)
22668 // recursively calls this function to bubble the event up the DOM.
22669 if (parent && !event.isPropagationStopped() && event.bubbles === true) {
22670 trigger.call(null, parent, event, hash);
22672 // If at the top of the DOM, triggers the default action unless disabled.
22673 } else if (!parent && !event.defaultPrevented) {
22674 var targetData = Dom.getElData(event.target);
22676 // Checks if the target has a default action for this event.
22677 if (event.target[event.type]) {
22678 // Temporarily disables event dispatching on the target as we have already executed the handler.
22679 targetData.disabled = true;
22680 // Executes the default action.
22681 if (typeof event.target[event.type] === 'function') {
22682 event.target[event.type]();
22684 // Re-enables event dispatching.
22685 targetData.disabled = false;
22689 // Inform the triggerer if the default was prevented by returning false
22690 return !event.defaultPrevented;
22694 * Trigger a listener only once for an event
22696 * @param {Element|Object} elem
22697 * Element or object to bind to.
22699 * @param {string|string[]} type
22700 * Name/type of event
22702 * @param {Event~EventListener} fn
22703 * Event Listener function
22705 function one(elem, type, fn) {
22706 if (Array.isArray(type)) {
22707 return _handleMultipleEvents(one, elem, type, fn);
22709 var func = function func() {
22710 off(elem, type, func);
22711 fn.apply(this, arguments);
22714 // copy the guid to the new function so it can removed using the original function's ID
22715 func.guid = fn.guid = fn.guid || Guid.newGUID();
22716 on(elem, type, func);
22719 },{"81":81,"85":85,"86":86,"94":94,"95":95}],83:[function(_dereq_,module,exports){
22722 exports.__esModule = true;
22723 exports.throttle = exports.bind = undefined;
22725 var _guid = _dereq_(85);
22728 * Bind (a.k.a proxy or Context). A simple method for changing the context of a function
22729 * It also stores a unique id on the function so it can be easily removed from events.
22731 * @param {Mixed} context
22732 * The object to bind as scope.
22734 * @param {Function} fn
22735 * The function to be bound to a scope.
22737 * @param {number} [uid]
22738 * An optional unique ID for the function to be set
22740 * @return {Function}
22741 * The new function that will be bound into the context given
22743 var bind = exports.bind = function bind(context, fn, uid) {
22744 // Make sure the function has a unique ID
22746 fn.guid = (0, _guid.newGUID)();
22749 // Create the new function that changes the context
22750 var bound = function bound() {
22751 return fn.apply(context, arguments);
22754 // Allow for the ability to individualize this function
22755 // Needed in the case where multiple objects might share the same prototype
22756 // IF both items add an event listener with the same function, then you try to remove just one
22757 // it will remove both because they both have the same guid.
22758 // when using this, you need to use the bind method when you remove the listener as well.
22759 // currently used in text tracks
22760 bound.guid = uid ? uid + '_' + fn.guid : fn.guid;
22766 * Wraps the given function, `fn`, with a new function that only invokes `fn`
22767 * at most once per every `wait` milliseconds.
22769 * @param {Function} fn
22770 * The function to be throttled.
22772 * @param {Number} wait
22773 * The number of milliseconds by which to throttle.
22775 * @return {Function}
22781 var throttle = exports.throttle = function throttle(fn, wait) {
22782 var last = Date.now();
22784 var throttled = function throttled() {
22785 var now = Date.now();
22787 if (now - last >= wait) {
22788 fn.apply(undefined, arguments);
22796 },{"85":85}],84:[function(_dereq_,module,exports){
22799 exports.__esModule = true;
22801 * @file format-time.js
22802 * @module Format-time
22806 * Format seconds as a time string, H:MM:SS or M:SS. Supplying a guide (in seconds)
22807 * will force a number of leading zeros to cover the length of the guide.
22809 * @param {number} seconds
22810 * Number of seconds to be turned into a string
22812 * @param {number} guide
22813 * Number (in seconds) to model the string after
22816 * Time formatted as H:MM:SS or M:SS
22818 function formatTime(seconds) {
22819 var guide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : seconds;
22821 seconds = seconds < 0 ? 0 : seconds;
22822 var s = Math.floor(seconds % 60);
22823 var m = Math.floor(seconds / 60 % 60);
22824 var h = Math.floor(seconds / 3600);
22825 var gm = Math.floor(guide / 60 % 60);
22826 var gh = Math.floor(guide / 3600);
22828 // handle invalid times
22829 if (isNaN(seconds) || seconds === Infinity) {
22830 // '-' is false for all relational operators (e.g. <, >=) so this setting
22831 // will add the minimum number of fields specified by the guide
22835 // Check if we need to show hours
22836 h = h > 0 || gh > 0 ? h + ':' : '';
22838 // If hours are showing, we may need to add a leading zero.
22839 // Always show at least one digit of minutes.
22840 m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':';
22842 // Check if leading zero is need for seconds
22843 s = s < 10 ? '0' + s : s;
22848 exports['default'] = formatTime;
22850 },{}],85:[function(_dereq_,module,exports){
22853 exports.__esModule = true;
22854 exports.newGUID = newGUID;
22861 * Unique ID for an element or function
22867 * Get a unique auto-incrementing ID by number that has not been returned before.
22872 function newGUID() {
22876 },{}],86:[function(_dereq_,module,exports){
22879 exports.__esModule = true;
22880 exports.logByType = undefined;
22882 var _window = _dereq_(95);
22884 var _window2 = _interopRequireDefault(_window);
22886 var _browser = _dereq_(78);
22888 var _obj = _dereq_(88);
22890 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
22895 * Log messages to the console and history based on the type of message
22897 * @param {string} type
22898 * The name of the console method to use.
22900 * @param {Array} args
22901 * The arguments to be passed to the matching console method.
22903 * @param {boolean} [stringify]
22904 * By default, only old IEs should get console argument stringification,
22905 * but this is exposed as a parameter to facilitate testing.
22911 var logByType = exports.logByType = function logByType(type, args) {
22912 var stringify = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : !!_browser.IE_VERSION && _browser.IE_VERSION < 11;
22915 if (type !== 'log') {
22917 // add the type to the front of the message when it's not "log"
22918 args.unshift(type.toUpperCase() + ':');
22922 log.history.push(args);
22924 // add console prefix after adding to history
22925 args.unshift('VIDEOJS:');
22927 // If there's no console then don't try to output messages, but they will
22928 // still be stored in `log.history`.
22930 // Was setting these once outside of this function, but containing them
22931 // in the function makes it easier to test cases where console doesn't exist
22932 // when the module is executed.
22933 var fn = _window2['default'].console && _window2['default'].console[type];
22935 // Bail out if there's no console.
22940 // IEs previous to 11 log objects uselessly as "[object Object]"; so, JSONify
22941 // objects and arrays for those less-capable browsers.
22943 args = args.map(function (a) {
22944 if ((0, _obj.isObject)(a) || Array.isArray(a)) {
22946 return JSON.stringify(a);
22952 // Cast to string before joining, so we get null and undefined explicitly
22953 // included in output (as we would in a modern console).
22958 // Old IE versions do not allow .apply() for console methods (they are
22959 // reported as objects rather than functions).
22963 fn[Array.isArray(args) ? 'apply' : 'call'](_window2['default'].console, args);
22968 * Log plain debug messages
22970 * @param {Mixed[]} args
22971 * One or more messages or objects that should be logged.
22973 log = function log() {
22974 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
22975 args[_key] = arguments[_key];
22978 logByType('log', args);
22982 * Keep a history of log messages
22989 * Log error messages
22991 * @param {Mixed[]} args
22992 * One or more messages or objects that should be logged as an error
22994 log.error = function () {
22995 for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
22996 args[_key2] = arguments[_key2];
22999 return logByType('error', args);
23003 * Log warning messages
23005 * @param {Mixed[]} args
23006 * One or more messages or objects that should be logged as a warning.
23008 log.warn = function () {
23009 for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
23010 args[_key3] = arguments[_key3];
23013 return logByType('warn', args);
23016 exports['default'] = log;
23018 },{"78":78,"88":88,"95":95}],87:[function(_dereq_,module,exports){
23021 exports.__esModule = true;
23022 exports['default'] = mergeOptions;
23024 var _obj = _dereq_(88);
23027 * Deep-merge one or more options objects, recursively merging **only** plain
23028 * object properties.
23030 * @param {Object[]} sources
23031 * One or more objects to merge into a new object.
23033 * @returns {Object}
23034 * A new object that is the merged result of all sources.
23036 function mergeOptions() {
23039 for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {
23040 sources[_key] = arguments[_key];
23043 sources.forEach(function (source) {
23048 (0, _obj.each)(source, function (value, key) {
23049 if (!(0, _obj.isPlain)(value)) {
23050 result[key] = value;
23054 if (!(0, _obj.isPlain)(result[key])) {
23058 result[key] = mergeOptions(result[key], value);
23064 * @file merge-options.js
23065 * @module merge-options
23068 },{"88":88}],88:[function(_dereq_,module,exports){
23071 exports.__esModule = true;
23073 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; };
23075 exports.each = each;
23076 exports.reduce = reduce;
23077 exports.assign = assign;
23078 exports.isObject = isObject;
23079 exports.isPlain = isPlain;
23086 * @callback obj:EachCallback
23088 * @param {Mixed} value
23089 * The current key for the object that is being iterated over.
23091 * @param {string} key
23092 * The current key-value for object that is being iterated over
23096 * @callback obj:ReduceCallback
23098 * @param {Mixed} accum
23099 * The value that is accumulating over the reduce loop.
23101 * @param {Mixed} value
23102 * The current key for the object that is being iterated over.
23104 * @param {string} key
23105 * The current key-value for object that is being iterated over
23108 * The new accumulated value.
23110 var toString = Object.prototype.toString;
23113 * Get the keys of an Object
23116 * The Object to get the keys from
23118 * @return {string[]}
23119 * An array of the keys from the object. Returns an empty array if the
23120 * object passed in was invalid or had no keys.
23124 var keys = function keys(object) {
23125 return isObject(object) ? Object.keys(object) : [];
23129 * Array-like iteration for objects.
23131 * @param {Object} object
23132 * The object to iterate over
23134 * @param {obj:EachCallback} fn
23135 * The callback function which is called for each key in the object.
23137 function each(object, fn) {
23138 keys(object).forEach(function (key) {
23139 return fn(object[key], key);
23144 * Array-like reduce for objects.
23146 * @param {Object} object
23147 * The Object that you want to reduce.
23149 * @param {Function} fn
23150 * A callback function which is called for each key in the object. It
23151 * receives the accumulated value and the per-iteration value and key
23154 * @param {Mixed} [initial = 0]
23158 * The final accumulated value.
23160 function reduce(object, fn) {
23161 var initial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
23163 return keys(object).reduce(function (accum, key) {
23164 return fn(accum, object[key], key);
23169 * Object.assign-style object shallow merge/extend.
23171 * @param {Object} target
23172 * @param {Object} ...sources
23175 function assign(target) {
23176 for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
23177 sources[_key - 1] = arguments[_key];
23180 if (Object.assign) {
23181 return Object.assign.apply(Object, [target].concat(sources));
23184 sources.forEach(function (source) {
23189 each(source, function (value, key) {
23190 target[key] = value;
23198 * Returns whether a value is an object of any kind - including DOM nodes,
23199 * arrays, regular expressions, etc. Not functions, though.
23201 * This avoids the gotcha where using `typeof` on a `null` value
23202 * results in `'object'`.
23204 * @param {Object} value
23205 * @return {Boolean}
23207 function isObject(value) {
23208 return !!value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object';
23212 * Returns whether an object appears to be a "plain" object - that is, a
23213 * direct instance of `Object`.
23215 * @param {Object} value
23216 * @return {Boolean}
23218 function isPlain(value) {
23219 return isObject(value) && toString.call(value) === '[object Object]' && value.constructor === Object;
23222 },{}],89:[function(_dereq_,module,exports){
23225 exports.__esModule = true;
23226 exports.setTextContent = exports.createStyleElement = undefined;
23228 var _document = _dereq_(94);
23230 var _document2 = _interopRequireDefault(_document);
23232 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23235 * Create a DOM syle element given a className for it.
23237 * @param {string} className
23238 * The className to add to the created style element.
23240 * @return {Element}
23241 * The element that was created.
23243 var createStyleElement = exports.createStyleElement = function createStyleElement(className) {
23244 var style = _document2['default'].createElement('style');
23246 style.className = className;
23252 * Add text to a DOM element.
23254 * @param {Element} el
23255 * The Element to add text content to.
23257 * @param {string} content
23258 * The text to add to the element.
23261 * @file stylesheet.js
23262 * @module stylesheet
23264 var setTextContent = exports.setTextContent = function setTextContent(el, content) {
23265 if (el.styleSheet) {
23266 el.styleSheet.cssText = content;
23268 el.textContent = content;
23272 },{"94":94}],90:[function(_dereq_,module,exports){
23275 exports.__esModule = true;
23276 exports.createTimeRange = undefined;
23277 exports.createTimeRanges = createTimeRanges;
23279 var _log = _dereq_(86);
23281 var _log2 = _interopRequireDefault(_log);
23283 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23286 * Returns the time for the specified index at the start or end
23287 * of a TimeRange object.
23289 * @function time-ranges:indexFunction
23291 * @param {number} [index=0]
23292 * The range number to return the time for.
23295 * The time that offset at the specified index.
23297 * @depricated index must be set to a value, in the future this will throw an error.
23301 * An object that contains ranges of time for various reasons.
23303 * @typedef {Object} TimeRange
23305 * @property {number} length
23306 * The number of time ranges represented by this Object
23308 * @property {time-ranges:indexFunction} start
23309 * Returns the time offset at which a specified time range begins.
23311 * @property {time-ranges:indexFunction} end
23312 * Returns the time offset at which a specified time range begins.
23314 * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges
23318 * Check if any of the time ranges are over the maximum index.
23320 * @param {string} fnName
23321 * The function name to use for logging
23323 * @param {number} index
23324 * The index to check
23326 * @param {number} maxIndex
23327 * The maximum possible index
23329 * @throws {Error} if the timeRanges provided are over the maxIndex
23331 function rangeCheck(fnName, index, maxIndex) {
23332 if (index < 0 || index > maxIndex) {
23333 throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is greater than or equal to the maximum bound (' + maxIndex + ').');
23338 * Check if any of the time ranges are over the maximum index.
23340 * @param {string} fnName
23341 * The function name to use for logging
23343 * @param {string} valueIndex
23344 * The proprety that should be used to get the time. should be 'start' or 'end'
23346 * @param {Array} ranges
23347 * An array of time ranges
23349 * @param {Array} [rangeIndex=0]
23350 * The index to start the search at
23353 * The time that offset at the specified index.
23356 * @depricated rangeIndex must be set to a value, in the future this will throw an error.
23357 * @throws {Error} if rangeIndex is more than the length of ranges
23360 * @file time-ranges.js
23361 * @module time-ranges
23363 function getRange(fnName, valueIndex, ranges, rangeIndex) {
23364 if (rangeIndex === undefined) {
23365 _log2['default'].warn('DEPRECATED: Function \'' + fnName + '\' on \'TimeRanges\' called without an index argument.');
23368 rangeCheck(fnName, rangeIndex, ranges.length - 1);
23369 return ranges[rangeIndex][valueIndex];
23373 * Create a time range object givent ranges of time.
23375 * @param {Array} [ranges]
23376 * An array of time ranges.
23378 function createTimeRangesObj(ranges) {
23379 if (ranges === undefined || ranges.length === 0) {
23382 start: function start() {
23383 throw new Error('This TimeRanges object is empty');
23385 end: function end() {
23386 throw new Error('This TimeRanges object is empty');
23391 length: ranges.length,
23392 start: getRange.bind(null, 'start', 0, ranges),
23393 end: getRange.bind(null, 'end', 1, ranges)
23398 * Should create a fake `TimeRange` object which mimics an HTML5 time range instance.
23400 * @param {number|Array} start
23401 * The start of a single range or an array of ranges
23403 * @param {number} end
23404 * The end of a single range.
23408 function createTimeRanges(start, end) {
23409 if (Array.isArray(start)) {
23410 return createTimeRangesObj(start);
23411 } else if (start === undefined || end === undefined) {
23412 return createTimeRangesObj();
23414 return createTimeRangesObj([[start, end]]);
23417 exports.createTimeRange = createTimeRanges;
23419 },{"86":86}],91:[function(_dereq_,module,exports){
23422 exports.__esModule = true;
23424 * @file to-title-case.js
23425 * @module to-title-case
23429 * Uppercase the first letter of a string.
23431 * @param {string} string
23432 * String to be uppercased
23435 * The string with an uppercased first letter
23437 function toTitleCase(string) {
23438 if (typeof string !== 'string') {
23442 return string.charAt(0).toUpperCase() + string.slice(1);
23445 exports['default'] = toTitleCase;
23447 },{}],92:[function(_dereq_,module,exports){
23450 exports.__esModule = true;
23451 exports.isCrossOrigin = exports.getFileExtension = exports.getAbsoluteURL = exports.parseUrl = undefined;
23453 var _document = _dereq_(94);
23455 var _document2 = _interopRequireDefault(_document);
23457 var _window = _dereq_(95);
23459 var _window2 = _interopRequireDefault(_window);
23461 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23464 * @typedef {Object} url:URLObject
23466 * @property {string} protocol
23467 * The protocol of the url that was parsed.
23469 * @property {string} hostname
23470 * The hostname of the url that was parsed.
23472 * @property {string} port
23473 * The port of the url that was parsed.
23475 * @property {string} pathname
23476 * The pathname of the url that was parsed.
23478 * @property {string} search
23479 * The search query of the url that was parsed.
23481 * @property {string} hash
23482 * The hash of the url that was parsed.
23484 * @property {string} host
23485 * The host of the url that was parsed.
23489 * Resolve and parse the elements of a URL.
23491 * @param {String} url
23494 * @return {url:URLObject}
23495 * An object of url details
23501 var parseUrl = exports.parseUrl = function parseUrl(url) {
23502 var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host'];
23504 // add the url to an anchor and let the browser parse the URL
23505 var a = _document2['default'].createElement('a');
23509 // IE8 (and 9?) Fix
23510 // ie8 doesn't parse the URL correctly until the anchor is actually
23511 // added to the body, and an innerHTML is needed to trigger the parsing
23512 var addToBody = a.host === '' && a.protocol !== 'file:';
23516 div = _document2['default'].createElement('div');
23517 div.innerHTML = '<a href="' + url + '"></a>';
23518 a = div.firstChild;
23519 // prevent the div from affecting layout
23520 div.setAttribute('style', 'display:none; position:absolute;');
23521 _document2['default'].body.appendChild(div);
23524 // Copy the specific URL properties to a new object
23525 // This is also needed for IE8 because the anchor loses its
23526 // properties when it's removed from the dom
23529 for (var i = 0; i < props.length; i++) {
23530 details[props[i]] = a[props[i]];
23533 // IE9 adds the port to the host property unlike everyone else. If
23534 // a port identifier is added for standard ports, strip it.
23535 if (details.protocol === 'http:') {
23536 details.host = details.host.replace(/:80$/, '');
23539 if (details.protocol === 'https:') {
23540 details.host = details.host.replace(/:443$/, '');
23544 _document2['default'].body.removeChild(div);
23551 * Get absolute version of relative URL. Used to tell flash correct URL.
23554 * @param {string} url
23555 * URL to make absolute
23560 * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
23562 var getAbsoluteURL = exports.getAbsoluteURL = function getAbsoluteURL(url) {
23563 // Check if absolute URL
23564 if (!url.match(/^https?:\/\//)) {
23565 // Convert to absolute URL. Flash hosted off-site needs an absolute URL.
23566 var div = _document2['default'].createElement('div');
23568 div.innerHTML = '<a href="' + url + '">x</a>';
23569 url = div.firstChild.href;
23576 * Returns the extension of the passed file name. It will return an empty string
23577 * if passed an invalid path.
23579 * @param {string} path
23580 * The fileName path like '/path/to/file.mp4'
23582 * @returns {string}
23583 * The extension in lower case or an empty string if no
23584 * extension could be found.
23586 var getFileExtension = exports.getFileExtension = function getFileExtension(path) {
23587 if (typeof path === 'string') {
23588 var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i;
23589 var pathParts = splitPathRe.exec(path);
23592 return pathParts.pop().toLowerCase();
23600 * Returns whether the url passed is a cross domain request or not.
23602 * @param {string} url
23603 * The url to check.
23605 * @return {boolean}
23606 * Whether it is a cross domain request or not.
23608 var isCrossOrigin = exports.isCrossOrigin = function isCrossOrigin(url) {
23609 var winLoc = _window2['default'].location;
23610 var urlInfo = parseUrl(url);
23612 // IE8 protocol relative urls will return ':' for protocol
23613 var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol;
23615 // Check if url is for another domain/origin
23616 // IE8 doesn't know location.origin, so we won't rely on it here
23617 var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host;
23619 return crossOrigin;
23622 },{"94":94,"95":95}],93:[function(_dereq_,module,exports){
23625 exports.__esModule = true;
23627 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; }; /**
23632 /* global define */
23634 // Include the built-in techs
23637 var _window = _dereq_(95);
23639 var _window2 = _interopRequireDefault(_window);
23641 var _document = _dereq_(94);
23643 var _document2 = _interopRequireDefault(_document);
23645 var _setup = _dereq_(56);
23647 var setup = _interopRequireWildcard(_setup);
23649 var _stylesheet = _dereq_(89);
23651 var stylesheet = _interopRequireWildcard(_stylesheet);
23653 var _component = _dereq_(5);
23655 var _component2 = _interopRequireDefault(_component);
23657 var _eventTarget = _dereq_(42);
23659 var _eventTarget2 = _interopRequireDefault(_eventTarget);
23661 var _events = _dereq_(82);
23663 var Events = _interopRequireWildcard(_events);
23665 var _player = _dereq_(51);
23667 var _player2 = _interopRequireDefault(_player);
23669 var _plugins = _dereq_(52);
23671 var _plugins2 = _interopRequireDefault(_plugins);
23673 var _mergeOptions2 = _dereq_(87);
23675 var _mergeOptions3 = _interopRequireDefault(_mergeOptions2);
23677 var _fn = _dereq_(83);
23679 var Fn = _interopRequireWildcard(_fn);
23681 var _textTrack = _dereq_(72);
23683 var _textTrack2 = _interopRequireDefault(_textTrack);
23685 var _audioTrack = _dereq_(64);
23687 var _audioTrack2 = _interopRequireDefault(_audioTrack);
23689 var _videoTrack = _dereq_(77);
23691 var _videoTrack2 = _interopRequireDefault(_videoTrack);
23693 var _timeRanges = _dereq_(90);
23695 var _formatTime = _dereq_(84);
23697 var _formatTime2 = _interopRequireDefault(_formatTime);
23699 var _log = _dereq_(86);
23701 var _log2 = _interopRequireDefault(_log);
23703 var _dom = _dereq_(81);
23705 var Dom = _interopRequireWildcard(_dom);
23707 var _browser = _dereq_(78);
23709 var browser = _interopRequireWildcard(_browser);
23711 var _url = _dereq_(92);
23713 var Url = _interopRequireWildcard(_url);
23715 var _obj = _dereq_(88);
23717 var _computedStyle = _dereq_(80);
23719 var _computedStyle2 = _interopRequireDefault(_computedStyle);
23721 var _extend = _dereq_(43);
23723 var _extend2 = _interopRequireDefault(_extend);
23725 var _xhr = _dereq_(99);
23727 var _xhr2 = _interopRequireDefault(_xhr);
23729 var _tech = _dereq_(62);
23731 var _tech2 = _interopRequireDefault(_tech);
23733 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; } }
23735 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
23737 // HTML5 Element Shim for IE8
23738 if (typeof HTMLVideoElement === 'undefined' && Dom.isReal()) {
23739 _document2['default'].createElement('video');
23740 _document2['default'].createElement('audio');
23741 _document2['default'].createElement('track');
23745 * Doubles as the main function for users to create a player instance and also
23746 * the main library object.
23747 * The `videojs` function can be used to initialize or retrieve a player.
23749 * @param {string|Element} id
23750 * Video element or video element ID
23752 * @param {Object} [options]
23753 * Optional options object for config/settings
23755 * @param {Component~ReadyCallback} [ready]
23756 * Optional ready callback
23759 * A player instance
23763 function videojs(id, options, ready) {
23766 // Allow for element or ID to be passed in
23768 if (typeof id === 'string') {
23770 // Adjust for jQuery ID syntax
23771 if (id.indexOf('#') === 0) {
23775 // If a player instance has already been created for this ID return it.
23776 if (videojs.getPlayers()[id]) {
23778 // If options or ready funtion are passed, warn
23780 _log2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.');
23784 videojs.getPlayers()[id].ready(ready);
23787 return videojs.getPlayers()[id];
23790 // Otherwise get element for ID
23791 tag = Dom.getEl(id);
23793 // ID is a media element
23798 // Check for a useable element
23799 // re: nodeName, could be a box div also
23800 if (!tag || !tag.nodeName) {
23801 throw new TypeError('The element or ID supplied is not valid. (videojs)');
23804 // Element may have a player attr referring to an already created player instance.
23805 // If so return that otherwise set up a new player below
23806 if (tag.player || _player2['default'].players[tag.playerId]) {
23807 return tag.player || _player2['default'].players[tag.playerId];
23810 options = options || {};
23812 videojs.hooks('beforesetup').forEach(function (hookFunction) {
23813 var opts = hookFunction(tag, (0, _mergeOptions3['default'])(options));
23815 if (!(0, _obj.isObject)(opts) || Array.isArray(opts)) {
23816 _log2['default'].error('please return an object in beforesetup hooks');
23820 options = (0, _mergeOptions3['default'])(options, opts);
23823 var PlayerComponent = _component2['default'].getComponent('Player');
23824 // If not, set up a new player
23825 var player = new PlayerComponent(tag, options, ready);
23827 videojs.hooks('setup').forEach(function (hookFunction) {
23828 return hookFunction(player);
23835 * An Object that contains lifecycle hooks as keys which point to an array
23836 * of functions that are run when a lifecycle is triggered
23838 videojs.hooks_ = {};
23841 * Get a list of hooks for a specific lifecycle
23843 * @param {string} type
23844 * the lifecyle to get hooks from
23846 * @param {Function} [fn]
23847 * Optionally add a hook to the lifecycle that your are getting.
23850 * an array of hooks, or an empty array if there are none.
23852 videojs.hooks = function (type, fn) {
23853 videojs.hooks_[type] = videojs.hooks_[type] || [];
23855 videojs.hooks_[type] = videojs.hooks_[type].concat(fn);
23857 return videojs.hooks_[type];
23861 * Add a function hook to a specific videojs lifecycle.
23863 * @param {string} type
23864 * the lifecycle to hook the function to.
23866 * @param {Function|Function[]}
23867 * The function or array of functions to attach.
23869 videojs.hook = function (type, fn) {
23870 videojs.hooks(type, fn);
23874 * Remove a hook from a specific videojs lifecycle.
23876 * @param {string} type
23877 * the lifecycle that the function hooked to
23879 * @param {Function} fn
23880 * The hooked function to remove
23882 * @return {boolean}
23883 * The function that was removed or undef
23885 videojs.removeHook = function (type, fn) {
23886 var index = videojs.hooks(type).indexOf(fn);
23892 videojs.hooks_[type] = videojs.hooks_[type].slice();
23893 videojs.hooks_[type].splice(index, 1);
23898 // Add default styles
23899 if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true && Dom.isReal()) {
23900 var style = Dom.$('.vjs-styles-defaults');
23903 style = stylesheet.createStyleElement('vjs-styles-defaults');
23904 var head = Dom.$('head');
23907 head.insertBefore(style, head.firstChild);
23909 stylesheet.setTextContent(style, '\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n ');
23913 // Run Auto-load players
23914 // You have to wait at least once in case this script is loaded after your
23915 // video in the DOM (weird behavior only with minified version)
23916 setup.autoSetupTimeout(1, videojs);
23919 * Current software version. Follows semver.
23923 videojs.VERSION = '5.19.2';
23926 * The global options object. These are the settings that take effect
23927 * if no overrides are specified when the player is created.
23931 videojs.options = _player2['default'].prototype.options_;
23934 * Get an object with the currently created players, keyed by player ID
23937 * The created players
23939 videojs.getPlayers = function () {
23940 return _player2['default'].players;
23944 * Expose players object.
23946 * @memberOf videojs
23947 * @property {Object} players
23949 videojs.players = _player2['default'].players;
23952 * Get a component class object by name
23954 * @borrows Component.getComponent as videojs.getComponent
23956 videojs.getComponent = _component2['default'].getComponent;
23959 * Register a component so it can referred to by name. Used when adding to other
23960 * components, either through addChild `component.addChild('myComponent')` or through
23961 * default children options `{ children: ['myComponent'] }`.
23963 * > NOTE: You could also just initialize the component before adding.
23964 * `component.addChild(new MyComponent());`
23966 * @param {string} name
23967 * The class name of the component
23969 * @param {Component} comp
23970 * The component class
23972 * @return {Component}
23973 * The newly registered component
23975 videojs.registerComponent = function (name, comp) {
23976 if (_tech2['default'].isTech(comp)) {
23977 _log2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)');
23980 _component2['default'].registerComponent.call(_component2['default'], name, comp);
23984 * Get a Tech class object by name
23986 * @borrows Tech.getTech as videojs.getTech
23988 videojs.getTech = _tech2['default'].getTech;
23991 * Register a Tech so it can referred to by name.
23992 * This is used in the tech order for the player.
23994 * @borrows Tech.registerTech as videojs.registerTech
23996 videojs.registerTech = _tech2['default'].registerTech;
23999 * A suite of browser and device tests from {@link browser}.
24004 videojs.browser = browser;
24007 * Whether or not the browser supports touch events. Included for backward
24008 * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED`
24009 * instead going forward.
24011 * @deprecated since version 5.0
24014 videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED;
24017 * Subclass an existing class
24018 * Mimics ES6 subclassing with the `extend` keyword
24020 * @borrows extend:extendFn as videojs.extend
24022 videojs.extend = _extend2['default'];
24025 * Merge two options objects recursively
24026 * Performs a deep merge like lodash.merge but **only merges plain objects**
24027 * (not arrays, elements, anything else)
24028 * Other values will be copied directly from the second object.
24030 * @borrows merge-options:mergeOptions as videojs.mergeOptions
24032 videojs.mergeOptions = _mergeOptions3['default'];
24035 * Change the context (this) of a function
24037 * > NOTE: as of v5.0 we require an ES5 shim, so you should use the native
24038 * `function() {}.bind(newContext);` instead of this.
24040 * @borrows fn:bind as videojs.bind
24042 videojs.bind = Fn.bind;
24045 * Create a Video.js player plugin.
24046 * Plugins are only initialized when options for the plugin are included
24047 * in the player options, or the plugin function on the player instance is
24050 * @borrows plugin:plugin as videojs.plugin
24052 videojs.plugin = _plugins2['default'];
24055 * Adding languages so that they're available to all players.
24056 * Example: `videojs.addLanguage('es', { 'Hello': 'Hola' });`
24058 * @param {string} code
24059 * The language code or dictionary property
24061 * @param {Object} data
24062 * The data values to be translated
24065 * The resulting language dictionary object
24067 videojs.addLanguage = function (code, data) {
24070 code = ('' + code).toLowerCase();
24072 videojs.options.languages = (0, _mergeOptions3['default'])(videojs.options.languages, (_mergeOptions = {}, _mergeOptions[code] = data, _mergeOptions));
24074 return videojs.options.languages[code];
24080 * @borrows log:log as videojs.log
24082 videojs.log = _log2['default'];
24085 * Creates an emulated TimeRange object.
24087 * @borrows time-ranges:createTimeRanges as videojs.createTimeRange
24090 * @borrows time-ranges:createTimeRanges as videojs.createTimeRanges
24092 videojs.createTimeRange = videojs.createTimeRanges = _timeRanges.createTimeRanges;
24095 * Format seconds as a time string, H:MM:SS or M:SS
24096 * Supplying a guide (in seconds) will force a number of leading zeros
24097 * to cover the length of the guide
24099 * @borrows format-time:formatTime as videojs.formatTime
24101 videojs.formatTime = _formatTime2['default'];
24104 * Resolve and parse the elements of a URL
24106 * @borrows url:parseUrl as videojs.parseUrl
24108 videojs.parseUrl = Url.parseUrl;
24111 * Returns whether the url passed is a cross domain request or not.
24113 * @borrows url:isCrossOrigin as videojs.isCrossOrigin
24115 videojs.isCrossOrigin = Url.isCrossOrigin;
24118 * Event target class.
24120 * @borrows EventTarget as videojs.EventTarget
24122 videojs.EventTarget = _eventTarget2['default'];
24125 * Add an event listener to element
24126 * It stores the handler function in a separate cache object
24127 * and adds a generic handler to the element's event,
24128 * along with a unique id (guid) to the element.
24130 * @borrows events:on as videojs.on
24132 videojs.on = Events.on;
24135 * Trigger a listener only once for an event
24137 * @borrows events:one as videojs.one
24139 videojs.one = Events.one;
24142 * Removes event listeners from an element
24144 * @borrows events:off as videojs.off
24146 videojs.off = Events.off;
24149 * Trigger an event for an element
24151 * @borrows events:trigger as videojs.trigger
24153 videojs.trigger = Events.trigger;
24156 * A cross-browser XMLHttpRequest wrapper. Here's a simple example:
24158 * @param {Object} options
24159 * settings for the request.
24161 * @return {XMLHttpRequest|XDomainRequest}
24162 * The request object.
24164 * @see https://github.com/Raynos/xhr
24166 videojs.xhr = _xhr2['default'];
24171 * @borrows TextTrack as videojs.TextTrack
24173 videojs.TextTrack = _textTrack2['default'];
24176 * export the AudioTrack class so that source handlers can create
24177 * AudioTracks and then add them to the players AudioTrackList
24179 * @borrows AudioTrack as videojs.AudioTrack
24181 videojs.AudioTrack = _audioTrack2['default'];
24184 * export the VideoTrack class so that source handlers can create
24185 * VideoTracks and then add them to the players VideoTrackList
24187 * @borrows VideoTrack as videojs.VideoTrack
24189 videojs.VideoTrack = _videoTrack2['default'];
24192 * Determines, via duck typing, whether or not a value is a DOM element.
24194 * @borrows dom:isEl as videojs.isEl
24196 videojs.isEl = Dom.isEl;
24199 * Determines, via duck typing, whether or not a value is a text node.
24201 * @borrows dom:isTextNode as videojs.isTextNode
24203 videojs.isTextNode = Dom.isTextNode;
24206 * Creates an element and applies properties.
24208 * @borrows dom:createEl as videojs.createEl
24210 videojs.createEl = Dom.createEl;
24213 * Check if an element has a CSS class
24215 * @borrows dom:hasElClass as videojs.hasClass
24217 videojs.hasClass = Dom.hasElClass;
24220 * Add a CSS class name to an element
24222 * @borrows dom:addElClass as videojs.addClass
24224 videojs.addClass = Dom.addElClass;
24227 * Remove a CSS class name from an element
24229 * @borrows dom:removeElClass as videojs.removeClass
24231 videojs.removeClass = Dom.removeElClass;
24234 * Adds or removes a CSS class name on an element depending on an optional
24235 * condition or the presence/absence of the class name.
24237 * @borrows dom:toggleElClass as videojs.toggleClass
24239 videojs.toggleClass = Dom.toggleElClass;
24242 * Apply attributes to an HTML element.
24244 * @borrows dom:setElAttributes as videojs.setAttribute
24246 videojs.setAttributes = Dom.setElAttributes;
24249 * Get an element's attribute values, as defined on the HTML tag
24250 * Attributes are not the same as properties. They're defined on the tag
24251 * or with setAttribute (which shouldn't be used with HTML)
24252 * This will return true or false for boolean attributes.
24254 * @borrows dom:getElAttributes as videojs.getAttributes
24256 videojs.getAttributes = Dom.getElAttributes;
24259 * Empties the contents of an element.
24261 * @borrows dom:emptyEl as videojs.emptyEl
24263 videojs.emptyEl = Dom.emptyEl;
24266 * Normalizes and appends content to an element.
24268 * The content for an element can be passed in multiple types and
24269 * combinations, whose behavior is as follows:
24272 * Normalized into a text node.
24274 * - Element, TextNode
24278 * A one-dimensional array of strings, elements, nodes, or functions (which
24279 * return single strings, elements, or nodes).
24282 * If the sole argument, is expected to produce a string, element,
24285 * @borrows dom:appendContents as videojs.appendContet
24287 videojs.appendContent = Dom.appendContent;
24290 * Normalizes and inserts content into an element; this is identical to
24291 * `appendContent()`, except it empties the element first.
24293 * The content for an element can be passed in multiple types and
24294 * combinations, whose behavior is as follows:
24297 * Normalized into a text node.
24299 * - Element, TextNode
24303 * A one-dimensional array of strings, elements, nodes, or functions (which
24304 * return single strings, elements, or nodes).
24307 * If the sole argument, is expected to produce a string, element,
24310 * @borrows dom:insertContent as videojs.insertContent
24312 videojs.insertContent = Dom.insertContent;
24315 * A safe getComputedStyle with an IE8 fallback.
24317 * This is because in Firefox, if the player is loaded in an iframe with `display:none`,
24318 * then `getComputedStyle` returns `null`, so, we do a null-check to make sure
24319 * that the player doesn't break in these cases.
24320 * See https://bugzilla.mozilla.org/show_bug.cgi?id=548397 for more details.
24322 * @borrows computed-style:computedStyle as videojs.computedStyle
24324 videojs.computedStyle = _computedStyle2['default'];
24327 * Custom Universal Module Definition (UMD)
24329 * Video.js will never be a non-browser lib so we can simplify UMD a bunch and
24330 * still support requirejs and browserify. This also needs to be closure
24331 * compiler compatible, so string keys are used.
24333 if (typeof define === 'function' && define.amd) {
24334 define('videojs', [], function () {
24338 // checking that module is an object too because of umdjs/umd#35
24339 } else if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && (typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') {
24340 module.exports = videojs;
24343 exports['default'] = videojs;
24345 },{"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){
24346 (function (global){
24347 var topLevel = typeof global !== 'undefined' ? global :
24348 typeof window !== 'undefined' ? window : {}
24349 var minDoc = _dereq_(96);
24351 if (typeof document !== 'undefined') {
24352 module.exports = document;
24354 var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];
24357 doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;
24360 module.exports = doccy;
24363 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
24364 },{"96":96}],95:[function(_dereq_,module,exports){
24365 (function (global){
24366 if (typeof window !== "undefined") {
24367 module.exports = window;
24368 } else if (typeof global !== "undefined") {
24369 module.exports = global;
24370 } else if (typeof self !== "undefined"){
24371 module.exports = self;
24373 module.exports = {};
24376 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
24377 },{}],96:[function(_dereq_,module,exports){
24379 },{}],97:[function(_dereq_,module,exports){
24380 module.exports = SafeParseTuple
24382 function SafeParseTuple(obj, reviver) {
24387 json = JSON.parse(obj, reviver)
24392 return [error, json]
24395 },{}],98:[function(_dereq_,module,exports){
24396 function clean (s) {
24397 return s.replace(/\n\r?\s*/g, '')
24401 module.exports = function tsml (sa) {
24405 for (; i < arguments.length; i++)
24406 s += clean(sa[i]) + (arguments[i + 1] || '')
24410 },{}],99:[function(_dereq_,module,exports){
24412 var window = _dereq_(95)
24413 var isFunction = _dereq_(100)
24414 var parseHeaders = _dereq_(103)
24415 var xtend = _dereq_(104)
24417 module.exports = createXHR
24418 createXHR.XMLHttpRequest = window.XMLHttpRequest || noop
24419 createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest
24421 forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) {
24422 createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) {
24423 options = initParams(uri, options, callback)
24424 options.method = method.toUpperCase()
24425 return _createXHR(options)
24429 function forEachArray(array, iterator) {
24430 for (var i = 0; i < array.length; i++) {
24435 function isEmpty(obj){
24437 if(obj.hasOwnProperty(i)) return false
24442 function initParams(uri, options, callback) {
24445 if (isFunction(options)) {
24447 if (typeof uri === "string") {
24451 params = xtend(options, {uri: uri})
24454 params.callback = callback
24458 function createXHR(uri, options, callback) {
24459 options = initParams(uri, options, callback)
24460 return _createXHR(options)
24463 function _createXHR(options) {
24464 if(typeof options.callback === "undefined"){
24465 throw new Error("callback argument missing")
24469 var callback = function cbOnce(err, response, body){
24472 options.callback(err, response, body)
24476 function readystatechange() {
24477 if (xhr.readyState === 4) {
24478 setTimeout(loadFunc, 0)
24482 function getBody() {
24483 // Chrome with requestType=blob throws errors arround when even testing access to responseText
24484 var body = undefined
24486 if (xhr.response) {
24487 body = xhr.response
24489 body = xhr.responseText || getXml(xhr)
24494 body = JSON.parse(body)
24501 function errorFunc(evt) {
24502 clearTimeout(timeoutTimer)
24503 if(!(evt instanceof Error)){
24504 evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") )
24507 return callback(evt, failureResponse)
24510 // will load the data & process the response in a special response object
24511 function loadFunc() {
24512 if (aborted) return
24514 clearTimeout(timeoutTimer)
24515 if(options.useXDR && xhr.status===undefined) {
24516 //IE8 CORS GET successful response doesn't have a status field, but body is fine
24519 status = (xhr.status === 1223 ? 204 : xhr.status)
24521 var response = failureResponse
24527 statusCode: status,
24533 if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
24534 response.headers = parseHeaders(xhr.getAllResponseHeaders())
24537 err = new Error("Internal XMLHttpRequest Error")
24539 return callback(err, response, response.body)
24542 var xhr = options.xhr || null
24545 if (options.cors || options.useXDR) {
24546 xhr = new createXHR.XDomainRequest()
24548 xhr = new createXHR.XMLHttpRequest()
24554 var uri = xhr.url = options.uri || options.url
24555 var method = xhr.method = options.method || "GET"
24556 var body = options.body || options.data
24557 var headers = xhr.headers = options.headers || {}
24558 var sync = !!options.sync
24561 var failureResponse = {
24570 if ("json" in options && options.json !== false) {
24572 headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user
24573 if (method !== "GET" && method !== "HEAD") {
24574 headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user
24575 body = JSON.stringify(options.json === true ? body : options.json)
24579 xhr.onreadystatechange = readystatechange
24580 xhr.onload = loadFunc
24581 xhr.onerror = errorFunc
24582 // IE9 must have onprogress be set to a unique function.
24583 xhr.onprogress = function () {
24586 xhr.onabort = function(){
24589 xhr.ontimeout = errorFunc
24590 xhr.open(method, uri, !sync, options.username, options.password)
24591 //has to be after open
24593 xhr.withCredentials = !!options.withCredentials
24595 // Cannot set timeout with sync request
24596 // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly
24597 // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent
24598 if (!sync && options.timeout > 0 ) {
24599 timeoutTimer = setTimeout(function(){
24600 if (aborted) return
24601 aborted = true//IE9 may still call readystatechange
24602 xhr.abort("timeout")
24603 var e = new Error("XMLHttpRequest timeout")
24604 e.code = "ETIMEDOUT"
24606 }, options.timeout )
24609 if (xhr.setRequestHeader) {
24610 for(key in headers){
24611 if(headers.hasOwnProperty(key)){
24612 xhr.setRequestHeader(key, headers[key])
24615 } else if (options.headers && !isEmpty(options.headers)) {
24616 throw new Error("Headers cannot be set on an XDomainRequest object")
24619 if ("responseType" in options) {
24620 xhr.responseType = options.responseType
24623 if ("beforeSend" in options &&
24624 typeof options.beforeSend === "function"
24626 options.beforeSend(xhr)
24629 // Microsoft Edge browser sends "undefined" when send is called with undefined value.
24630 // XMLHttpRequest spec says to pass null as body to indicate no body
24631 // See https://github.com/naugtur/xhr/issues/100.
24632 xhr.send(body || null)
24639 function getXml(xhr) {
24640 if (xhr.responseType === "document") {
24641 return xhr.responseXML
24643 var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror"
24644 if (xhr.responseType === "" && !firefoxBugTakenEffect) {
24645 return xhr.responseXML
24653 },{"100":100,"103":103,"104":104,"95":95}],100:[function(_dereq_,module,exports){
24654 module.exports = isFunction
24656 var toString = Object.prototype.toString
24658 function isFunction (fn) {
24659 var string = toString.call(fn)
24660 return string === '[object Function]' ||
24661 (typeof fn === 'function' && string !== '[object RegExp]') ||
24662 (typeof window !== 'undefined' &&
24664 (fn === window.setTimeout ||
24665 fn === window.alert ||
24666 fn === window.confirm ||
24667 fn === window.prompt))
24670 },{}],101:[function(_dereq_,module,exports){
24671 var isFunction = _dereq_(100)
24673 module.exports = forEach
24675 var toString = Object.prototype.toString
24676 var hasOwnProperty = Object.prototype.hasOwnProperty
24678 function forEach(list, iterator, context) {
24679 if (!isFunction(iterator)) {
24680 throw new TypeError('iterator must be a function')
24683 if (arguments.length < 3) {
24687 if (toString.call(list) === '[object Array]')
24688 forEachArray(list, iterator, context)
24689 else if (typeof list === 'string')
24690 forEachString(list, iterator, context)
24692 forEachObject(list, iterator, context)
24695 function forEachArray(array, iterator, context) {
24696 for (var i = 0, len = array.length; i < len; i++) {
24697 if (hasOwnProperty.call(array, i)) {
24698 iterator.call(context, array[i], i, array)
24703 function forEachString(string, iterator, context) {
24704 for (var i = 0, len = string.length; i < len; i++) {
24705 // no such thing as a sparse string.
24706 iterator.call(context, string.charAt(i), i, string)
24710 function forEachObject(object, iterator, context) {
24711 for (var k in object) {
24712 if (hasOwnProperty.call(object, k)) {
24713 iterator.call(context, object[k], k, object)
24718 },{"100":100}],102:[function(_dereq_,module,exports){
24720 exports = module.exports = trim;
24722 function trim(str){
24723 return str.replace(/^\s*|\s*$/g, '');
24726 exports.left = function(str){
24727 return str.replace(/^\s*/, '');
24730 exports.right = function(str){
24731 return str.replace(/\s*$/, '');
24734 },{}],103:[function(_dereq_,module,exports){
24735 var trim = _dereq_(102)
24736 , forEach = _dereq_(101)
24737 , isArray = function(arg) {
24738 return Object.prototype.toString.call(arg) === '[object Array]';
24741 module.exports = function (headers) {
24748 trim(headers).split('\n')
24750 var index = row.indexOf(':')
24751 , key = trim(row.slice(0, index)).toLowerCase()
24752 , value = trim(row.slice(index + 1))
24754 if (typeof(result[key]) === 'undefined') {
24755 result[key] = value
24756 } else if (isArray(result[key])) {
24757 result[key].push(value)
24759 result[key] = [ result[key], value ]
24766 },{"101":101,"102":102}],104:[function(_dereq_,module,exports){
24767 module.exports = extend
24769 var hasOwnProperty = Object.prototype.hasOwnProperty;
24771 function extend() {
24774 for (var i = 0; i < arguments.length; i++) {
24775 var source = arguments[i]
24777 for (var key in source) {
24778 if (hasOwnProperty.call(source, key)) {
24779 target[key] = source[key]
24787 },{}],105:[function(_dereq_,module,exports){
24789 * Copyright 2013 vtt.js Contributors
24791 * Licensed under the Apache License, Version 2.0 (the "License");
24792 * you may not use this file except in compliance with the License.
24793 * You may obtain a copy of the License at
24795 * http://www.apache.org/licenses/LICENSE-2.0
24797 * Unless required by applicable law or agreed to in writing, software
24798 * distributed under the License is distributed on an "AS IS" BASIS,
24799 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24800 * See the License for the specific language governing permissions and
24801 * limitations under the License.
24804 // Default exports for Node. Export the extended versions of VTTCue and
24805 // VTTRegion in Node since we likely want the capability to convert back and
24806 // forth between JSON. If we don't then it's not that big of a deal since we're
24809 var window = _dereq_(109);
24811 var vttjs = module.exports = {
24812 WebVTT: _dereq_(106).WebVTT,
24813 VTTCue: _dereq_(107).VTTCue,
24814 VTTRegion: _dereq_(108).VTTRegion
24817 window.vttjs = vttjs;
24818 window.WebVTT = vttjs.WebVTT;
24820 var cueShim = vttjs.VTTCue;
24821 var regionShim = vttjs.VTTRegion;
24822 var nativeVTTCue = window.VTTCue;
24823 var nativeVTTRegion = window.VTTRegion;
24825 vttjs.shim = function() {
24826 window.VTTCue = cueShim;
24827 window.VTTRegion = regionShim;
24830 vttjs.restore = function() {
24831 window.VTTCue = nativeVTTCue;
24832 window.VTTRegion = nativeVTTRegion;
24835 if (!window.VTTCue) {
24839 },{"106":106,"107":107,"108":108,"109":109}],106:[function(_dereq_,module,exports){
24841 * Copyright 2013 vtt.js Contributors
24843 * Licensed under the Apache License, Version 2.0 (the "License");
24844 * you may not use this file except in compliance with the License.
24845 * You may obtain a copy of the License at
24847 * http://www.apache.org/licenses/LICENSE-2.0
24849 * Unless required by applicable law or agreed to in writing, software
24850 * distributed under the License is distributed on an "AS IS" BASIS,
24851 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24852 * See the License for the specific language governing permissions and
24853 * limitations under the License.
24856 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
24857 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
24859 (function(global) {
24861 var _objCreate = Object.create || (function() {
24863 return function(o) {
24864 if (arguments.length !== 1) {
24865 throw new Error('Object.create shim only accepts one parameter.');
24872 // Creates a new ParserError object from an errorData object. The errorData
24873 // object should have default code and message properties. The default message
24874 // property can be overriden by passing in a message parameter.
24875 // See ParsingError.Errors below for acceptable errors.
24876 function ParsingError(errorData, message) {
24877 this.name = "ParsingError";
24878 this.code = errorData.code;
24879 this.message = message || errorData.message;
24881 ParsingError.prototype = _objCreate(Error.prototype);
24882 ParsingError.prototype.constructor = ParsingError;
24884 // ParsingError metadata for acceptable ParsingErrors.
24885 ParsingError.Errors = {
24888 message: "Malformed WebVTT signature."
24892 message: "Malformed time stamp."
24896 // Try to parse input as a time stamp.
24897 function parseTimeStamp(input) {
24899 function computeSeconds(h, m, s, f) {
24900 return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000;
24903 var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);
24909 // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds]
24910 return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]);
24911 } else if (m[1] > 59) {
24912 // Timestamp takes the form of [hours]:[minutes].[milliseconds]
24913 // First position is hours as it's over 59.
24914 return computeSeconds(m[1], m[2], 0, m[4]);
24916 // Timestamp takes the form of [minutes]:[seconds].[milliseconds]
24917 return computeSeconds(0, m[1], m[2], m[4]);
24921 // A settings object holds key/value pairs and will ignore anything but the first
24922 // assignment to a specific key.
24923 function Settings() {
24924 this.values = _objCreate(null);
24927 Settings.prototype = {
24928 // Only accept the first assignment to any key.
24929 set: function(k, v) {
24930 if (!this.get(k) && v !== "") {
24931 this.values[k] = v;
24934 // Return the value for a key, or a default value.
24935 // If 'defaultKey' is passed then 'dflt' is assumed to be an object with
24936 // a number of possible default values as properties where 'defaultKey' is
24937 // the key of the property that will be chosen; otherwise it's assumed to be
24939 get: function(k, dflt, defaultKey) {
24941 return this.has(k) ? this.values[k] : dflt[defaultKey];
24943 return this.has(k) ? this.values[k] : dflt;
24945 // Check whether we have a value for a key.
24947 return k in this.values;
24949 // Accept a setting if its one of the given alternatives.
24950 alt: function(k, v, a) {
24951 for (var n = 0; n < a.length; ++n) {
24958 // Accept a setting if its a valid (signed) integer.
24959 integer: function(k, v) {
24960 if (/^-?\d+$/.test(v)) { // integer
24961 this.set(k, parseInt(v, 10));
24964 // Accept a setting if its a valid percentage.
24965 percent: function(k, v) {
24967 if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) {
24969 if (v >= 0 && v <= 100) {
24978 // Helper function to parse input into groups separated by 'groupDelim', and
24979 // interprete each group as a key/value pair separated by 'keyValueDelim'.
24980 function parseOptions(input, callback, keyValueDelim, groupDelim) {
24981 var groups = groupDelim ? input.split(groupDelim) : [input];
24982 for (var i in groups) {
24983 if (typeof groups[i] !== "string") {
24986 var kv = groups[i].split(keyValueDelim);
24987 if (kv.length !== 2) {
24996 function parseCue(input, cue, regionList) {
24997 // Remember the original input if we need to throw an error.
24998 var oInput = input;
24999 // 4.1 WebVTT timestamp
25000 function consumeTimeStamp() {
25001 var ts = parseTimeStamp(input);
25003 throw new ParsingError(ParsingError.Errors.BadTimeStamp,
25004 "Malformed timestamp: " + oInput);
25006 // Remove time stamp from input.
25007 input = input.replace(/^[^\sa-zA-Z-]+/, "");
25011 // 4.4.2 WebVTT cue settings
25012 function consumeCueSettings(input, cue) {
25013 var settings = new Settings();
25015 parseOptions(input, function (k, v) {
25018 // Find the last region we parsed with the same region id.
25019 for (var i = regionList.length - 1; i >= 0; i--) {
25020 if (regionList[i].id === v) {
25021 settings.set(k, regionList[i].region);
25027 settings.alt(k, v, ["rl", "lr"]);
25030 var vals = v.split(","),
25032 settings.integer(k, vals0);
25033 settings.percent(k, vals0) ? settings.set("snapToLines", false) : null;
25034 settings.alt(k, vals0, ["auto"]);
25035 if (vals.length === 2) {
25036 settings.alt("lineAlign", vals[1], ["start", "middle", "end"]);
25040 vals = v.split(",");
25041 settings.percent(k, vals[0]);
25042 if (vals.length === 2) {
25043 settings.alt("positionAlign", vals[1], ["start", "middle", "end"]);
25047 settings.percent(k, v);
25050 settings.alt(k, v, ["start", "middle", "end", "left", "right"]);
25055 // Apply default values for any missing fields.
25056 cue.region = settings.get("region", null);
25057 cue.vertical = settings.get("vertical", "");
25058 cue.line = settings.get("line", "auto");
25059 cue.lineAlign = settings.get("lineAlign", "start");
25060 cue.snapToLines = settings.get("snapToLines", true);
25061 cue.size = settings.get("size", 100);
25062 cue.align = settings.get("align", "middle");
25063 cue.position = settings.get("position", {
25070 cue.positionAlign = settings.get("positionAlign", {
25079 function skipWhitespace() {
25080 input = input.replace(/^\s+/, "");
25083 // 4.1 WebVTT cue timings.
25085 cue.startTime = consumeTimeStamp(); // (1) collect cue start time
25087 if (input.substr(0, 3) !== "-->") { // (3) next characters must match "-->"
25088 throw new ParsingError(ParsingError.Errors.BadTimeStamp,
25089 "Malformed time stamp (time stamps must be separated by '-->'): " +
25092 input = input.substr(3);
25094 cue.endTime = consumeTimeStamp(); // (5) collect cue end time
25096 // 4.1 WebVTT cue settings list.
25098 consumeCueSettings(input, cue);
25121 var TAG_ANNOTATION = {
25126 var NEEDS_PARENT = {
25130 // Parse content into a document fragment.
25131 function parseContent(window, input) {
25132 function nextToken() {
25133 // Check for end-of-string.
25138 // Consume 'n' characters from the input.
25139 function consume(result) {
25140 input = input.substr(result.length);
25144 var m = input.match(/^([^<]*)(<[^>]+>?)?/);
25145 // If there is some text before the next tag, return it, otherwise return
25147 return consume(m[1] ? m[1] : m[2]);
25150 // Unescape a string 's'.
25151 function unescape1(e) {
25154 function unescape(s) {
25155 while ((m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/))) {
25156 s = s.replace(m[0], unescape1);
25161 function shouldAdd(current, element) {
25162 return !NEEDS_PARENT[element.localName] ||
25163 NEEDS_PARENT[element.localName] === current.localName;
25166 // Create an element for this tag.
25167 function createElement(type, annotation) {
25168 var tagName = TAG_NAME[type];
25172 var element = window.document.createElement(tagName);
25173 element.localName = tagName;
25174 var name = TAG_ANNOTATION[type];
25175 if (name && annotation) {
25176 element[name] = annotation.trim();
25181 var rootDiv = window.document.createElement("div"),
25186 while ((t = nextToken()) !== null) {
25187 if (t[0] === '<') {
25188 if (t[1] === "/") {
25189 // If the closing tag matches, move back up to the parent node.
25190 if (tagStack.length &&
25191 tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) {
25193 current = current.parentNode;
25195 // Otherwise just ignore the end tag.
25198 var ts = parseTimeStamp(t.substr(1, t.length - 2));
25201 // Timestamps are lead nodes as well.
25202 node = window.document.createProcessingInstruction("timestamp", ts);
25203 current.appendChild(node);
25206 var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);
25207 // If we can't parse the tag, skip to the next tag.
25211 // Try to construct an element, and ignore the tag if we couldn't.
25212 node = createElement(m[1], m[3]);
25216 // Determine if the tag should be added based on the context of where it
25217 // is placed in the cuetext.
25218 if (!shouldAdd(current, node)) {
25221 // Set the class list (as a list of classes, separated by space).
25223 node.className = m[2].substr(1).replace('.', ' ');
25225 // Append the node to the current node, and enter the scope of the new
25227 tagStack.push(m[1]);
25228 current.appendChild(node);
25233 // Text nodes are leaf nodes.
25234 current.appendChild(window.document.createTextNode(unescape(t)));
25240 // This is a list of all the Unicode characters that have a strong
25241 // right-to-left category. What this means is that these characters are
25242 // written right-to-left for sure. It was generated by pulling all the strong
25243 // right-to-left characters out of the Unicode data table. That table can
25244 // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
25245 var strongRTLRanges = [[0x5be, 0x5be], [0x5c0, 0x5c0], [0x5c3, 0x5c3], [0x5c6, 0x5c6],
25246 [0x5d0, 0x5ea], [0x5f0, 0x5f4], [0x608, 0x608], [0x60b, 0x60b], [0x60d, 0x60d],
25247 [0x61b, 0x61b], [0x61e, 0x64a], [0x66d, 0x66f], [0x671, 0x6d5], [0x6e5, 0x6e6],
25248 [0x6ee, 0x6ef], [0x6fa, 0x70d], [0x70f, 0x710], [0x712, 0x72f], [0x74d, 0x7a5],
25249 [0x7b1, 0x7b1], [0x7c0, 0x7ea], [0x7f4, 0x7f5], [0x7fa, 0x7fa], [0x800, 0x815],
25250 [0x81a, 0x81a], [0x824, 0x824], [0x828, 0x828], [0x830, 0x83e], [0x840, 0x858],
25251 [0x85e, 0x85e], [0x8a0, 0x8a0], [0x8a2, 0x8ac], [0x200f, 0x200f],
25252 [0xfb1d, 0xfb1d], [0xfb1f, 0xfb28], [0xfb2a, 0xfb36], [0xfb38, 0xfb3c],
25253 [0xfb3e, 0xfb3e], [0xfb40, 0xfb41], [0xfb43, 0xfb44], [0xfb46, 0xfbc1],
25254 [0xfbd3, 0xfd3d], [0xfd50, 0xfd8f], [0xfd92, 0xfdc7], [0xfdf0, 0xfdfc],
25255 [0xfe70, 0xfe74], [0xfe76, 0xfefc], [0x10800, 0x10805], [0x10808, 0x10808],
25256 [0x1080a, 0x10835], [0x10837, 0x10838], [0x1083c, 0x1083c], [0x1083f, 0x10855],
25257 [0x10857, 0x1085f], [0x10900, 0x1091b], [0x10920, 0x10939], [0x1093f, 0x1093f],
25258 [0x10980, 0x109b7], [0x109be, 0x109bf], [0x10a00, 0x10a00], [0x10a10, 0x10a13],
25259 [0x10a15, 0x10a17], [0x10a19, 0x10a33], [0x10a40, 0x10a47], [0x10a50, 0x10a58],
25260 [0x10a60, 0x10a7f], [0x10b00, 0x10b35], [0x10b40, 0x10b55], [0x10b58, 0x10b72],
25261 [0x10b78, 0x10b7f], [0x10c00, 0x10c48], [0x1ee00, 0x1ee03], [0x1ee05, 0x1ee1f],
25262 [0x1ee21, 0x1ee22], [0x1ee24, 0x1ee24], [0x1ee27, 0x1ee27], [0x1ee29, 0x1ee32],
25263 [0x1ee34, 0x1ee37], [0x1ee39, 0x1ee39], [0x1ee3b, 0x1ee3b], [0x1ee42, 0x1ee42],
25264 [0x1ee47, 0x1ee47], [0x1ee49, 0x1ee49], [0x1ee4b, 0x1ee4b], [0x1ee4d, 0x1ee4f],
25265 [0x1ee51, 0x1ee52], [0x1ee54, 0x1ee54], [0x1ee57, 0x1ee57], [0x1ee59, 0x1ee59],
25266 [0x1ee5b, 0x1ee5b], [0x1ee5d, 0x1ee5d], [0x1ee5f, 0x1ee5f], [0x1ee61, 0x1ee62],
25267 [0x1ee64, 0x1ee64], [0x1ee67, 0x1ee6a], [0x1ee6c, 0x1ee72], [0x1ee74, 0x1ee77],
25268 [0x1ee79, 0x1ee7c], [0x1ee7e, 0x1ee7e], [0x1ee80, 0x1ee89], [0x1ee8b, 0x1ee9b],
25269 [0x1eea1, 0x1eea3], [0x1eea5, 0x1eea9], [0x1eeab, 0x1eebb], [0x10fffd, 0x10fffd]];
25271 function isStrongRTLChar(charCode) {
25272 for (var i = 0; i < strongRTLRanges.length; i++) {
25273 var currentRange = strongRTLRanges[i];
25274 if (charCode >= currentRange[0] && charCode <= currentRange[1]) {
25282 function determineBidi(cueDiv) {
25283 var nodeStack = [],
25287 if (!cueDiv || !cueDiv.childNodes) {
25291 function pushNodes(nodeStack, node) {
25292 for (var i = node.childNodes.length - 1; i >= 0; i--) {
25293 nodeStack.push(node.childNodes[i]);
25297 function nextTextNode(nodeStack) {
25298 if (!nodeStack || !nodeStack.length) {
25302 var node = nodeStack.pop(),
25303 text = node.textContent || node.innerText;
25305 // TODO: This should match all unicode type B characters (paragraph
25306 // separator characters). See issue #115.
25307 var m = text.match(/^.*(\n|\r)/);
25309 nodeStack.length = 0;
25314 if (node.tagName === "ruby") {
25315 return nextTextNode(nodeStack);
25317 if (node.childNodes) {
25318 pushNodes(nodeStack, node);
25319 return nextTextNode(nodeStack);
25323 pushNodes(nodeStack, cueDiv);
25324 while ((text = nextTextNode(nodeStack))) {
25325 for (var i = 0; i < text.length; i++) {
25326 charCode = text.charCodeAt(i);
25327 if (isStrongRTLChar(charCode)) {
25335 function computeLinePos(cue) {
25336 if (typeof cue.line === "number" &&
25337 (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) {
25340 if (!cue.track || !cue.track.textTrackList ||
25341 !cue.track.textTrackList.mediaElement) {
25344 var track = cue.track,
25345 trackList = track.textTrackList,
25347 for (var i = 0; i < trackList.length && trackList[i] !== track; i++) {
25348 if (trackList[i].mode === "showing") {
25352 return ++count * -1;
25355 function StyleBox() {
25358 // Apply styles to a div. If there is no div passed then it defaults to the
25360 StyleBox.prototype.applyStyles = function(styles, div) {
25361 div = div || this.div;
25362 for (var prop in styles) {
25363 if (styles.hasOwnProperty(prop)) {
25364 div.style[prop] = styles[prop];
25369 StyleBox.prototype.formatStyle = function(val, unit) {
25370 return val === 0 ? 0 : val + unit;
25373 // Constructs the computed display state of the cue (a div). Places the div
25374 // into the overlay which should be a block level element (usually a div).
25375 function CueStyleBox(window, cue, styleOptions) {
25376 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
25377 var color = "rgba(255, 255, 255, 1)";
25378 var backgroundColor = "rgba(0, 0, 0, 0.8)";
25381 color = "rgb(255, 255, 255)";
25382 backgroundColor = "rgb(0, 0, 0)";
25385 StyleBox.call(this);
25388 // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will
25389 // have inline positioning and will function as the cue background box.
25390 this.cueDiv = parseContent(window, cue.text);
25393 backgroundColor: backgroundColor,
25394 position: "relative",
25403 styles.writingMode = cue.vertical === "" ? "horizontal-tb"
25404 : cue.vertical === "lr" ? "vertical-lr"
25406 styles.unicodeBidi = "plaintext";
25408 this.applyStyles(styles, this.cueDiv);
25410 // Create an absolutely positioned div that will be used to position the cue
25411 // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS
25412 // mirrors of them except "middle" which is "center" in CSS.
25413 this.div = window.document.createElement("div");
25415 textAlign: cue.align === "middle" ? "center" : cue.align,
25416 font: styleOptions.font,
25417 whiteSpace: "pre-line",
25418 position: "absolute"
25422 styles.direction = determineBidi(this.cueDiv);
25423 styles.writingMode = cue.vertical === "" ? "horizontal-tb"
25424 : cue.vertical === "lr" ? "vertical-lr"
25426 stylesunicodeBidi = "plaintext";
25429 this.applyStyles(styles);
25431 this.div.appendChild(this.cueDiv);
25433 // Calculate the distance from the reference edge of the viewport to the text
25434 // position of the cue box. The reference edge will be resolved later when
25435 // the box orientation styles are applied.
25437 switch (cue.positionAlign) {
25439 textPos = cue.position;
25442 textPos = cue.position - (cue.size / 2);
25445 textPos = cue.position - cue.size;
25449 // Horizontal box orientation; textPos is the distance from the left edge of the
25450 // area to the left edge of the box and cue.size is the distance extending to
25451 // the right from there.
25452 if (cue.vertical === "") {
25454 left: this.formatStyle(textPos, "%"),
25455 width: this.formatStyle(cue.size, "%")
25457 // Vertical box orientation; textPos is the distance from the top edge of the
25458 // area to the top edge of the box and cue.size is the height extending
25459 // downwards from there.
25462 top: this.formatStyle(textPos, "%"),
25463 height: this.formatStyle(cue.size, "%")
25467 this.move = function(box) {
25469 top: this.formatStyle(box.top, "px"),
25470 bottom: this.formatStyle(box.bottom, "px"),
25471 left: this.formatStyle(box.left, "px"),
25472 right: this.formatStyle(box.right, "px"),
25473 height: this.formatStyle(box.height, "px"),
25474 width: this.formatStyle(box.width, "px")
25478 CueStyleBox.prototype = _objCreate(StyleBox.prototype);
25479 CueStyleBox.prototype.constructor = CueStyleBox;
25481 // Represents the co-ordinates of an Element in a way that we can easily
25482 // compute things with such as if it overlaps or intersects with another Element.
25483 // Can initialize it with either a StyleBox or another BoxPosition.
25484 function BoxPosition(obj) {
25485 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
25487 // Either a BoxPosition was passed in and we need to copy it, or a StyleBox
25488 // was passed in and we need to copy the results of 'getBoundingClientRect'
25489 // as the object returned is readonly. All co-ordinate values are in reference
25490 // to the viewport origin (top left).
25491 var lh, height, width, top;
25493 height = obj.div.offsetHeight;
25494 width = obj.div.offsetWidth;
25495 top = obj.div.offsetTop;
25497 var rects = (rects = obj.div.childNodes) && (rects = rects[0]) &&
25498 rects.getClientRects && rects.getClientRects();
25499 obj = obj.div.getBoundingClientRect();
25500 // In certain cases the outter div will be slightly larger then the sum of
25501 // the inner div's lines. This could be due to bold text, etc, on some platforms.
25502 // In this case we should get the average line height and use that. This will
25503 // result in the desired behaviour.
25504 lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length)
25508 this.left = obj.left;
25509 this.right = obj.right;
25510 this.top = obj.top || top;
25511 this.height = obj.height || height;
25512 this.bottom = obj.bottom || (top + (obj.height || height));
25513 this.width = obj.width || width;
25514 this.lineHeight = lh !== undefined ? lh : obj.lineHeight;
25516 if (isIE8 && !this.lineHeight) {
25517 this.lineHeight = 13;
25521 // Move the box along a particular axis. Optionally pass in an amount to move
25522 // the box. If no amount is passed then the default is the line height of the
25524 BoxPosition.prototype.move = function(axis, toMove) {
25525 toMove = toMove !== undefined ? toMove : this.lineHeight;
25528 this.left += toMove;
25529 this.right += toMove;
25532 this.left -= toMove;
25533 this.right -= toMove;
25536 this.top += toMove;
25537 this.bottom += toMove;
25540 this.top -= toMove;
25541 this.bottom -= toMove;
25546 // Check if this box overlaps another box, b2.
25547 BoxPosition.prototype.overlaps = function(b2) {
25548 return this.left < b2.right &&
25549 this.right > b2.left &&
25550 this.top < b2.bottom &&
25551 this.bottom > b2.top;
25554 // Check if this box overlaps any other boxes in boxes.
25555 BoxPosition.prototype.overlapsAny = function(boxes) {
25556 for (var i = 0; i < boxes.length; i++) {
25557 if (this.overlaps(boxes[i])) {
25564 // Check if this box is within another box.
25565 BoxPosition.prototype.within = function(container) {
25566 return this.top >= container.top &&
25567 this.bottom <= container.bottom &&
25568 this.left >= container.left &&
25569 this.right <= container.right;
25572 // Check if this box is entirely within the container or it is overlapping
25573 // on the edge opposite of the axis direction passed. For example, if "+x" is
25574 // passed and the box is overlapping on the left edge of the container, then
25576 BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) {
25579 return this.left < container.left;
25581 return this.right > container.right;
25583 return this.top < container.top;
25585 return this.bottom > container.bottom;
25589 // Find the percentage of the area that this box is overlapping with another
25591 BoxPosition.prototype.intersectPercentage = function(b2) {
25592 var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)),
25593 y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)),
25594 intersectArea = x * y;
25595 return intersectArea / (this.height * this.width);
25598 // Convert the positions from this box to CSS compatible positions using
25599 // the reference container's positions. This has to be done because this
25600 // box's positions are in reference to the viewport origin, whereas, CSS
25601 // values are in referecne to their respective edges.
25602 BoxPosition.prototype.toCSSCompatValues = function(reference) {
25604 top: this.top - reference.top,
25605 bottom: reference.bottom - this.bottom,
25606 left: this.left - reference.left,
25607 right: reference.right - this.right,
25608 height: this.height,
25613 // Get an object that represents the box's position without anything extra.
25614 // Can pass a StyleBox, HTMLElement, or another BoxPositon.
25615 BoxPosition.getSimpleBoxPosition = function(obj) {
25616 var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0;
25617 var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0;
25618 var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0;
25620 obj = obj.div ? obj.div.getBoundingClientRect() :
25621 obj.tagName ? obj.getBoundingClientRect() : obj;
25625 top: obj.top || top,
25626 height: obj.height || height,
25627 bottom: obj.bottom || (top + (obj.height || height)),
25628 width: obj.width || width
25633 // Move a StyleBox to its specified, or next best, position. The containerBox
25634 // is the box that contains the StyleBox, such as a div. boxPositions are
25635 // a list of other boxes that the styleBox can't overlap with.
25636 function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) {
25638 // Find the best position for a cue box, b, on the video. The axis parameter
25639 // is a list of axis, the order of which, it will move the box along. For example:
25640 // Passing ["+x", "-x"] will move the box first along the x axis in the positive
25641 // direction. If it doesn't find a good position for it there it will then move
25642 // it along the x axis in the negative direction.
25643 function findBestPosition(b, axis) {
25645 specifiedPosition = new BoxPosition(b),
25646 percentage = 1; // Highest possible so the first thing we get is better.
25648 for (var i = 0; i < axis.length; i++) {
25649 while (b.overlapsOppositeAxis(containerBox, axis[i]) ||
25650 (b.within(containerBox) && b.overlapsAny(boxPositions))) {
25653 // We found a spot where we aren't overlapping anything. This is our
25655 if (b.within(containerBox)) {
25658 var p = b.intersectPercentage(containerBox);
25659 // If we're outside the container box less then we were on our last try
25660 // then remember this position as the best position.
25661 if (percentage > p) {
25662 bestPosition = new BoxPosition(b);
25665 // Reset the box position to the specified position.
25666 b = new BoxPosition(specifiedPosition);
25668 return bestPosition || specifiedPosition;
25671 var boxPosition = new BoxPosition(styleBox),
25672 cue = styleBox.cue,
25673 linePos = computeLinePos(cue),
25676 // If we have a line number to align the cue to.
25677 if (cue.snapToLines) {
25679 switch (cue.vertical) {
25681 axis = [ "+y", "-y" ];
25685 axis = [ "+x", "-x" ];
25689 axis = [ "-x", "+x" ];
25694 var step = boxPosition.lineHeight,
25695 position = step * Math.round(linePos),
25696 maxPosition = containerBox[size] + step,
25697 initialAxis = axis[0];
25699 // If the specified intial position is greater then the max position then
25700 // clamp the box to the amount of steps it would take for the box to
25701 // reach the max position.
25702 if (Math.abs(position) > maxPosition) {
25703 position = position < 0 ? -1 : 1;
25704 position *= Math.ceil(maxPosition / step) * step;
25707 // If computed line position returns negative then line numbers are
25708 // relative to the bottom of the video instead of the top. Therefore, we
25709 // need to increase our initial position by the length or width of the
25710 // video, depending on the writing direction, and reverse our axis directions.
25712 position += cue.vertical === "" ? containerBox.height : containerBox.width;
25713 axis = axis.reverse();
25716 // Move the box to the specified position. This may not be its best
25718 boxPosition.move(initialAxis, position);
25721 // If we have a percentage line value for the cue.
25722 var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100;
25724 switch (cue.lineAlign) {
25726 linePos -= (calculatedPercentage / 2);
25729 linePos -= calculatedPercentage;
25733 // Apply initial line position to the cue box.
25734 switch (cue.vertical) {
25736 styleBox.applyStyles({
25737 top: styleBox.formatStyle(linePos, "%")
25741 styleBox.applyStyles({
25742 left: styleBox.formatStyle(linePos, "%")
25746 styleBox.applyStyles({
25747 right: styleBox.formatStyle(linePos, "%")
25752 axis = [ "+y", "-x", "+x", "-y" ];
25754 // Get the box position again after we've applied the specified positioning
25756 boxPosition = new BoxPosition(styleBox);
25759 var bestPosition = findBestPosition(boxPosition, axis);
25760 styleBox.move(bestPosition.toCSSCompatValues(containerBox));
25763 function WebVTT() {
25767 // Helper to allow strings to be decoded instead of the default binary utf8 data.
25768 WebVTT.StringDecoder = function() {
25770 decode: function(data) {
25774 if (typeof data !== "string") {
25775 throw new Error("Error - expected string data.");
25777 return decodeURIComponent(encodeURIComponent(data));
25782 WebVTT.convertCueToDOMTree = function(window, cuetext) {
25783 if (!window || !cuetext) {
25786 return parseContent(window, cuetext);
25789 var FONT_SIZE_PERCENT = 0.05;
25790 var FONT_STYLE = "sans-serif";
25791 var CUE_BACKGROUND_PADDING = "1.5%";
25793 // Runs the processing model over the cues and regions passed to it.
25794 // @param overlay A block level element (usually a div) that the computed cues
25795 // and regions will be placed into.
25796 WebVTT.processCues = function(window, cues, overlay) {
25797 if (!window || !cues || !overlay) {
25801 // Remove all previous children.
25802 while (overlay.firstChild) {
25803 overlay.removeChild(overlay.firstChild);
25806 var paddedOverlay = window.document.createElement("div");
25807 paddedOverlay.style.position = "absolute";
25808 paddedOverlay.style.left = "0";
25809 paddedOverlay.style.right = "0";
25810 paddedOverlay.style.top = "0";
25811 paddedOverlay.style.bottom = "0";
25812 paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;
25813 overlay.appendChild(paddedOverlay);
25815 // Determine if we need to compute the display states of the cues. This could
25816 // be the case if a cue's state has been changed since the last computation or
25817 // if it has not been computed yet.
25818 function shouldCompute(cues) {
25819 for (var i = 0; i < cues.length; i++) {
25820 if (cues[i].hasBeenReset || !cues[i].displayState) {
25827 // We don't need to recompute the cues' display states. Just reuse them.
25828 if (!shouldCompute(cues)) {
25829 for (var i = 0; i < cues.length; i++) {
25830 paddedOverlay.appendChild(cues[i].displayState);
25835 var boxPositions = [],
25836 containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay),
25837 fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;
25838 var styleOptions = {
25839 font: fontSize + "px " + FONT_STYLE
25845 for (var i = 0; i < cues.length; i++) {
25848 // Compute the intial position and styles of the cue div.
25849 styleBox = new CueStyleBox(window, cue, styleOptions);
25850 paddedOverlay.appendChild(styleBox.div);
25852 // Move the cue div to it's correct line position.
25853 moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);
25855 // Remember the computed div so that we don't have to recompute it later
25856 // if we don't have too.
25857 cue.displayState = styleBox.div;
25859 boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox));
25864 WebVTT.Parser = function(window, vttjs, decoder) {
25873 this.window = window;
25874 this.vttjs = vttjs;
25875 this.state = "INITIAL";
25877 this.decoder = decoder || new TextDecoder("utf8");
25878 this.regionList = [];
25881 WebVTT.Parser.prototype = {
25882 // If the error is a ParsingError then report it to the consumer if
25883 // possible. If it's not a ParsingError then throw it like normal.
25884 reportOrThrowError: function(e) {
25885 if (e instanceof ParsingError) {
25886 this.onparsingerror && this.onparsingerror(e);
25891 parse: function (data) {
25894 // If there is no data then we won't decode it, but will just try to parse
25895 // whatever is in buffer already. This may occur in circumstances, for
25896 // example when flush() is called.
25898 // Try to decode the data that we received.
25899 self.buffer += self.decoder.decode(data, {stream: true});
25902 function collectNextLine() {
25903 var buffer = self.buffer;
25905 while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') {
25908 var line = buffer.substr(0, pos);
25909 // Advance the buffer early in case we fail below.
25910 if (buffer[pos] === '\r') {
25913 if (buffer[pos] === '\n') {
25916 self.buffer = buffer.substr(pos);
25920 // 3.4 WebVTT region and WebVTT region settings syntax
25921 function parseRegion(input) {
25922 var settings = new Settings();
25924 parseOptions(input, function (k, v) {
25927 settings.set(k, v);
25930 settings.percent(k, v);
25933 settings.integer(k, v);
25935 case "regionanchor":
25936 case "viewportanchor":
25937 var xy = v.split(',');
25938 if (xy.length !== 2) {
25941 // We have to make sure both x and y parse, so use a temporary
25942 // settings object here.
25943 var anchor = new Settings();
25944 anchor.percent("x", xy[0]);
25945 anchor.percent("y", xy[1]);
25946 if (!anchor.has("x") || !anchor.has("y")) {
25949 settings.set(k + "X", anchor.get("x"));
25950 settings.set(k + "Y", anchor.get("y"));
25953 settings.alt(k, v, ["up"]);
25958 // Create the region, using default values for any values that were not
25960 if (settings.has("id")) {
25961 var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)();
25962 region.width = settings.get("width", 100);
25963 region.lines = settings.get("lines", 3);
25964 region.regionAnchorX = settings.get("regionanchorX", 0);
25965 region.regionAnchorY = settings.get("regionanchorY", 100);
25966 region.viewportAnchorX = settings.get("viewportanchorX", 0);
25967 region.viewportAnchorY = settings.get("viewportanchorY", 100);
25968 region.scroll = settings.get("scroll", "");
25969 // Register the region.
25970 self.onregion && self.onregion(region);
25971 // Remember the VTTRegion for later in case we parse any VTTCues that
25973 self.regionList.push({
25974 id: settings.get("id"),
25980 // draft-pantos-http-live-streaming-20
25981 // https://tools.ietf.org/html/draft-pantos-http-live-streaming-20#section-3.5
25983 function parseTimestampMap(input) {
25984 var settings = new Settings();
25986 parseOptions(input, function(k, v) {
25989 settings.integer(k + 'S', v);
25992 settings.set(k + 'L', parseTimeStamp(v));
25997 self.ontimestampmap && self.ontimestampmap({
25998 "MPEGTS": settings.get("MPEGTS"),
25999 "LOCAL": settings.get("LOCAL")
26003 // 3.2 WebVTT metadata header syntax
26004 function parseHeader(input) {
26005 if (input.match(/X-TIMESTAMP-MAP/)) {
26006 // This line contains HLS X-TIMESTAMP-MAP metadata
26007 parseOptions(input, function(k, v) {
26009 case "X-TIMESTAMP-MAP":
26010 parseTimestampMap(v);
26015 parseOptions(input, function (k, v) {
26018 // 3.3 WebVTT region metadata header syntax
26027 // 5.1 WebVTT file parsing.
26030 if (self.state === "INITIAL") {
26031 // We can't start parsing until we have the first line.
26032 if (!/\r\n|\n/.test(self.buffer)) {
26036 line = collectNextLine();
26038 var m = line.match(/^WEBVTT([ \t].*)?$/);
26040 throw new ParsingError(ParsingError.Errors.BadSignature);
26043 self.state = "HEADER";
26046 var alreadyCollectedLine = false;
26047 while (self.buffer) {
26048 // We can't parse a line until we have the full line.
26049 if (!/\r\n|\n/.test(self.buffer)) {
26053 if (!alreadyCollectedLine) {
26054 line = collectNextLine();
26056 alreadyCollectedLine = false;
26059 switch (self.state) {
26061 // 13-18 - Allow a header (metadata) under the WEBVTT line.
26062 if (/:/.test(line)) {
26064 } else if (!line) {
26065 // An empty line terminates the header and starts the body (cues).
26070 // Ignore NOTE blocks.
26076 // Check for the start of NOTE blocks.
26077 if (/^NOTE($|[ \t])/.test(line)) {
26078 self.state = "NOTE";
26081 // 19-29 - Allow any number of line terminators, then initialize new cue values.
26085 self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, "");
26086 self.state = "CUE";
26087 // 30-39 - Check if self line contains an optional identifier or timing data.
26088 if (line.indexOf("-->") === -1) {
26089 self.cue.id = line;
26092 // Process line as start of a cue.
26095 // 40 - Collect cue timings and settings.
26097 parseCue(line, self.cue, self.regionList);
26099 self.reportOrThrowError(e);
26100 // In case of an error ignore rest of the cue.
26102 self.state = "BADCUE";
26105 self.state = "CUETEXT";
26108 var hasSubstring = line.indexOf("-->") !== -1;
26109 // 34 - If we have an empty line then report the cue.
26110 // 35 - If we have the special substring '-->' then report the cue,
26111 // but do not collect the line as we need to process the current
26112 // one as a new cue.
26113 if (!line || hasSubstring && (alreadyCollectedLine = true)) {
26114 // We are done parsing self cue.
26115 self.oncue && self.oncue(self.cue);
26120 if (self.cue.text) {
26121 self.cue.text += "\n";
26123 self.cue.text += line;
26125 case "BADCUE": // BADCUE
26126 // 54-62 - Collect and discard the remaining cue.
26134 self.reportOrThrowError(e);
26136 // If we are currently parsing a cue, report what we have.
26137 if (self.state === "CUETEXT" && self.cue && self.oncue) {
26138 self.oncue(self.cue);
26141 // Enter BADWEBVTT state if header was not parsed correctly otherwise
26142 // another exception occurred so enter BADCUE state.
26143 self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE";
26147 flush: function () {
26150 // Finish decoding the stream.
26151 self.buffer += self.decoder.decode();
26152 // Synthesize the end of the current cue or region.
26153 if (self.cue || self.state === "HEADER") {
26154 self.buffer += "\n\n";
26157 // If we've flushed, parsed, and we're still on the INITIAL state then
26158 // that means we don't have enough of the stream to parse the first
26160 if (self.state === "INITIAL") {
26161 throw new ParsingError(ParsingError.Errors.BadSignature);
26164 self.reportOrThrowError(e);
26166 self.onflush && self.onflush();
26171 global.WebVTT = WebVTT;
26173 }(this, (this.vttjs || {})));
26175 },{}],107:[function(_dereq_,module,exports){
26177 * Copyright 2013 vtt.js Contributors
26179 * Licensed under the Apache License, Version 2.0 (the "License");
26180 * you may not use this file except in compliance with the License.
26181 * You may obtain a copy of the License at
26183 * http://www.apache.org/licenses/LICENSE-2.0
26185 * Unless required by applicable law or agreed to in writing, software
26186 * distributed under the License is distributed on an "AS IS" BASIS,
26187 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26188 * See the License for the specific language governing permissions and
26189 * limitations under the License.
26192 (function(root, vttjs) {
26194 var autoKeyword = "auto";
26195 var directionSetting = {
26200 var alignSetting = {
26208 function findDirectionSetting(value) {
26209 if (typeof value !== "string") {
26212 var dir = directionSetting[value.toLowerCase()];
26213 return dir ? value.toLowerCase() : false;
26216 function findAlignSetting(value) {
26217 if (typeof value !== "string") {
26220 var align = alignSetting[value.toLowerCase()];
26221 return align ? value.toLowerCase() : false;
26224 function extend(obj) {
26226 for (; i < arguments.length; i++) {
26227 var cobj = arguments[i];
26228 for (var p in cobj) {
26236 function VTTCue(startTime, endTime, text) {
26238 var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
26242 cue = document.createElement('custom');
26244 baseObj.enumerable = true;
26248 * Shim implementation specific properties. These properties are not in
26252 // Lets us know when the VTTCue's data has changed in such a way that we need
26253 // to recompute its display state. This lets us compute its display state
26255 cue.hasBeenReset = false;
26258 * VTTCue and TextTrackCue properties
26259 * http://dev.w3.org/html5/webvtt/#vttcue-interface
26263 var _pauseOnExit = false;
26264 var _startTime = startTime;
26265 var _endTime = endTime;
26267 var _region = null;
26268 var _vertical = "";
26269 var _snapToLines = true;
26270 var _line = "auto";
26271 var _lineAlign = "start";
26272 var _position = 50;
26273 var _positionAlign = "middle";
26275 var _align = "middle";
26277 Object.defineProperty(cue,
26278 "id", extend({}, baseObj, {
26282 set: function(value) {
26287 Object.defineProperty(cue,
26288 "pauseOnExit", extend({}, baseObj, {
26290 return _pauseOnExit;
26292 set: function(value) {
26293 _pauseOnExit = !!value;
26297 Object.defineProperty(cue,
26298 "startTime", extend({}, baseObj, {
26302 set: function(value) {
26303 if (typeof value !== "number") {
26304 throw new TypeError("Start time must be set to a number.");
26306 _startTime = value;
26307 this.hasBeenReset = true;
26311 Object.defineProperty(cue,
26312 "endTime", extend({}, baseObj, {
26316 set: function(value) {
26317 if (typeof value !== "number") {
26318 throw new TypeError("End time must be set to a number.");
26321 this.hasBeenReset = true;
26325 Object.defineProperty(cue,
26326 "text", extend({}, baseObj, {
26330 set: function(value) {
26331 _text = "" + value;
26332 this.hasBeenReset = true;
26336 Object.defineProperty(cue,
26337 "region", extend({}, baseObj, {
26341 set: function(value) {
26343 this.hasBeenReset = true;
26347 Object.defineProperty(cue,
26348 "vertical", extend({}, baseObj, {
26352 set: function(value) {
26353 var setting = findDirectionSetting(value);
26354 // Have to check for false because the setting an be an empty string.
26355 if (setting === false) {
26356 throw new SyntaxError("An invalid or illegal string was specified.");
26358 _vertical = setting;
26359 this.hasBeenReset = true;
26363 Object.defineProperty(cue,
26364 "snapToLines", extend({}, baseObj, {
26366 return _snapToLines;
26368 set: function(value) {
26369 _snapToLines = !!value;
26370 this.hasBeenReset = true;
26374 Object.defineProperty(cue,
26375 "line", extend({}, baseObj, {
26379 set: function(value) {
26380 if (typeof value !== "number" && value !== autoKeyword) {
26381 throw new SyntaxError("An invalid number or illegal string was specified.");
26384 this.hasBeenReset = true;
26388 Object.defineProperty(cue,
26389 "lineAlign", extend({}, baseObj, {
26393 set: function(value) {
26394 var setting = findAlignSetting(value);
26396 throw new SyntaxError("An invalid or illegal string was specified.");
26398 _lineAlign = setting;
26399 this.hasBeenReset = true;
26403 Object.defineProperty(cue,
26404 "position", extend({}, baseObj, {
26408 set: function(value) {
26409 if (value < 0 || value > 100) {
26410 throw new Error("Position must be between 0 and 100.");
26413 this.hasBeenReset = true;
26417 Object.defineProperty(cue,
26418 "positionAlign", extend({}, baseObj, {
26420 return _positionAlign;
26422 set: function(value) {
26423 var setting = findAlignSetting(value);
26425 throw new SyntaxError("An invalid or illegal string was specified.");
26427 _positionAlign = setting;
26428 this.hasBeenReset = true;
26432 Object.defineProperty(cue,
26433 "size", extend({}, baseObj, {
26437 set: function(value) {
26438 if (value < 0 || value > 100) {
26439 throw new Error("Size must be between 0 and 100.");
26442 this.hasBeenReset = true;
26446 Object.defineProperty(cue,
26447 "align", extend({}, baseObj, {
26451 set: function(value) {
26452 var setting = findAlignSetting(value);
26454 throw new SyntaxError("An invalid or illegal string was specified.");
26457 this.hasBeenReset = true;
26462 * Other <track> spec defined properties
26465 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state
26466 cue.displayState = undefined;
26477 VTTCue.prototype.getCueAsHTML = function() {
26478 // Assume WebVTT.convertCueToDOMTree is on the global.
26479 return WebVTT.convertCueToDOMTree(window, this.text);
26482 root.VTTCue = root.VTTCue || VTTCue;
26483 vttjs.VTTCue = VTTCue;
26484 }(this, (this.vttjs || {})));
26486 },{}],108:[function(_dereq_,module,exports){
26488 * Copyright 2013 vtt.js Contributors
26490 * Licensed under the Apache License, Version 2.0 (the "License");
26491 * you may not use this file except in compliance with the License.
26492 * You may obtain a copy of the License at
26494 * http://www.apache.org/licenses/LICENSE-2.0
26496 * Unless required by applicable law or agreed to in writing, software
26497 * distributed under the License is distributed on an "AS IS" BASIS,
26498 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26499 * See the License for the specific language governing permissions and
26500 * limitations under the License.
26503 (function(root, vttjs) {
26505 var scrollSetting = {
26510 function findScrollSetting(value) {
26511 if (typeof value !== "string") {
26514 var scroll = scrollSetting[value.toLowerCase()];
26515 return scroll ? value.toLowerCase() : false;
26518 function isValidPercentValue(value) {
26519 return typeof value === "number" && (value >= 0 && value <= 100);
26522 // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface
26523 function VTTRegion() {
26526 var _regionAnchorX = 0;
26527 var _regionAnchorY = 100;
26528 var _viewportAnchorX = 0;
26529 var _viewportAnchorY = 100;
26532 Object.defineProperties(this, {
26538 set: function(value) {
26539 if (!isValidPercentValue(value)) {
26540 throw new Error("Width must be between 0 and 100.");
26550 set: function(value) {
26551 if (typeof value !== "number") {
26552 throw new TypeError("Lines must be set to a number.");
26560 return _regionAnchorY;
26562 set: function(value) {
26563 if (!isValidPercentValue(value)) {
26564 throw new Error("RegionAnchorX must be between 0 and 100.");
26566 _regionAnchorY = value;
26572 return _regionAnchorX;
26574 set: function(value) {
26575 if(!isValidPercentValue(value)) {
26576 throw new Error("RegionAnchorY must be between 0 and 100.");
26578 _regionAnchorX = value;
26581 "viewportAnchorY": {
26584 return _viewportAnchorY;
26586 set: function(value) {
26587 if (!isValidPercentValue(value)) {
26588 throw new Error("ViewportAnchorY must be between 0 and 100.");
26590 _viewportAnchorY = value;
26593 "viewportAnchorX": {
26596 return _viewportAnchorX;
26598 set: function(value) {
26599 if (!isValidPercentValue(value)) {
26600 throw new Error("ViewportAnchorX must be between 0 and 100.");
26602 _viewportAnchorX = value;
26610 set: function(value) {
26611 var setting = findScrollSetting(value);
26612 // Have to check for false as an empty string is a legal value.
26613 if (setting === false) {
26614 throw new SyntaxError("An invalid or illegal string was specified.");
26622 root.VTTRegion = root.VTTRegion || VTTRegion;
26623 vttjs.VTTRegion = VTTRegion;
26624 }(this, (this.vttjs || {})));
26626 },{}],109:[function(_dereq_,module,exports){
26627 arguments[4][95][0].apply(exports,arguments)
26628 },{"95":95}]},{},[93])(93)