Comparar commits
1 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| aa0fe379fa |
@@ -1,95 +1,3 @@
|
||||
<a name="5.19.0"></a>
|
||||
# [5.19.0](https://github.com/videojs/video.js/compare/v6.0.0-RC.5...v5.19.0) (2017-03-15)
|
||||
|
||||
### Features
|
||||
|
||||
* focus play toggle from Big Play Btn on play ([#4132](https://github.com/videojs/video.js/issues/4132)) ([dcc615a](https://github.com/videojs/video.js/commit/dcc615a)), closes [#2729](https://github.com/videojs/video.js/issues/2729)
|
||||
* Make pause on open optional for ModalDialog via options ([#4187](https://github.com/videojs/video.js/issues/4187)) ([4ec3b56](https://github.com/videojs/video.js/commit/4ec3b56))
|
||||
* update videojs-vtt.js and wrap native cues in TextTrack ([#4131](https://github.com/videojs/video.js/issues/4131)) ([3d4aebc](https://github.com/videojs/video.js/commit/3d4aebc)), closes [#4093](https://github.com/videojs/video.js/issues/4093)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* addChild instance names should be toTitleCased ([#4117](https://github.com/videojs/video.js/issues/4117)) ([fa97309](https://github.com/videojs/video.js/commit/fa97309))
|
||||
* cue-points with a startTime of 0 ([#4148](https://github.com/videojs/video.js/issues/4148)) ([e7d4b47](https://github.com/videojs/video.js/commit/e7d4b47))
|
||||
* make load progress buffered regions height 100% ([#4191](https://github.com/videojs/video.js/issues/4191)) ([398c6e9](https://github.com/videojs/video.js/commit/398c6e9))
|
||||
* make mergeOptions behave the same across browsers ([#4090](https://github.com/videojs/video.js/issues/4090)) ([ce19ed5](https://github.com/videojs/video.js/commit/ce19ed5))
|
||||
* make sure audio track hides with one item ([#4203](https://github.com/videojs/video.js/issues/4203)) ([c069655](https://github.com/videojs/video.js/commit/c069655))
|
||||
* **cues:** only copy cue props that don't exist ([#4146](https://github.com/videojs/video.js/issues/4146)) ([de08669](https://github.com/videojs/video.js/commit/de08669))
|
||||
* **cues:** only copy cue props that don't exist ([#4146](https://github.com/videojs/video.js/issues/4146)) ([841d135](https://github.com/videojs/video.js/commit/841d135))
|
||||
* **MenuButton:** Unify behavior of showing/hiding ([#3993](https://github.com/videojs/video.js/issues/3993)) ([4367c69](https://github.com/videojs/video.js/commit/4367c69))
|
||||
* **playback rate menu:** playback rate menu items should be selectable ([#4150](https://github.com/videojs/video.js/issues/4150)) ([288edd1](https://github.com/videojs/video.js/commit/288edd1))
|
||||
* **sass:** import path has cwd once again ([#4076](https://github.com/videojs/video.js/issues/4076)) ([c02c6c6](https://github.com/videojs/video.js/commit/c02c6c6))
|
||||
* **vttjs:** wait till tech el in DOM before loading vttjs ([#4176](https://github.com/videojs/video.js/issues/4176)) ([ad86eec](https://github.com/videojs/video.js/commit/ad86eec))
|
||||
* make sure that cues copy over their id ([#4154](https://github.com/videojs/video.js/issues/4154)) ([072c277](https://github.com/videojs/video.js/commit/072c277))
|
||||
* Patch a memory leak caused by un-removed track listener(s). ([#3975](https://github.com/videojs/video.js/issues/3975)) ([bca44c0](https://github.com/videojs/video.js/commit/bca44c0))
|
||||
* remove title attribute on menu items, fixes [#3699](https://github.com/videojs/video.js/issues/3699) ([#4009](https://github.com/videojs/video.js/issues/4009)) ([91874a3](https://github.com/videojs/video.js/commit/91874a3))
|
||||
* synchronously shim vtt.js when possible ([#4082](https://github.com/videojs/video.js/issues/4082)) ([b5727a6](https://github.com/videojs/video.js/commit/b5727a6))
|
||||
|
||||
### Chores
|
||||
|
||||
* change accessibility test in grunt.js to remove unnecessary warning message. ([#4008](https://github.com/videojs/video.js/issues/4008)) ([daad492](https://github.com/videojs/video.js/commit/daad492))
|
||||
* **build:** lint errors only and silence webpack ([#4153](https://github.com/videojs/video.js/issues/4153)) ([b1ca344](https://github.com/videojs/video.js/commit/b1ca344))
|
||||
* **package:** update swf to 5.2.0 ([#4040](https://github.com/videojs/video.js/issues/4040)) ([dab893b](https://github.com/videojs/video.js/commit/dab893b))
|
||||
* **package:** update video-js-swf to 5.3.0 ([#4161](https://github.com/videojs/video.js/issues/4161)) ([2bcfe21](https://github.com/videojs/video.js/commit/2bcfe21))
|
||||
|
||||
<a name="5.18.4"></a>
|
||||
## [5.18.4](https://github.com/videojs/video.js/compare/v5.18.3...v5.18.4) (2017-03-08)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **vttjs:** wait till tech el in DOM before loading vttjs ([#4176](https://github.com/videojs/video.js/issues/4176)) ([ad86eec](https://github.com/videojs/video.js/commit/ad86eec))
|
||||
|
||||
<a name="5.18.3"></a>
|
||||
## [5.18.3](https://github.com/videojs/video.js/compare/v5.18.2...v5.18.3) (2017-03-06)
|
||||
|
||||
<a name="5.18.1"></a>
|
||||
## [5.18.1](https://github.com/videojs/video.js/compare/v5.18.0...v5.18.1) (2017-03-03)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **cues:** only copy cue props that don't exist ([#4146](https://github.com/videojs/video.js/issues/4146)) ([de08669](https://github.com/videojs/video.js/commit/de08669))
|
||||
* cue-points with a startTime of 0 ([#4148](https://github.com/videojs/video.js/issues/4148)) ([e7d4b47](https://github.com/videojs/video.js/commit/e7d4b47))
|
||||
* make sure that cues copy over their id ([#4154](https://github.com/videojs/video.js/issues/4154)) ([072c277](https://github.com/videojs/video.js/commit/072c277))
|
||||
* **MenuButton:** Unify behavior of showing/hiding ([#3993](https://github.com/videojs/video.js/issues/3993)) ([4367c69](https://github.com/videojs/video.js/commit/4367c69))
|
||||
* **playback rate menu:** playback rate menu items should be selectable ([#4150](https://github.com/videojs/video.js/issues/4150)) ([288edd1](https://github.com/videojs/video.js/commit/288edd1))
|
||||
|
||||
### Chores
|
||||
|
||||
* **build:** lint errors only and silence webpack ([#4153](https://github.com/videojs/video.js/issues/4153)) ([b1ca344](https://github.com/videojs/video.js/commit/b1ca344))
|
||||
* **package:** update video-js-swf to 5.3.0 ([#4161](https://github.com/videojs/video.js/issues/4161)) ([2bcfe21](https://github.com/videojs/video.js/commit/2bcfe21))
|
||||
|
||||
<a name="5.18.0"></a>
|
||||
# [5.18.0](https://github.com/videojs/video.js/compare/v5.17.0...v5.18.0) (2017-02-27)
|
||||
|
||||
### Features
|
||||
|
||||
* focus play toggle from Big Play Btn on play ([#4132](https://github.com/videojs/video.js/issues/4132)) ([dcc615a](https://github.com/videojs/video.js/commit/dcc615a)), closes [#2729](https://github.com/videojs/video.js/issues/2729)
|
||||
* update videojs-vtt.js and wrap native cues in TextTrack ([#4131](https://github.com/videojs/video.js/issues/4131)) ([3d4aebc](https://github.com/videojs/video.js/commit/3d4aebc)), closes [#4093](https://github.com/videojs/video.js/issues/4093)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **sass:** import path has cwd once again ([#4076](https://github.com/videojs/video.js/issues/4076)) ([c02c6c6](https://github.com/videojs/video.js/commit/c02c6c6))
|
||||
* addChild instance names should be toTitleCased ([#4117](https://github.com/videojs/video.js/issues/4117)) ([fa97309](https://github.com/videojs/video.js/commit/fa97309))
|
||||
* make mergeOptions behave the same across browsers ([#4090](https://github.com/videojs/video.js/issues/4090)) ([ce19ed5](https://github.com/videojs/video.js/commit/ce19ed5))
|
||||
* synchronously shim vtt.js when possible ([#4082](https://github.com/videojs/video.js/issues/4082)) ([b5727a6](https://github.com/videojs/video.js/commit/b5727a6))
|
||||
|
||||
<a name="5.17.0"></a>
|
||||
# [5.17.0](https://github.com/videojs/video.js/compare/v5.16.0...v5.17.0) (2017-02-07)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Patch a memory leak caused by un-removed track listener(s). ([#3975](https://github.com/videojs/video.js/issues/3975)) ([bca44c0](https://github.com/videojs/video.js/commit/bca44c0))
|
||||
* remove title attribute on menu items, fixes [#3699](https://github.com/videojs/video.js/issues/3699) ([#4009](https://github.com/videojs/video.js/issues/4009)) ([91874a3](https://github.com/videojs/video.js/commit/91874a3))
|
||||
|
||||
### Chores
|
||||
|
||||
* change accessibility test in grunt.js to remove unnecessary warning message. ([#4008](https://github.com/videojs/video.js/issues/4008)) ([daad492](https://github.com/videojs/video.js/commit/daad492))
|
||||
* **package:** update swf to 5.2.0 ([#4040](https://github.com/videojs/video.js/issues/4040)) ([dab893b](https://github.com/videojs/video.js/commit/dab893b))
|
||||
|
||||
### Documentation
|
||||
|
||||
* minor fix to currentTime() comment: "setting" not "getting" ([#3944](https://github.com/videojs/video.js/issues/3944)) ([6578ed9](https://github.com/videojs/video.js/commit/6578ed9))
|
||||
|
||||
<a name="5.16.0"></a>
|
||||
# [5.16.0](https://github.com/videojs/video.js/compare/v5.15.1...v5.16.0) (2017-01-12)
|
||||
|
||||
|
||||
+4
-4
@@ -450,7 +450,7 @@ module.exports = function(grunt) {
|
||||
}
|
||||
},
|
||||
lint: {
|
||||
command: 'npm run lint -- --errors',
|
||||
command: 'npm run lint',
|
||||
options: {
|
||||
preferLocal: true
|
||||
}
|
||||
@@ -468,7 +468,7 @@ module.exports = function(grunt) {
|
||||
}
|
||||
},
|
||||
webpack: {
|
||||
command: 'webpack --hide-modules test/require/webpack.js build/temp/webpack.js',
|
||||
command: 'webpack test/require/webpack.js build/temp/webpack.js',
|
||||
options: {
|
||||
preferLocal: true
|
||||
}
|
||||
@@ -483,8 +483,8 @@ module.exports = function(grunt) {
|
||||
error: true
|
||||
},
|
||||
ignore: [
|
||||
// Ignore warning about contrast of the "vjs-no-js" fallback link
|
||||
'WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.BgImage'
|
||||
// Ignore the warning about needing <optgroup> elements
|
||||
'WCAG2AA.Principle1.Guideline1_3.1_3_1.H85.2'
|
||||
]
|
||||
|
||||
},
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "video.js",
|
||||
"description": "An HTML5 and Flash video player with a common API and skin for both.",
|
||||
"version": "5.19.0",
|
||||
"version": "5.16.0",
|
||||
"keywords": [
|
||||
"videojs",
|
||||
"html5",
|
||||
|
||||
externo
+1
-1
@@ -690,7 +690,7 @@ body.vjs-full-window {
|
||||
.video-js .vjs-progress-holder .vjs-load-progress div {
|
||||
position: absolute;
|
||||
display: block;
|
||||
height: 100%;
|
||||
height: 0.3em;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 0;
|
||||
|
||||
externo
+1
-1
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
+463
-504
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
externo
+9
-9
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
Arquivo binário não exibido.
externo
+1
-1
@@ -690,7 +690,7 @@ body.vjs-full-window {
|
||||
.video-js .vjs-progress-holder .vjs-load-progress div {
|
||||
position: absolute;
|
||||
display: block;
|
||||
height: 100%;
|
||||
height: 0.3em;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 0;
|
||||
|
||||
externo
+1
-1
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
BIN
Arquivo binário não exibido.
externo
+1062
-978
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
externo
+10
-9
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
@@ -0,0 +1,80 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _button = require('./button.js');
|
||||
|
||||
var _button2 = _interopRequireDefault(_button);
|
||||
|
||||
var _component = require('./component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file big-play-button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The initial play button that shows before the video has played. The hiding of the
|
||||
* `BigPlayButton` get done via CSS and `Player` states.
|
||||
*
|
||||
* @extends Button
|
||||
*/
|
||||
var BigPlayButton = function (_Button) {
|
||||
_inherits(BigPlayButton, _Button);
|
||||
|
||||
function BigPlayButton() {
|
||||
_classCallCheck(this, BigPlayButton);
|
||||
|
||||
return _possibleConstructorReturn(this, _Button.apply(this, arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object. Always returns 'vjs-big-play-button'.
|
||||
*/
|
||||
BigPlayButton.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-big-play-button';
|
||||
};
|
||||
|
||||
/**
|
||||
* This gets called when a `BigPlayButton` "clicked". See {@link ClickableComponent}
|
||||
* for more detailed information on what a click can be.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
*/
|
||||
|
||||
|
||||
BigPlayButton.prototype.handleClick = function handleClick(event) {
|
||||
this.player_.play();
|
||||
};
|
||||
|
||||
return BigPlayButton;
|
||||
}(_button2['default']);
|
||||
|
||||
/**
|
||||
* The text that should display over the `BigPlayButton`s controls. Added to for localization.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
BigPlayButton.prototype.controlText_ = 'Play Video';
|
||||
|
||||
_component2['default'].registerComponent('BigPlayButton', BigPlayButton);
|
||||
exports['default'] = BigPlayButton;
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _clickableComponent = require('./clickable-component.js');
|
||||
|
||||
var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
|
||||
|
||||
var _component = require('./component');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _log = require('./utils/log.js');
|
||||
|
||||
var _log2 = _interopRequireDefault(_log);
|
||||
|
||||
var _obj = require('./utils/obj');
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Base class for all buttons.
|
||||
*
|
||||
* @extends ClickableComponent
|
||||
*/
|
||||
var Button = function (_ClickableComponent) {
|
||||
_inherits(Button, _ClickableComponent);
|
||||
|
||||
function Button() {
|
||||
_classCallCheck(this, Button);
|
||||
|
||||
return _possibleConstructorReturn(this, _ClickableComponent.apply(this, arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Button`s DOM element.
|
||||
*
|
||||
* @param {string} [tag=button]
|
||||
* Element's node type. e.g. 'button'
|
||||
*
|
||||
* @param {Object} [props={}]
|
||||
* An object of properties that should be set on the element.
|
||||
*
|
||||
* @param {Object} [attributes={}]
|
||||
* An object of attributes that should be set on the element.
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that gets created.
|
||||
*/
|
||||
Button.prototype.createEl = function createEl() {
|
||||
var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'button';
|
||||
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
||||
|
||||
props = (0, _obj.assign)({
|
||||
className: this.buildCSSClass()
|
||||
}, props);
|
||||
|
||||
if (tag !== 'button') {
|
||||
_log2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.');
|
||||
|
||||
// Add properties for clickable element which is not a native HTML button
|
||||
props = (0, _obj.assign)({
|
||||
tabIndex: 0
|
||||
}, props);
|
||||
|
||||
// Add ARIA attributes for clickable element which is not a native HTML button
|
||||
attributes = (0, _obj.assign)({
|
||||
role: 'button'
|
||||
}, attributes);
|
||||
}
|
||||
|
||||
// Add attributes for button element
|
||||
attributes = (0, _obj.assign)({
|
||||
|
||||
// Necessary since the default button type is "submit"
|
||||
'type': 'button',
|
||||
|
||||
// let the screen reader user know that the text of the button may change
|
||||
'aria-live': 'polite'
|
||||
}, attributes);
|
||||
|
||||
var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes);
|
||||
|
||||
this.createControlTextEl(el);
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a child `Component` inside of this `Button`.
|
||||
*
|
||||
* @param {string|Component} child
|
||||
* The name or instance of a child to add.
|
||||
*
|
||||
* @param {Object} [options={}]
|
||||
* The key/value store of options that will get passed to children of
|
||||
* the child.
|
||||
*
|
||||
* @return {Component}
|
||||
* The `Component` that gets added as a child. When using a string the
|
||||
* `Component` will get created by this process.
|
||||
*
|
||||
* @deprecated since version 5
|
||||
*/
|
||||
|
||||
|
||||
Button.prototype.addChild = function addChild(child) {
|
||||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
var className = this.constructor.name;
|
||||
|
||||
_log2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.');
|
||||
|
||||
// Avoid the error message generated by ClickableComponent's addChild method
|
||||
return _component2['default'].prototype.addChild.call(this, child, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable the `Button` element so that it can be activated or clicked. Use this with
|
||||
* {@link Button#disable}.
|
||||
*/
|
||||
|
||||
|
||||
Button.prototype.enable = function enable() {
|
||||
_ClickableComponent.prototype.enable.call(this);
|
||||
this.el_.removeAttribute('disabled');
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable the `Button` element so that it cannot be activated or clicked. Use this with
|
||||
* {@link Button#enable}.
|
||||
*/
|
||||
|
||||
|
||||
Button.prototype.disable = function disable() {
|
||||
_ClickableComponent.prototype.disable.call(this);
|
||||
this.el_.setAttribute('disabled', 'disabled');
|
||||
};
|
||||
|
||||
/**
|
||||
* This gets called when a `Button` has focus and `keydown` is triggered via a key
|
||||
* press.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The event that caused this function to get called.
|
||||
*
|
||||
* @listens keydown
|
||||
*/
|
||||
|
||||
|
||||
Button.prototype.handleKeyPress = function handleKeyPress(event) {
|
||||
|
||||
// Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button.
|
||||
if (event.which === 32 || event.which === 13) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Pass keypress handling up for unsupported keys
|
||||
_ClickableComponent.prototype.handleKeyPress.call(this, event);
|
||||
};
|
||||
|
||||
return Button;
|
||||
}(_clickableComponent2['default']);
|
||||
|
||||
_component2['default'].registerComponent('Button', Button);
|
||||
exports['default'] = Button;
|
||||
@@ -0,0 +1,316 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('./component');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _dom = require('./utils/dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
var _events = require('./utils/events.js');
|
||||
|
||||
var Events = _interopRequireWildcard(_events);
|
||||
|
||||
var _fn = require('./utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _log = require('./utils/log.js');
|
||||
|
||||
var _log2 = _interopRequireDefault(_log);
|
||||
|
||||
var _document = require('global/document');
|
||||
|
||||
var _document2 = _interopRequireDefault(_document);
|
||||
|
||||
var _obj = require('./utils/obj');
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Clickable Component which is clickable or keyboard actionable,
|
||||
* but is not a native HTML button.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var ClickableComponent = function (_Component) {
|
||||
_inherits(ClickableComponent, _Component);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function ClickableComponent(player, options) {
|
||||
_classCallCheck(this, ClickableComponent);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
|
||||
|
||||
_this.emitTapEvents();
|
||||
|
||||
_this.enable();
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`s DOM element.
|
||||
*
|
||||
* @param {string} [tag=div]
|
||||
* The element's node type.
|
||||
*
|
||||
* @param {Object} [props={}]
|
||||
* An object of properties that should be set on the element.
|
||||
*
|
||||
* @param {Object} [attributes={}]
|
||||
* An object of attributes that should be set on the element.
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that gets created.
|
||||
*/
|
||||
|
||||
|
||||
ClickableComponent.prototype.createEl = function createEl() {
|
||||
var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
|
||||
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
||||
|
||||
props = (0, _obj.assign)({
|
||||
className: this.buildCSSClass(),
|
||||
tabIndex: 0
|
||||
}, props);
|
||||
|
||||
if (tag === 'button') {
|
||||
_log2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.');
|
||||
}
|
||||
|
||||
// Add ARIA attributes for clickable element which is not a native HTML button
|
||||
attributes = (0, _obj.assign)({
|
||||
'role': 'button',
|
||||
|
||||
// let the screen reader user know that the text of the element may change
|
||||
'aria-live': 'polite'
|
||||
}, attributes);
|
||||
|
||||
this.tabIndex_ = props.tabIndex;
|
||||
|
||||
var el = _Component.prototype.createEl.call(this, tag, props, attributes);
|
||||
|
||||
this.createControlTextEl(el);
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a control text element on this `Component`
|
||||
*
|
||||
* @param {Element} [el]
|
||||
* Parent element for the control text.
|
||||
*
|
||||
* @return {Element}
|
||||
* The control text element that gets created.
|
||||
*/
|
||||
|
||||
|
||||
ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) {
|
||||
this.controlTextEl_ = Dom.createEl('span', {
|
||||
className: 'vjs-control-text'
|
||||
});
|
||||
|
||||
if (el) {
|
||||
el.appendChild(this.controlTextEl_);
|
||||
}
|
||||
|
||||
this.controlText(this.controlText_, el);
|
||||
|
||||
return this.controlTextEl_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get or set the localize text to use for the controls on the `Component`.
|
||||
*
|
||||
* @param {string} [text]
|
||||
* Control text for element.
|
||||
*
|
||||
* @param {Element} [el=this.el()]
|
||||
* Element to set the title on.
|
||||
*
|
||||
* @return {string|ClickableComponent}
|
||||
* - The control text when getting
|
||||
* - Returns itself when setting; method can be chained.
|
||||
*/
|
||||
|
||||
|
||||
ClickableComponent.prototype.controlText = function controlText(text) {
|
||||
var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.el();
|
||||
|
||||
if (!text) {
|
||||
return this.controlText_ || 'Need Text';
|
||||
}
|
||||
|
||||
var localizedText = this.localize(text);
|
||||
|
||||
this.controlText_ = text;
|
||||
this.controlTextEl_.innerHTML = localizedText;
|
||||
el.setAttribute('title', localizedText);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
ClickableComponent.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable this `Component`s element.
|
||||
*
|
||||
* @return {ClickableComponent}
|
||||
* Returns itself; method can be chained.
|
||||
*/
|
||||
|
||||
|
||||
ClickableComponent.prototype.enable = function enable() {
|
||||
this.removeClass('vjs-disabled');
|
||||
this.el_.setAttribute('aria-disabled', 'false');
|
||||
if (typeof this.tabIndex_ !== 'undefined') {
|
||||
this.el_.setAttribute('tabIndex', this.tabIndex_);
|
||||
}
|
||||
this.on('tap', this.handleClick);
|
||||
this.on('click', this.handleClick);
|
||||
this.on('focus', this.handleFocus);
|
||||
this.on('blur', this.handleBlur);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable this `Component`s element.
|
||||
*
|
||||
* @return {ClickableComponent}
|
||||
* Returns itself; method can be chained.
|
||||
*/
|
||||
|
||||
|
||||
ClickableComponent.prototype.disable = function disable() {
|
||||
this.addClass('vjs-disabled');
|
||||
this.el_.setAttribute('aria-disabled', 'true');
|
||||
if (typeof this.tabIndex_ !== 'undefined') {
|
||||
this.el_.removeAttribute('tabIndex');
|
||||
}
|
||||
this.off('tap', this.handleClick);
|
||||
this.off('click', this.handleClick);
|
||||
this.off('focus', this.handleFocus);
|
||||
this.off('blur', this.handleBlur);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* This gets called when a `ClickableComponent` gets:
|
||||
* - Clicked (via the `click` event, listening starts in the constructor)
|
||||
* - Tapped (via the `tap` event, listening starts in the constructor)
|
||||
* - The following things happen in order:
|
||||
* 1. {@link ClickableComponent#handleFocus} is called via a `focus` event on the
|
||||
* `ClickableComponent`.
|
||||
* 2. {@link ClickableComponent#handleFocus} adds a listener for `keydown` on using
|
||||
* {@link ClickableComponent#handleKeyPress}.
|
||||
* 3. `ClickableComponent` has not had a `blur` event (`blur` means that focus was lost). The user presses
|
||||
* the space or enter key.
|
||||
* 4. {@link ClickableComponent#handleKeyPress} calls this function with the `keydown`
|
||||
* event as a parameter.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
|
||||
ClickableComponent.prototype.handleClick = function handleClick(event) {};
|
||||
|
||||
/**
|
||||
* This gets called when a `ClickableComponent` gains focus via a `focus` event.
|
||||
* Turns on listening for `keydown` events. When they happen it
|
||||
* calls `this.handleKeyPress`.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `focus` event that caused this function to be called.
|
||||
*
|
||||
* @listens focus
|
||||
*/
|
||||
|
||||
|
||||
ClickableComponent.prototype.handleFocus = function handleFocus(event) {
|
||||
Events.on(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when this ClickableComponent has focus and a key gets pressed down. By
|
||||
* default it will call `this.handleClick` when the key is space or enter.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `keydown` event that caused this function to be called.
|
||||
*
|
||||
* @listens keydown
|
||||
*/
|
||||
|
||||
|
||||
ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) {
|
||||
|
||||
// Support Space (32) or Enter (13) key operation to fire a click event
|
||||
if (event.which === 32 || event.which === 13) {
|
||||
event.preventDefault();
|
||||
this.handleClick(event);
|
||||
} else if (_Component.prototype.handleKeyPress) {
|
||||
|
||||
// Pass keypress handling up for unsupported keys
|
||||
_Component.prototype.handleKeyPress.call(this, event);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when a `ClickableComponent` loses focus. Turns off the listener for
|
||||
* `keydown` events. Which Stops `this.handleKeyPress` from getting called.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `blur` event that caused this function to be called.
|
||||
*
|
||||
* @listens blur
|
||||
*/
|
||||
|
||||
|
||||
ClickableComponent.prototype.handleBlur = function handleBlur(event) {
|
||||
Events.off(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
|
||||
};
|
||||
|
||||
return ClickableComponent;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('ClickableComponent', ClickableComponent);
|
||||
exports['default'] = ClickableComponent;
|
||||
@@ -0,0 +1,97 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _button = require('./button');
|
||||
|
||||
var _button2 = _interopRequireDefault(_button);
|
||||
|
||||
var _component = require('./component');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file close-button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The `CloseButton` is a `{@link Button}` that fires a `close` event when
|
||||
* it gets clicked.
|
||||
*
|
||||
* @extends Button
|
||||
*/
|
||||
var CloseButton = function (_Button) {
|
||||
_inherits(CloseButton, _Button);
|
||||
|
||||
/**
|
||||
* Creates an instance of the this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function CloseButton(player, options) {
|
||||
_classCallCheck(this, CloseButton);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
|
||||
|
||||
_this.controlText(options && options.controlText || _this.localize('Close'));
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
CloseButton.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* This gets called when a `CloseButton` gets clicked. See
|
||||
* {@link ClickableComponent#handleClick} for more information on when this will be
|
||||
* triggered
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
* @fires CloseButton#close
|
||||
*/
|
||||
|
||||
|
||||
CloseButton.prototype.handleClick = function handleClick(event) {
|
||||
|
||||
/**
|
||||
* Triggered when the a `CloseButton` is clicked.
|
||||
*
|
||||
* @event CloseButton#close
|
||||
* @type {EventTarget~Event}
|
||||
*
|
||||
* @property {boolean} [bubbles=false]
|
||||
* set to false so that the close event does not
|
||||
* bubble up to parents if there is no listener
|
||||
*/
|
||||
this.trigger({ type: 'close', bubbles: false });
|
||||
};
|
||||
|
||||
return CloseButton;
|
||||
}(_button2['default']);
|
||||
|
||||
_component2['default'].registerComponent('CloseButton', CloseButton);
|
||||
exports['default'] = CloseButton;
|
||||
+1816
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,116 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _trackButton = require('../track-button.js');
|
||||
|
||||
var _trackButton2 = _interopRequireDefault(_trackButton);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _audioTrackMenuItem = require('./audio-track-menu-item.js');
|
||||
|
||||
var _audioTrackMenuItem2 = _interopRequireDefault(_audioTrackMenuItem);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file audio-track-button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The base class for buttons that toggle specific {@link AudioTrack} types.
|
||||
*
|
||||
* @extends TrackButton
|
||||
*/
|
||||
var AudioTrackButton = function (_TrackButton) {
|
||||
_inherits(AudioTrackButton, _TrackButton);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options={}]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function AudioTrackButton(player) {
|
||||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
_classCallCheck(this, AudioTrackButton);
|
||||
|
||||
options.tracks = player.audioTracks && player.audioTracks();
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _TrackButton.call(this, player, options));
|
||||
|
||||
_this.el_.setAttribute('aria-label', 'Audio Menu');
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
AudioTrackButton.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-audio-button ' + _TrackButton.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a menu item for each audio track
|
||||
*
|
||||
* @param {AudioTrackMenuItem[]} [items=[]]
|
||||
* An array of existing menu items to use.
|
||||
*
|
||||
* @return {AudioTrackMenuItem[]}
|
||||
* An array of menu items
|
||||
*/
|
||||
|
||||
|
||||
AudioTrackButton.prototype.createItems = function createItems() {
|
||||
var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
||||
|
||||
var tracks = this.player_.audioTracks && this.player_.audioTracks();
|
||||
|
||||
if (!tracks) {
|
||||
return items;
|
||||
}
|
||||
|
||||
for (var i = 0; i < tracks.length; i++) {
|
||||
var track = tracks[i];
|
||||
|
||||
items.push(new _audioTrackMenuItem2['default'](this.player_, {
|
||||
track: track,
|
||||
// MenuItem is selectable
|
||||
selectable: true
|
||||
}));
|
||||
}
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
return AudioTrackButton;
|
||||
}(_trackButton2['default']);
|
||||
|
||||
/**
|
||||
* The text that should display over the `AudioTrackButton`s controls. Added for localization.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
AudioTrackButton.prototype.controlText_ = 'Audio Track';
|
||||
_component2['default'].registerComponent('AudioTrackButton', AudioTrackButton);
|
||||
exports['default'] = AudioTrackButton;
|
||||
@@ -0,0 +1,121 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _menuItem = require('../../menu/menu-item.js');
|
||||
|
||||
var _menuItem2 = _interopRequireDefault(_menuItem);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _fn = require('../../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file audio-track-menu-item.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* An {@link AudioTrack} {@link MenuItem}
|
||||
*
|
||||
* @extends MenuItem
|
||||
*/
|
||||
var AudioTrackMenuItem = function (_MenuItem) {
|
||||
_inherits(AudioTrackMenuItem, _MenuItem);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function AudioTrackMenuItem(player, options) {
|
||||
_classCallCheck(this, AudioTrackMenuItem);
|
||||
|
||||
var track = options.track;
|
||||
var tracks = player.audioTracks();
|
||||
|
||||
// Modify options for parent MenuItem class's init.
|
||||
options.label = track.label || track.language || 'Unknown';
|
||||
options.selected = track.enabled;
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
|
||||
|
||||
_this.track = track;
|
||||
|
||||
if (tracks) {
|
||||
(function () {
|
||||
var changeHandler = Fn.bind(_this, _this.handleTracksChange);
|
||||
|
||||
tracks.addEventListener('change', changeHandler);
|
||||
_this.on('dispose', function () {
|
||||
tracks.removeEventListener('change', changeHandler);
|
||||
});
|
||||
})();
|
||||
}
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called when an `AudioTrackMenuItem is "clicked". See {@link ClickableComponent}
|
||||
* for more detailed information on what a click can be.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
*/
|
||||
|
||||
|
||||
AudioTrackMenuItem.prototype.handleClick = function handleClick(event) {
|
||||
var tracks = this.player_.audioTracks();
|
||||
|
||||
_MenuItem.prototype.handleClick.call(this, event);
|
||||
|
||||
if (!tracks) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < tracks.length; i++) {
|
||||
var track = tracks[i];
|
||||
|
||||
track.enabled = track === this.track;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle any {@link AudioTrack} change.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The {@link AudioTrackList#change} event that caused this to run.
|
||||
*
|
||||
* @listens AudioTrackList#change
|
||||
*/
|
||||
|
||||
|
||||
AudioTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
|
||||
this.selected(this.track.enabled);
|
||||
};
|
||||
|
||||
return AudioTrackMenuItem;
|
||||
}(_menuItem2['default']);
|
||||
|
||||
_component2['default'].registerComponent('AudioTrackMenuItem', AudioTrackMenuItem);
|
||||
exports['default'] = AudioTrackMenuItem;
|
||||
@@ -0,0 +1,105 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
require('./play-toggle.js');
|
||||
|
||||
require('./time-controls/current-time-display.js');
|
||||
|
||||
require('./time-controls/duration-display.js');
|
||||
|
||||
require('./time-controls/time-divider.js');
|
||||
|
||||
require('./time-controls/remaining-time-display.js');
|
||||
|
||||
require('./live-display.js');
|
||||
|
||||
require('./progress-control/progress-control.js');
|
||||
|
||||
require('./fullscreen-toggle.js');
|
||||
|
||||
require('./volume-control/volume-control.js');
|
||||
|
||||
require('./volume-menu-button.js');
|
||||
|
||||
require('./mute-toggle.js');
|
||||
|
||||
require('./text-track-controls/chapters-button.js');
|
||||
|
||||
require('./text-track-controls/descriptions-button.js');
|
||||
|
||||
require('./text-track-controls/subtitles-button.js');
|
||||
|
||||
require('./text-track-controls/captions-button.js');
|
||||
|
||||
require('./audio-track-controls/audio-track-button.js');
|
||||
|
||||
require('./playback-rate-menu/playback-rate-menu-button.js');
|
||||
|
||||
require('./spacer-controls/custom-control-spacer.js');
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file control-bar.js
|
||||
*/
|
||||
|
||||
|
||||
// Required children
|
||||
|
||||
|
||||
/**
|
||||
* Container of main controls.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var ControlBar = function (_Component) {
|
||||
_inherits(ControlBar, _Component);
|
||||
|
||||
function ControlBar() {
|
||||
_classCallCheck(this, ControlBar);
|
||||
|
||||
return _possibleConstructorReturn(this, _Component.apply(this, arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
ControlBar.prototype.createEl = function createEl() {
|
||||
return _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-control-bar',
|
||||
dir: 'ltr'
|
||||
}, {
|
||||
// The control bar is a group, so it can contain menuitems
|
||||
role: 'group'
|
||||
});
|
||||
};
|
||||
|
||||
return ControlBar;
|
||||
}(_component2['default']);
|
||||
|
||||
/**
|
||||
* Default options for `ControlBar`
|
||||
*
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
ControlBar.prototype.options_ = {
|
||||
children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subtitlesButton', 'captionsButton', 'audioTrackButton', 'fullscreenToggle']
|
||||
};
|
||||
|
||||
_component2['default'].registerComponent('ControlBar', ControlBar);
|
||||
exports['default'] = ControlBar;
|
||||
@@ -0,0 +1,116 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _button = require('../button.js');
|
||||
|
||||
var _button2 = _interopRequireDefault(_button);
|
||||
|
||||
var _component = require('../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file fullscreen-toggle.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Toggle fullscreen video
|
||||
*
|
||||
* @extends Button
|
||||
*/
|
||||
var FullscreenToggle = function (_Button) {
|
||||
_inherits(FullscreenToggle, _Button);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function FullscreenToggle(player, options) {
|
||||
_classCallCheck(this, FullscreenToggle);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
|
||||
|
||||
_this.on(player, 'fullscreenchange', _this.handleFullscreenChange);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles fullscreenchange on the player and change control text accordingly.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The {@link Player#fullscreenchange} event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens Player#fullscreenchange
|
||||
*/
|
||||
|
||||
|
||||
FullscreenToggle.prototype.handleFullscreenChange = function handleFullscreenChange(event) {
|
||||
if (this.player_.isFullscreen()) {
|
||||
this.controlText('Non-Fullscreen');
|
||||
} else {
|
||||
this.controlText('Fullscreen');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This gets called when an `FullscreenToggle` is "clicked". See
|
||||
* {@link ClickableComponent} for more detailed information on what a click can be.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
*/
|
||||
|
||||
|
||||
FullscreenToggle.prototype.handleClick = function handleClick(event) {
|
||||
if (!this.player_.isFullscreen()) {
|
||||
this.player_.requestFullscreen();
|
||||
} else {
|
||||
this.player_.exitFullscreen();
|
||||
}
|
||||
};
|
||||
|
||||
return FullscreenToggle;
|
||||
}(_button2['default']);
|
||||
|
||||
/**
|
||||
* The text that should display over the `FullscreenToggle`s controls. Added for localization.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
FullscreenToggle.prototype.controlText_ = 'Fullscreen';
|
||||
|
||||
_component2['default'].registerComponent('FullscreenToggle', FullscreenToggle);
|
||||
exports['default'] = FullscreenToggle;
|
||||
@@ -0,0 +1,102 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../component');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _dom = require('../utils/dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file live-display.js
|
||||
*/
|
||||
|
||||
|
||||
// TODO - Future make it click to snap to live
|
||||
|
||||
/**
|
||||
* Displays the live indicator when duration is Infinity.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var LiveDisplay = function (_Component) {
|
||||
_inherits(LiveDisplay, _Component);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function LiveDisplay(player, options) {
|
||||
_classCallCheck(this, LiveDisplay);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
|
||||
|
||||
_this.updateShowing();
|
||||
_this.on(_this.player(), 'durationchange', _this.updateShowing);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
LiveDisplay.prototype.createEl = function createEl() {
|
||||
var el = _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-live-control vjs-control'
|
||||
});
|
||||
|
||||
this.contentEl_ = Dom.createEl('div', {
|
||||
className: 'vjs-live-display',
|
||||
innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE')
|
||||
}, {
|
||||
'aria-live': 'off'
|
||||
});
|
||||
|
||||
el.appendChild(this.contentEl_);
|
||||
return el;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check the duration to see if the LiveDisplay should be showing or not. Then show/hide
|
||||
* it accordingly
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The {@link Player#durationchange} event that caused this function to run.
|
||||
*
|
||||
* @listens Player#durationchange
|
||||
*/
|
||||
|
||||
|
||||
LiveDisplay.prototype.updateShowing = function updateShowing(event) {
|
||||
if (this.player().duration() === Infinity) {
|
||||
this.show();
|
||||
} else {
|
||||
this.hide();
|
||||
}
|
||||
};
|
||||
|
||||
return LiveDisplay;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('LiveDisplay', LiveDisplay);
|
||||
exports['default'] = LiveDisplay;
|
||||
@@ -0,0 +1,154 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _button = require('../button');
|
||||
|
||||
var _button2 = _interopRequireDefault(_button);
|
||||
|
||||
var _component = require('../component');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _dom = require('../utils/dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file mute-toggle.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A button component for muting the audio.
|
||||
*
|
||||
* @extends Button
|
||||
*/
|
||||
var MuteToggle = function (_Button) {
|
||||
_inherits(MuteToggle, _Button);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function MuteToggle(player, options) {
|
||||
_classCallCheck(this, MuteToggle);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
|
||||
|
||||
_this.on(player, 'volumechange', _this.update);
|
||||
|
||||
// hide mute toggle if the current tech doesn't support volume control
|
||||
if (player.tech_ && player.tech_.featuresVolumeControl === false) {
|
||||
_this.addClass('vjs-hidden');
|
||||
}
|
||||
|
||||
_this.on(player, 'loadstart', function () {
|
||||
// We need to update the button to account for a default muted state.
|
||||
this.update();
|
||||
|
||||
if (player.tech_.featuresVolumeControl === false) {
|
||||
this.addClass('vjs-hidden');
|
||||
} else {
|
||||
this.removeClass('vjs-hidden');
|
||||
}
|
||||
});
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
MuteToggle.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* This gets called when an `MuteToggle` is "clicked". See
|
||||
* {@link ClickableComponent} for more detailed information on what a click can be.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
*/
|
||||
|
||||
|
||||
MuteToggle.prototype.handleClick = function handleClick(event) {
|
||||
this.player_.muted(this.player_.muted() ? false : true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the state of volume.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The {@link Player#loadstart} event if this function was called through an
|
||||
* event.
|
||||
*
|
||||
* @listens Player#loadstart
|
||||
*/
|
||||
|
||||
|
||||
MuteToggle.prototype.update = function update(event) {
|
||||
var vol = this.player_.volume();
|
||||
var level = 3;
|
||||
|
||||
if (vol === 0 || this.player_.muted()) {
|
||||
level = 0;
|
||||
} else if (vol < 0.33) {
|
||||
level = 1;
|
||||
} else if (vol < 0.67) {
|
||||
level = 2;
|
||||
}
|
||||
|
||||
// Don't rewrite the button text if the actual text doesn't change.
|
||||
// This causes unnecessary and confusing information for screen reader users.
|
||||
// This check is needed because this function gets called every time the volume level is changed.
|
||||
var toMute = this.player_.muted() ? 'Unmute' : 'Mute';
|
||||
|
||||
if (this.controlText() !== toMute) {
|
||||
this.controlText(toMute);
|
||||
}
|
||||
|
||||
// TODO improve muted icon classes
|
||||
for (var i = 0; i < 4; i++) {
|
||||
Dom.removeElClass(this.el_, 'vjs-vol-' + i);
|
||||
}
|
||||
Dom.addElClass(this.el_, 'vjs-vol-' + level);
|
||||
};
|
||||
|
||||
return MuteToggle;
|
||||
}(_button2['default']);
|
||||
|
||||
/**
|
||||
* The text that should display over the `MuteToggle`s controls. Added for localization.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
MuteToggle.prototype.controlText_ = 'Mute';
|
||||
|
||||
_component2['default'].registerComponent('MuteToggle', MuteToggle);
|
||||
exports['default'] = MuteToggle;
|
||||
@@ -0,0 +1,132 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _button = require('../button.js');
|
||||
|
||||
var _button2 = _interopRequireDefault(_button);
|
||||
|
||||
var _component = require('../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file play-toggle.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Button to toggle between play and pause.
|
||||
*
|
||||
* @extends Button
|
||||
*/
|
||||
var PlayToggle = function (_Button) {
|
||||
_inherits(PlayToggle, _Button);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function PlayToggle(player, options) {
|
||||
_classCallCheck(this, PlayToggle);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
|
||||
|
||||
_this.on(player, 'play', _this.handlePlay);
|
||||
_this.on(player, 'pause', _this.handlePause);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
PlayToggle.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* This gets called when an `PlayToggle` is "clicked". See
|
||||
* {@link ClickableComponent} for more detailed information on what a click can be.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
*/
|
||||
|
||||
|
||||
PlayToggle.prototype.handleClick = function handleClick(event) {
|
||||
if (this.player_.paused()) {
|
||||
this.player_.play();
|
||||
} else {
|
||||
this.player_.pause();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the vjs-playing class to the element so it can change appearance.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The event that caused this function to run.
|
||||
*
|
||||
* @listens Player#play
|
||||
*/
|
||||
|
||||
|
||||
PlayToggle.prototype.handlePlay = function handlePlay(event) {
|
||||
this.removeClass('vjs-paused');
|
||||
this.addClass('vjs-playing');
|
||||
// change the button text to "Pause"
|
||||
this.controlText('Pause');
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the vjs-paused class to the element so it can change appearance.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The event that caused this function to run.
|
||||
*
|
||||
* @listens Player#pause
|
||||
*/
|
||||
|
||||
|
||||
PlayToggle.prototype.handlePause = function handlePause(event) {
|
||||
this.removeClass('vjs-playing');
|
||||
this.addClass('vjs-paused');
|
||||
// change the button text to "Play"
|
||||
this.controlText('Play');
|
||||
};
|
||||
|
||||
return PlayToggle;
|
||||
}(_button2['default']);
|
||||
|
||||
/**
|
||||
* The text that should display over the `PlayToggle`s controls. Added for localization.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
PlayToggle.prototype.controlText_ = 'Play';
|
||||
|
||||
_component2['default'].registerComponent('PlayToggle', PlayToggle);
|
||||
exports['default'] = PlayToggle;
|
||||
@@ -0,0 +1,235 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _menuButton = require('../../menu/menu-button.js');
|
||||
|
||||
var _menuButton2 = _interopRequireDefault(_menuButton);
|
||||
|
||||
var _menu = require('../../menu/menu.js');
|
||||
|
||||
var _menu2 = _interopRequireDefault(_menu);
|
||||
|
||||
var _playbackRateMenuItem = require('./playback-rate-menu-item.js');
|
||||
|
||||
var _playbackRateMenuItem2 = _interopRequireDefault(_playbackRateMenuItem);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _dom = require('../../utils/dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file playback-rate-menu-button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The component for controlling the playback rate.
|
||||
*
|
||||
* @extends MenuButton
|
||||
*/
|
||||
var PlaybackRateMenuButton = function (_MenuButton) {
|
||||
_inherits(PlaybackRateMenuButton, _MenuButton);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function PlaybackRateMenuButton(player, options) {
|
||||
_classCallCheck(this, PlaybackRateMenuButton);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options));
|
||||
|
||||
_this.updateVisibility();
|
||||
_this.updateLabel();
|
||||
|
||||
_this.on(player, 'loadstart', _this.updateVisibility);
|
||||
_this.on(player, 'ratechange', _this.updateLabel);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
PlaybackRateMenuButton.prototype.createEl = function createEl() {
|
||||
var el = _MenuButton.prototype.createEl.call(this);
|
||||
|
||||
this.labelEl_ = Dom.createEl('div', {
|
||||
className: 'vjs-playback-rate-value',
|
||||
innerHTML: 1.0
|
||||
});
|
||||
|
||||
el.appendChild(this.labelEl_);
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the playback rate menu
|
||||
*
|
||||
* @return {Menu}
|
||||
* Menu object populated with {@link PlaybackRateMenuItem}s
|
||||
*/
|
||||
|
||||
|
||||
PlaybackRateMenuButton.prototype.createMenu = function createMenu() {
|
||||
var menu = new _menu2['default'](this.player());
|
||||
var rates = this.playbackRates();
|
||||
|
||||
if (rates) {
|
||||
for (var i = rates.length - 1; i >= 0; i--) {
|
||||
menu.addChild(new _playbackRateMenuItem2['default'](this.player(), { rate: rates[i] + 'x' }));
|
||||
}
|
||||
}
|
||||
|
||||
return menu;
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates ARIA accessibility attributes
|
||||
*/
|
||||
|
||||
|
||||
PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() {
|
||||
// Current playback rate
|
||||
this.el().setAttribute('aria-valuenow', this.player().playbackRate());
|
||||
};
|
||||
|
||||
/**
|
||||
* This gets called when an `PlaybackRateMenuButton` is "clicked". See
|
||||
* {@link ClickableComponent} for more detailed information on what a click can be.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
*/
|
||||
|
||||
|
||||
PlaybackRateMenuButton.prototype.handleClick = function handleClick(event) {
|
||||
// select next rate option
|
||||
var currentRate = this.player().playbackRate();
|
||||
var rates = this.playbackRates();
|
||||
|
||||
// this will select first one if the last one currently selected
|
||||
var newRate = rates[0];
|
||||
|
||||
for (var i = 0; i < rates.length; i++) {
|
||||
if (rates[i] > currentRate) {
|
||||
newRate = rates[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.player().playbackRate(newRate);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get possible playback rates
|
||||
*
|
||||
* @return {Array}
|
||||
* All possible playback rates
|
||||
*/
|
||||
|
||||
|
||||
PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() {
|
||||
return this.options_.playbackRates || this.options_.playerOptions && this.options_.playerOptions.playbackRates;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get whether playback rates is supported by the tech
|
||||
* and an array of playback rates exists
|
||||
*
|
||||
* @return {boolean}
|
||||
* Whether changing playback rate is supported
|
||||
*/
|
||||
|
||||
|
||||
PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() {
|
||||
return this.player().tech_ && this.player().tech_.featuresPlaybackRate && this.playbackRates() && this.playbackRates().length > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide playback rate controls when they're no playback rate options to select
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The event that caused this function to run.
|
||||
*
|
||||
* @listens Player#loadstart
|
||||
*/
|
||||
|
||||
|
||||
PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility(event) {
|
||||
if (this.playbackRateSupported()) {
|
||||
this.removeClass('vjs-hidden');
|
||||
} else {
|
||||
this.addClass('vjs-hidden');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update button label when rate changed
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The event that caused this function to run.
|
||||
*
|
||||
* @listens Player#ratechange
|
||||
*/
|
||||
|
||||
|
||||
PlaybackRateMenuButton.prototype.updateLabel = function updateLabel(event) {
|
||||
if (this.playbackRateSupported()) {
|
||||
this.labelEl_.innerHTML = this.player().playbackRate() + 'x';
|
||||
}
|
||||
};
|
||||
|
||||
return PlaybackRateMenuButton;
|
||||
}(_menuButton2['default']);
|
||||
|
||||
/**
|
||||
* The text that should display over the `FullscreenToggle`s controls. Added for localization.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate';
|
||||
|
||||
_component2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton);
|
||||
exports['default'] = PlaybackRateMenuButton;
|
||||
@@ -0,0 +1,106 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _menuItem = require('../../menu/menu-item.js');
|
||||
|
||||
var _menuItem2 = _interopRequireDefault(_menuItem);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file playback-rate-menu-item.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The specific menu item type for selecting a playback rate.
|
||||
*
|
||||
* @extends MenuItem
|
||||
*/
|
||||
var PlaybackRateMenuItem = function (_MenuItem) {
|
||||
_inherits(PlaybackRateMenuItem, _MenuItem);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function PlaybackRateMenuItem(player, options) {
|
||||
_classCallCheck(this, PlaybackRateMenuItem);
|
||||
|
||||
var label = options.rate;
|
||||
var rate = parseFloat(label, 10);
|
||||
|
||||
// Modify options for parent MenuItem class's init.
|
||||
options.label = label;
|
||||
options.selected = rate === 1;
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
|
||||
|
||||
_this.label = label;
|
||||
_this.rate = rate;
|
||||
|
||||
_this.on(player, 'ratechange', _this.update);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called when an `PlaybackRateMenuItem` is "clicked". See
|
||||
* {@link ClickableComponent} for more detailed information on what a click can be.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
*/
|
||||
|
||||
|
||||
PlaybackRateMenuItem.prototype.handleClick = function handleClick(event) {
|
||||
_MenuItem.prototype.handleClick.call(this);
|
||||
this.player().playbackRate(this.rate);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the PlaybackRateMenuItem when the playbackrate changes.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `ratechange` event that caused this function to run.
|
||||
*
|
||||
* @listens Player#ratechange
|
||||
*/
|
||||
|
||||
|
||||
PlaybackRateMenuItem.prototype.update = function update(event) {
|
||||
this.selected(this.player().playbackRate() === this.rate);
|
||||
};
|
||||
|
||||
return PlaybackRateMenuItem;
|
||||
}(_menuItem2['default']);
|
||||
|
||||
/**
|
||||
* The text that should display over the `PlaybackRateMenuItem`s controls. Added for localization.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
PlaybackRateMenuItem.prototype.contentElType = 'button';
|
||||
|
||||
_component2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem);
|
||||
exports['default'] = PlaybackRateMenuItem;
|
||||
@@ -0,0 +1,122 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _dom = require('../../utils/dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file load-progress-bar.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Shows loading progress
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var LoadProgressBar = function (_Component) {
|
||||
_inherits(LoadProgressBar, _Component);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function LoadProgressBar(player, options) {
|
||||
_classCallCheck(this, LoadProgressBar);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
|
||||
|
||||
_this.partEls_ = [];
|
||||
_this.on(player, 'progress', _this.update);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
LoadProgressBar.prototype.createEl = function createEl() {
|
||||
return _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-load-progress',
|
||||
innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Update progress bar
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `progress` event that caused this function to run.
|
||||
*
|
||||
* @listens Player#progress
|
||||
*/
|
||||
|
||||
|
||||
LoadProgressBar.prototype.update = function update(event) {
|
||||
var buffered = this.player_.buffered();
|
||||
var duration = this.player_.duration();
|
||||
var bufferedEnd = this.player_.bufferedEnd();
|
||||
var children = this.partEls_;
|
||||
|
||||
// get the percent width of a time compared to the total end
|
||||
var percentify = function percentify(time, end) {
|
||||
// no NaN
|
||||
var percent = time / end || 0;
|
||||
|
||||
return (percent >= 1 ? 1 : percent) * 100 + '%';
|
||||
};
|
||||
|
||||
// update the width of the progress bar
|
||||
this.el_.style.width = percentify(bufferedEnd, duration);
|
||||
|
||||
// add child elements to represent the individual buffered time ranges
|
||||
for (var i = 0; i < buffered.length; i++) {
|
||||
var start = buffered.start(i);
|
||||
var end = buffered.end(i);
|
||||
var part = children[i];
|
||||
|
||||
if (!part) {
|
||||
part = this.el_.appendChild(Dom.createEl());
|
||||
children[i] = part;
|
||||
}
|
||||
|
||||
// set the percent based on the width of the progress bar (bufferedEnd)
|
||||
part.style.left = percentify(start, bufferedEnd);
|
||||
part.style.width = percentify(end - start, bufferedEnd);
|
||||
}
|
||||
|
||||
// remove unused buffered range elements
|
||||
for (var _i = children.length; _i > buffered.length; _i--) {
|
||||
this.el_.removeChild(children[_i - 1]);
|
||||
}
|
||||
children.length = buffered.length;
|
||||
};
|
||||
|
||||
return LoadProgressBar;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('LoadProgressBar', LoadProgressBar);
|
||||
exports['default'] = LoadProgressBar;
|
||||
@@ -0,0 +1,194 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _dom = require('../../utils/dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
var _fn = require('../../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _formatTime = require('../../utils/format-time.js');
|
||||
|
||||
var _formatTime2 = _interopRequireDefault(_formatTime);
|
||||
|
||||
var _computedStyle = require('../../utils/computed-style.js');
|
||||
|
||||
var _computedStyle2 = _interopRequireDefault(_computedStyle);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file mouse-time-display.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The Mouse Time Display component shows the time you will seek to
|
||||
* when hovering over the progress bar
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var MouseTimeDisplay = function (_Component) {
|
||||
_inherits(MouseTimeDisplay, _Component);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function MouseTimeDisplay(player, options) {
|
||||
_classCallCheck(this, MouseTimeDisplay);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
|
||||
|
||||
if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
|
||||
_this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
|
||||
}
|
||||
|
||||
if (_this.keepTooltipsInside) {
|
||||
_this.tooltip = Dom.createEl('div', { className: 'vjs-time-tooltip' });
|
||||
_this.el().appendChild(_this.tooltip);
|
||||
_this.addClass('vjs-keep-tooltips-inside');
|
||||
}
|
||||
|
||||
_this.update(0, 0);
|
||||
|
||||
player.on('ready', function () {
|
||||
_this.on(player.controlBar.progressControl.el(), 'mousemove', Fn.throttle(Fn.bind(_this, _this.handleMouseMove), 25));
|
||||
});
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
MouseTimeDisplay.prototype.createEl = function createEl() {
|
||||
return _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-mouse-display'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle the mouse move event on the `MouseTimeDisplay`.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `mousemove` event that caused this to event to run.
|
||||
*
|
||||
* @listen mousemove
|
||||
*/
|
||||
|
||||
|
||||
MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) {
|
||||
var duration = this.player_.duration();
|
||||
var newTime = this.calculateDistance(event) * duration;
|
||||
var position = event.pageX - Dom.findElPosition(this.el().parentNode).left;
|
||||
|
||||
this.update(newTime, position);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the time and posistion of the `MouseTimeDisplay`.
|
||||
*
|
||||
* @param {number} newTime
|
||||
* Time to change the `MouseTimeDisplay` to.
|
||||
*
|
||||
* @param {nubmer} position
|
||||
* Postion from the left of the in pixels.
|
||||
*/
|
||||
|
||||
|
||||
MouseTimeDisplay.prototype.update = function update(newTime, position) {
|
||||
var time = (0, _formatTime2['default'])(newTime, this.player_.duration());
|
||||
|
||||
this.el().style.left = position + 'px';
|
||||
this.el().setAttribute('data-current-time', time);
|
||||
|
||||
if (this.keepTooltipsInside) {
|
||||
var clampedPosition = this.clampPosition_(position);
|
||||
var difference = position - clampedPosition + 1;
|
||||
var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width'));
|
||||
var tooltipWidthHalf = tooltipWidth / 2;
|
||||
|
||||
this.tooltip.innerHTML = time;
|
||||
this.tooltip.style.right = '-' + (tooltipWidthHalf - difference) + 'px';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the mouse pointers x coordinate in pixels.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `mousemove` event that was passed to this function by
|
||||
* {@link MouseTimeDisplay#handleMouseMove}
|
||||
*
|
||||
* @return {number}
|
||||
* THe x position in pixels of the mouse pointer.
|
||||
*/
|
||||
|
||||
|
||||
MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) {
|
||||
return Dom.getPointerPosition(this.el().parentNode, event).x;
|
||||
};
|
||||
|
||||
/**
|
||||
* This takes in a horizontal position for the bar and returns a clamped position.
|
||||
* Clamped position means that it will keep the position greater than half the width
|
||||
* of the tooltip and smaller than the player width minus half the width o the tooltip.
|
||||
* It will only clamp the position if `keepTooltipsInside` option is set.
|
||||
*
|
||||
* @param {number} position
|
||||
* The position the bar wants to be
|
||||
*
|
||||
* @return {number}
|
||||
* The (potentially) new clamped position.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
MouseTimeDisplay.prototype.clampPosition_ = function clampPosition_(position) {
|
||||
if (!this.keepTooltipsInside) {
|
||||
return position;
|
||||
}
|
||||
|
||||
var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width'));
|
||||
var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width'));
|
||||
var tooltipWidthHalf = tooltipWidth / 2;
|
||||
var actualPosition = position;
|
||||
|
||||
if (position < tooltipWidthHalf) {
|
||||
actualPosition = Math.ceil(tooltipWidthHalf);
|
||||
} else if (position > playerWidth - tooltipWidthHalf) {
|
||||
actualPosition = Math.floor(playerWidth - tooltipWidthHalf);
|
||||
}
|
||||
|
||||
return actualPosition;
|
||||
};
|
||||
|
||||
return MouseTimeDisplay;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay);
|
||||
exports['default'] = MouseTimeDisplay;
|
||||
@@ -0,0 +1,101 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _fn = require('../../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _formatTime = require('../../utils/format-time.js');
|
||||
|
||||
var _formatTime2 = _interopRequireDefault(_formatTime);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file play-progress-bar.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Shows play progress
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var PlayProgressBar = function (_Component) {
|
||||
_inherits(PlayProgressBar, _Component);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function PlayProgressBar(player, options) {
|
||||
_classCallCheck(this, PlayProgressBar);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
|
||||
|
||||
_this.updateDataAttr();
|
||||
_this.on(player, 'timeupdate', _this.updateDataAttr);
|
||||
player.ready(Fn.bind(_this, _this.updateDataAttr));
|
||||
|
||||
if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
|
||||
_this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
|
||||
}
|
||||
|
||||
if (_this.keepTooltipsInside) {
|
||||
_this.addClass('vjs-keep-tooltips-inside');
|
||||
}
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
PlayProgressBar.prototype.createEl = function createEl() {
|
||||
return _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-play-progress vjs-slider-bar',
|
||||
innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the data-current-time attribute on the `PlayProgressBar`.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `timeupdate` event that caused this to run.
|
||||
*
|
||||
* @listens Player#timeupdate
|
||||
*/
|
||||
|
||||
|
||||
PlayProgressBar.prototype.updateDataAttr = function updateDataAttr(event) {
|
||||
var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
|
||||
|
||||
this.el_.setAttribute('data-current-time', (0, _formatTime2['default'])(time, this.player_.duration()));
|
||||
};
|
||||
|
||||
return PlayProgressBar;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('PlayProgressBar', PlayProgressBar);
|
||||
exports['default'] = PlayProgressBar;
|
||||
@@ -0,0 +1,67 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
require('./seek-bar.js');
|
||||
|
||||
require('./mouse-time-display.js');
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file progress-control.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The Progress Control component contains the seek bar, load progress,
|
||||
* and play progress.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var ProgressControl = function (_Component) {
|
||||
_inherits(ProgressControl, _Component);
|
||||
|
||||
function ProgressControl() {
|
||||
_classCallCheck(this, ProgressControl);
|
||||
|
||||
return _possibleConstructorReturn(this, _Component.apply(this, arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
ProgressControl.prototype.createEl = function createEl() {
|
||||
return _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-progress-control vjs-control'
|
||||
});
|
||||
};
|
||||
|
||||
return ProgressControl;
|
||||
}(_component2['default']);
|
||||
|
||||
/**
|
||||
* Default options for `ProgressControl`
|
||||
*
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
ProgressControl.prototype.options_ = {
|
||||
children: ['seekBar']
|
||||
};
|
||||
|
||||
_component2['default'].registerComponent('ProgressControl', ProgressControl);
|
||||
exports['default'] = ProgressControl;
|
||||
@@ -0,0 +1,260 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _slider = require('../../slider/slider.js');
|
||||
|
||||
var _slider2 = _interopRequireDefault(_slider);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _fn = require('../../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _formatTime = require('../../utils/format-time.js');
|
||||
|
||||
var _formatTime2 = _interopRequireDefault(_formatTime);
|
||||
|
||||
var _computedStyle = require('../../utils/computed-style.js');
|
||||
|
||||
var _computedStyle2 = _interopRequireDefault(_computedStyle);
|
||||
|
||||
require('./load-progress-bar.js');
|
||||
|
||||
require('./play-progress-bar.js');
|
||||
|
||||
require('./tooltip-progress-bar.js');
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file seek-bar.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Seek Bar and holder for the progress bars
|
||||
*
|
||||
* @extends Slider
|
||||
*/
|
||||
var SeekBar = function (_Slider) {
|
||||
_inherits(SeekBar, _Slider);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function SeekBar(player, options) {
|
||||
_classCallCheck(this, SeekBar);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options));
|
||||
|
||||
_this.on(player, 'timeupdate', _this.updateProgress);
|
||||
_this.on(player, 'ended', _this.updateProgress);
|
||||
player.ready(Fn.bind(_this, _this.updateProgress));
|
||||
|
||||
if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
|
||||
_this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
|
||||
}
|
||||
|
||||
if (_this.keepTooltipsInside) {
|
||||
_this.tooltipProgressBar = _this.addChild('TooltipProgressBar');
|
||||
}
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
SeekBar.prototype.createEl = function createEl() {
|
||||
return _Slider.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-progress-holder'
|
||||
}, {
|
||||
'aria-label': 'progress bar'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the seek bars tooltip and width.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `timeupdate` or `ended` event that caused this to run.
|
||||
*
|
||||
* @listens Player#timeupdate
|
||||
* @listens Player#ended
|
||||
*/
|
||||
|
||||
|
||||
SeekBar.prototype.updateProgress = function updateProgress(event) {
|
||||
this.updateAriaAttributes(this.el_);
|
||||
|
||||
if (this.keepTooltipsInside) {
|
||||
this.updateAriaAttributes(this.tooltipProgressBar.el_);
|
||||
this.tooltipProgressBar.el_.style.width = this.bar.el_.style.width;
|
||||
|
||||
var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width'));
|
||||
var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltipProgressBar.tooltip, 'width'));
|
||||
var tooltipStyle = this.tooltipProgressBar.el().style;
|
||||
|
||||
tooltipStyle.maxWidth = Math.floor(playerWidth - tooltipWidth / 2) + 'px';
|
||||
tooltipStyle.minWidth = Math.ceil(tooltipWidth / 2) + 'px';
|
||||
tooltipStyle.right = '-' + tooltipWidth / 2 + 'px';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update ARIA accessibility attributes
|
||||
*
|
||||
* @param {Element} el
|
||||
* The element to update with aria accessibility attributes.
|
||||
*/
|
||||
|
||||
|
||||
SeekBar.prototype.updateAriaAttributes = function updateAriaAttributes(el) {
|
||||
// Allows for smooth scrubbing, when player can't keep up.
|
||||
var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
|
||||
|
||||
// machine readable value of progress bar (percentage complete)
|
||||
el.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2));
|
||||
// human readable value of progress bar (time complete)
|
||||
el.setAttribute('aria-valuetext', (0, _formatTime2['default'])(time, this.player_.duration()));
|
||||
};
|
||||
|
||||
/**
|
||||
* Get percentage of video played
|
||||
*
|
||||
* @return {number}
|
||||
* The percentage played
|
||||
*/
|
||||
|
||||
|
||||
SeekBar.prototype.getPercent = function getPercent() {
|
||||
var percent = this.player_.currentTime() / this.player_.duration();
|
||||
|
||||
return percent >= 1 ? 1 : percent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle mouse down on seek bar
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `mousedown` event that caused this to run.
|
||||
*
|
||||
* @listens mousedown
|
||||
*/
|
||||
|
||||
|
||||
SeekBar.prototype.handleMouseDown = function handleMouseDown(event) {
|
||||
this.player_.scrubbing(true);
|
||||
|
||||
this.videoWasPlaying = !this.player_.paused();
|
||||
this.player_.pause();
|
||||
|
||||
_Slider.prototype.handleMouseDown.call(this, event);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle mouse move on seek bar
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `mousemove` event that caused this to run.
|
||||
*
|
||||
* @listens mousemove
|
||||
*/
|
||||
|
||||
|
||||
SeekBar.prototype.handleMouseMove = function handleMouseMove(event) {
|
||||
var newTime = this.calculateDistance(event) * this.player_.duration();
|
||||
|
||||
// Don't let video end while scrubbing.
|
||||
if (newTime === this.player_.duration()) {
|
||||
newTime = newTime - 0.1;
|
||||
}
|
||||
|
||||
// Set new time (tell player to seek to new time)
|
||||
this.player_.currentTime(newTime);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle mouse up on seek bar
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `mouseup` event that caused this to run.
|
||||
*
|
||||
* @listens mouseup
|
||||
*/
|
||||
|
||||
|
||||
SeekBar.prototype.handleMouseUp = function handleMouseUp(event) {
|
||||
_Slider.prototype.handleMouseUp.call(this, event);
|
||||
|
||||
this.player_.scrubbing(false);
|
||||
if (this.videoWasPlaying) {
|
||||
this.player_.play();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Move more quickly fast forward for keyboard-only users
|
||||
*/
|
||||
|
||||
|
||||
SeekBar.prototype.stepForward = function stepForward() {
|
||||
// more quickly fast forward for keyboard-only users
|
||||
this.player_.currentTime(this.player_.currentTime() + 5);
|
||||
};
|
||||
|
||||
/**
|
||||
* Move more quickly rewind for keyboard-only users
|
||||
*/
|
||||
|
||||
|
||||
SeekBar.prototype.stepBack = function stepBack() {
|
||||
// more quickly rewind for keyboard-only users
|
||||
this.player_.currentTime(this.player_.currentTime() - 5);
|
||||
};
|
||||
|
||||
return SeekBar;
|
||||
}(_slider2['default']);
|
||||
|
||||
/**
|
||||
* Default options for the `SeekBar`
|
||||
*
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
SeekBar.prototype.options_ = {
|
||||
children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'],
|
||||
barName: 'playProgressBar'
|
||||
};
|
||||
|
||||
/**
|
||||
* Call the update event for this Slider when this event happens on the player.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
SeekBar.prototype.playerEvent = 'timeupdate';
|
||||
|
||||
_component2['default'].registerComponent('SeekBar', SeekBar);
|
||||
exports['default'] = SeekBar;
|
||||
@@ -0,0 +1,99 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _fn = require('../../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _formatTime = require('../../utils/format-time.js');
|
||||
|
||||
var _formatTime2 = _interopRequireDefault(_formatTime);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file play-progress-bar.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Shows play progress
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var TooltipProgressBar = function (_Component) {
|
||||
_inherits(TooltipProgressBar, _Component);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function TooltipProgressBar(player, options) {
|
||||
_classCallCheck(this, TooltipProgressBar);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
|
||||
|
||||
_this.updateDataAttr();
|
||||
_this.on(player, 'timeupdate', _this.updateDataAttr);
|
||||
player.ready(Fn.bind(_this, _this.updateDataAttr));
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
TooltipProgressBar.prototype.createEl = function createEl() {
|
||||
var el = _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-tooltip-progress-bar vjs-slider-bar',
|
||||
innerHTML: '<div class="vjs-time-tooltip"></div>\n <span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
|
||||
});
|
||||
|
||||
this.tooltip = el.querySelector('.vjs-time-tooltip');
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
/**
|
||||
* Updatet the data-current-time attribute for TooltipProgressBar
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `timeupdate` event that caused this function to run.
|
||||
*
|
||||
* @listens Player#timeupdate
|
||||
*/
|
||||
|
||||
|
||||
TooltipProgressBar.prototype.updateDataAttr = function updateDataAttr(event) {
|
||||
var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
|
||||
var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration());
|
||||
|
||||
this.el_.setAttribute('data-current-time', formattedTime);
|
||||
this.tooltip.innerHTML = formattedTime;
|
||||
};
|
||||
|
||||
return TooltipProgressBar;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('TooltipProgressBar', TooltipProgressBar);
|
||||
exports['default'] = TooltipProgressBar;
|
||||
@@ -0,0 +1,71 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _spacer = require('./spacer.js');
|
||||
|
||||
var _spacer2 = _interopRequireDefault(_spacer);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file custom-control-spacer.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Spacer specifically meant to be used as an insertion point for new plugins, etc.
|
||||
*
|
||||
* @extends Spacer
|
||||
*/
|
||||
var CustomControlSpacer = function (_Spacer) {
|
||||
_inherits(CustomControlSpacer, _Spacer);
|
||||
|
||||
function CustomControlSpacer() {
|
||||
_classCallCheck(this, CustomControlSpacer);
|
||||
|
||||
return _possibleConstructorReturn(this, _Spacer.apply(this, arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
CustomControlSpacer.prototype.createEl = function createEl() {
|
||||
var el = _Spacer.prototype.createEl.call(this, {
|
||||
className: this.buildCSSClass()
|
||||
});
|
||||
|
||||
// No-flex/table-cell mode requires there be some content
|
||||
// in the cell to fill the remaining space of the table.
|
||||
el.innerHTML = ' ';
|
||||
return el;
|
||||
};
|
||||
|
||||
return CustomControlSpacer;
|
||||
}(_spacer2['default']);
|
||||
|
||||
_component2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer);
|
||||
exports['default'] = CustomControlSpacer;
|
||||
@@ -0,0 +1,64 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file spacer.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Just an empty spacer element that can be used as an append point for plugins, etc.
|
||||
* Also can be used to create space between elements when necessary.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var Spacer = function (_Component) {
|
||||
_inherits(Spacer, _Component);
|
||||
|
||||
function Spacer() {
|
||||
_classCallCheck(this, Spacer);
|
||||
|
||||
return _possibleConstructorReturn(this, _Component.apply(this, arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
Spacer.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
Spacer.prototype.createEl = function createEl() {
|
||||
return _Component.prototype.createEl.call(this, 'div', {
|
||||
className: this.buildCSSClass()
|
||||
});
|
||||
};
|
||||
|
||||
return Spacer;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('Spacer', Spacer);
|
||||
|
||||
exports['default'] = Spacer;
|
||||
@@ -0,0 +1,85 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _textTrackMenuItem = require('./text-track-menu-item.js');
|
||||
|
||||
var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file caption-settings-menu-item.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The menu item for caption track settings menu
|
||||
*
|
||||
* @extends TextTrackMenuItem
|
||||
*/
|
||||
var CaptionSettingsMenuItem = function (_TextTrackMenuItem) {
|
||||
_inherits(CaptionSettingsMenuItem, _TextTrackMenuItem);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function CaptionSettingsMenuItem(player, options) {
|
||||
_classCallCheck(this, CaptionSettingsMenuItem);
|
||||
|
||||
options.track = {
|
||||
player: player,
|
||||
kind: options.kind,
|
||||
label: options.kind + ' settings',
|
||||
selectable: false,
|
||||
'default': false,
|
||||
mode: 'disabled'
|
||||
};
|
||||
|
||||
// CaptionSettingsMenuItem has no concept of 'selected'
|
||||
options.selectable = false;
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
|
||||
|
||||
_this.addClass('vjs-texttrack-settings');
|
||||
_this.controlText(', opens ' + options.kind + ' settings dialog');
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called when an `CaptionSettingsMenuItem` is "clicked". See
|
||||
* {@link ClickableComponent} for more detailed information on what a click can be.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
*/
|
||||
|
||||
|
||||
CaptionSettingsMenuItem.prototype.handleClick = function handleClick(event) {
|
||||
this.player().getChild('textTrackSettings').show();
|
||||
this.player().getChild('textTrackSettings').el_.focus();
|
||||
};
|
||||
|
||||
return CaptionSettingsMenuItem;
|
||||
}(_textTrackMenuItem2['default']);
|
||||
|
||||
_component2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem);
|
||||
exports['default'] = CaptionSettingsMenuItem;
|
||||
@@ -0,0 +1,138 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _textTrackButton = require('./text-track-button.js');
|
||||
|
||||
var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _captionSettingsMenuItem = require('./caption-settings-menu-item.js');
|
||||
|
||||
var _captionSettingsMenuItem2 = _interopRequireDefault(_captionSettingsMenuItem);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file captions-button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The button component for toggling and selecting captions
|
||||
*
|
||||
* @extends TextTrackButton
|
||||
*/
|
||||
var CaptionsButton = function (_TextTrackButton) {
|
||||
_inherits(CaptionsButton, _TextTrackButton);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*
|
||||
* @param {Component~ReadyCallback} [ready]
|
||||
* The function to call when this component is ready.
|
||||
*/
|
||||
function CaptionsButton(player, options, ready) {
|
||||
_classCallCheck(this, CaptionsButton);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
|
||||
|
||||
_this.el_.setAttribute('aria-label', 'Captions Menu');
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
CaptionsButton.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update caption menu items
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `addtrack` or `removetrack` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens TextTrackList#addtrack
|
||||
* @listens TextTrackList#removetrack
|
||||
*/
|
||||
|
||||
|
||||
CaptionsButton.prototype.update = function update(event) {
|
||||
var threshold = 2;
|
||||
|
||||
_TextTrackButton.prototype.update.call(this);
|
||||
|
||||
// if native, then threshold is 1 because no settings button
|
||||
if (this.player().tech_ && this.player().tech_.featuresNativeTextTracks) {
|
||||
threshold = 1;
|
||||
}
|
||||
|
||||
if (this.items && this.items.length > threshold) {
|
||||
this.show();
|
||||
} else {
|
||||
this.hide();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create caption menu items
|
||||
*
|
||||
* @return {CaptionSettingsMenuItem[]}
|
||||
* The array of current menu items.
|
||||
*/
|
||||
|
||||
|
||||
CaptionsButton.prototype.createItems = function createItems() {
|
||||
var items = [];
|
||||
|
||||
if (!(this.player().tech_ && this.player().tech_.featuresNativeTextTracks)) {
|
||||
items.push(new _captionSettingsMenuItem2['default'](this.player_, { kind: this.kind_ }));
|
||||
}
|
||||
|
||||
return _TextTrackButton.prototype.createItems.call(this, items);
|
||||
};
|
||||
|
||||
return CaptionsButton;
|
||||
}(_textTrackButton2['default']);
|
||||
|
||||
/**
|
||||
* `kind` of TextTrack to look for to associate it with this menu.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
CaptionsButton.prototype.kind_ = 'captions';
|
||||
|
||||
/**
|
||||
* The text that should display over the `CaptionsButton`s controls. Added for localization.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
CaptionsButton.prototype.controlText_ = 'Captions';
|
||||
|
||||
_component2['default'].registerComponent('CaptionsButton', CaptionsButton);
|
||||
exports['default'] = CaptionsButton;
|
||||
@@ -0,0 +1,240 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _textTrackButton = require('./text-track-button.js');
|
||||
|
||||
var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _chaptersTrackMenuItem = require('./chapters-track-menu-item.js');
|
||||
|
||||
var _chaptersTrackMenuItem2 = _interopRequireDefault(_chaptersTrackMenuItem);
|
||||
|
||||
var _toTitleCase = require('../../utils/to-title-case.js');
|
||||
|
||||
var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file chapters-button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The button component for toggling and selecting chapters
|
||||
* Chapters act much differently than other text tracks
|
||||
* Cues are navigation vs. other tracks of alternative languages
|
||||
*
|
||||
* @extends TextTrackButton
|
||||
*/
|
||||
var ChaptersButton = function (_TextTrackButton) {
|
||||
_inherits(ChaptersButton, _TextTrackButton);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*
|
||||
* @param {Component~ReadyCallback} [ready]
|
||||
* The function to call when this function is ready.
|
||||
*/
|
||||
function ChaptersButton(player, options, ready) {
|
||||
_classCallCheck(this, ChaptersButton);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
|
||||
|
||||
_this.el_.setAttribute('aria-label', 'Chapters Menu');
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
ChaptersButton.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the menu based on the current state of its items.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* An event that triggered this function to run.
|
||||
*
|
||||
* @listens TextTrackList#addtrack
|
||||
* @listens TextTrackList#removetrack
|
||||
* @listens TextTrackList#change
|
||||
*/
|
||||
|
||||
|
||||
ChaptersButton.prototype.update = function update(event) {
|
||||
if (!this.track_ || event && (event.type === 'addtrack' || event.type === 'removetrack')) {
|
||||
this.setTrack(this.findChaptersTrack());
|
||||
}
|
||||
_TextTrackButton.prototype.update.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the currently selected track for the chapters button.
|
||||
*
|
||||
* @param {TextTrack} track
|
||||
* The new track to select. Nothing will change if this is the currently selected
|
||||
* track.
|
||||
*/
|
||||
|
||||
|
||||
ChaptersButton.prototype.setTrack = function setTrack(track) {
|
||||
if (this.track_ === track) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.updateHandler_) {
|
||||
this.updateHandler_ = this.update.bind(this);
|
||||
}
|
||||
|
||||
// here this.track_ refers to the old track instance
|
||||
if (this.track_) {
|
||||
var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
|
||||
|
||||
if (remoteTextTrackEl) {
|
||||
remoteTextTrackEl.removeEventListener('load', this.updateHandler_);
|
||||
}
|
||||
|
||||
this.track_ = null;
|
||||
}
|
||||
|
||||
this.track_ = track;
|
||||
|
||||
// here this.track_ refers to the new track instance
|
||||
if (this.track_) {
|
||||
this.track_.mode = 'hidden';
|
||||
|
||||
var _remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
|
||||
|
||||
if (_remoteTextTrackEl) {
|
||||
_remoteTextTrackEl.addEventListener('load', this.updateHandler_);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the track object that is currently in use by this ChaptersButton
|
||||
*
|
||||
* @return {TextTrack|undefined}
|
||||
* The current track or undefined if none was found.
|
||||
*/
|
||||
|
||||
|
||||
ChaptersButton.prototype.findChaptersTrack = function findChaptersTrack() {
|
||||
var tracks = this.player_.textTracks() || [];
|
||||
|
||||
for (var i = tracks.length - 1; i >= 0; i--) {
|
||||
// We will always choose the last track as our chaptersTrack
|
||||
var track = tracks[i];
|
||||
|
||||
if (track.kind === this.kind_) {
|
||||
return track;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the caption for the ChaptersButton based on the track label. This will also
|
||||
* use the current tracks localized kind as a fallback if a label does not exist.
|
||||
*
|
||||
* @return {string}
|
||||
* The tracks current label or the localized track kind.
|
||||
*/
|
||||
|
||||
|
||||
ChaptersButton.prototype.getMenuCaption = function getMenuCaption() {
|
||||
if (this.track_ && this.track_.label) {
|
||||
return this.track_.label;
|
||||
}
|
||||
return this.localize((0, _toTitleCase2['default'])(this.kind_));
|
||||
};
|
||||
|
||||
/**
|
||||
* Create menu from chapter track
|
||||
*
|
||||
* @return {Menu}
|
||||
* New menu for the chapter buttons
|
||||
*/
|
||||
|
||||
|
||||
ChaptersButton.prototype.createMenu = function createMenu() {
|
||||
this.options_.title = this.getMenuCaption();
|
||||
return _TextTrackButton.prototype.createMenu.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a menu item for each text track
|
||||
*
|
||||
* @return {TextTrackMenuItem[]}
|
||||
* Array of menu items
|
||||
*/
|
||||
|
||||
|
||||
ChaptersButton.prototype.createItems = function createItems() {
|
||||
var items = [];
|
||||
|
||||
if (!this.track_) {
|
||||
return items;
|
||||
}
|
||||
|
||||
var cues = this.track_.cues;
|
||||
|
||||
if (!cues) {
|
||||
return items;
|
||||
}
|
||||
|
||||
for (var i = 0, l = cues.length; i < l; i++) {
|
||||
var cue = cues[i];
|
||||
var mi = new _chaptersTrackMenuItem2['default'](this.player_, { track: this.track_, cue: cue });
|
||||
|
||||
items.push(mi);
|
||||
}
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
return ChaptersButton;
|
||||
}(_textTrackButton2['default']);
|
||||
|
||||
/**
|
||||
* `kind` of TextTrack to look for to associate it with this menu.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
ChaptersButton.prototype.kind_ = 'chapters';
|
||||
|
||||
/**
|
||||
* The text that should display over the `ChaptersButton`s controls. Added for localization.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
ChaptersButton.prototype.controlText_ = 'Chapters';
|
||||
|
||||
_component2['default'].registerComponent('ChaptersButton', ChaptersButton);
|
||||
exports['default'] = ChaptersButton;
|
||||
@@ -0,0 +1,108 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _menuItem = require('../../menu/menu-item.js');
|
||||
|
||||
var _menuItem2 = _interopRequireDefault(_menuItem);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _fn = require('../../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file chapters-track-menu-item.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The chapter track menu item
|
||||
*
|
||||
* @extends MenuItem
|
||||
*/
|
||||
var ChaptersTrackMenuItem = function (_MenuItem) {
|
||||
_inherits(ChaptersTrackMenuItem, _MenuItem);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function ChaptersTrackMenuItem(player, options) {
|
||||
_classCallCheck(this, ChaptersTrackMenuItem);
|
||||
|
||||
var track = options.track;
|
||||
var cue = options.cue;
|
||||
var currentTime = player.currentTime();
|
||||
|
||||
// Modify options for parent MenuItem class's init.
|
||||
options.selectable = true;
|
||||
options.label = cue.text;
|
||||
options.selected = cue.startTime <= currentTime && currentTime < cue.endTime;
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
|
||||
|
||||
_this.track = track;
|
||||
_this.cue = cue;
|
||||
track.addEventListener('cuechange', Fn.bind(_this, _this.update));
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called when an `ChaptersTrackMenuItem` is "clicked". See
|
||||
* {@link ClickableComponent} for more detailed information on what a click can be.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
*/
|
||||
|
||||
|
||||
ChaptersTrackMenuItem.prototype.handleClick = function handleClick(event) {
|
||||
_MenuItem.prototype.handleClick.call(this);
|
||||
this.player_.currentTime(this.cue.startTime);
|
||||
this.update(this.cue.startTime);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update chapter menu item
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `cuechange` event that caused this function to run.
|
||||
*
|
||||
* @listens TextTrack#cuechange
|
||||
*/
|
||||
|
||||
|
||||
ChaptersTrackMenuItem.prototype.update = function update(event) {
|
||||
var cue = this.cue;
|
||||
var currentTime = this.player_.currentTime();
|
||||
|
||||
// vjs.log(currentTime, cue.startTime);
|
||||
this.selected(cue.startTime <= currentTime && currentTime < cue.endTime);
|
||||
};
|
||||
|
||||
return ChaptersTrackMenuItem;
|
||||
}(_menuItem2['default']);
|
||||
|
||||
_component2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem);
|
||||
exports['default'] = ChaptersTrackMenuItem;
|
||||
@@ -0,0 +1,138 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _textTrackButton = require('./text-track-button.js');
|
||||
|
||||
var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _fn = require('../../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file descriptions-button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The button component for toggling and selecting descriptions
|
||||
*
|
||||
* @extends TextTrackButton
|
||||
*/
|
||||
var DescriptionsButton = function (_TextTrackButton) {
|
||||
_inherits(DescriptionsButton, _TextTrackButton);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*
|
||||
* @param {Component~ReadyCallback} [ready]
|
||||
* The function to call when this component is ready.
|
||||
*/
|
||||
function DescriptionsButton(player, options, ready) {
|
||||
_classCallCheck(this, DescriptionsButton);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
|
||||
|
||||
_this.el_.setAttribute('aria-label', 'Descriptions Menu');
|
||||
|
||||
var tracks = player.textTracks();
|
||||
|
||||
if (tracks) {
|
||||
(function () {
|
||||
var changeHandler = Fn.bind(_this, _this.handleTracksChange);
|
||||
|
||||
tracks.addEventListener('change', changeHandler);
|
||||
_this.on('dispose', function () {
|
||||
tracks.removeEventListener('change', changeHandler);
|
||||
});
|
||||
})();
|
||||
}
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle text track change
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The event that caused this function to run
|
||||
*
|
||||
* @listens TextTrackList#change
|
||||
*/
|
||||
|
||||
|
||||
DescriptionsButton.prototype.handleTracksChange = function handleTracksChange(event) {
|
||||
var tracks = this.player().textTracks();
|
||||
var disabled = false;
|
||||
|
||||
// Check whether a track of a different kind is showing
|
||||
for (var i = 0, l = tracks.length; i < l; i++) {
|
||||
var track = tracks[i];
|
||||
|
||||
if (track.kind !== this.kind_ && track.mode === 'showing') {
|
||||
disabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If another track is showing, disable this menu button
|
||||
if (disabled) {
|
||||
this.disable();
|
||||
} else {
|
||||
this.enable();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
DescriptionsButton.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
return DescriptionsButton;
|
||||
}(_textTrackButton2['default']);
|
||||
|
||||
/**
|
||||
* `kind` of TextTrack to look for to associate it with this menu.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
DescriptionsButton.prototype.kind_ = 'descriptions';
|
||||
|
||||
/**
|
||||
* The text that should display over the `DescriptionsButton`s controls. Added for localization.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
DescriptionsButton.prototype.controlText_ = 'Descriptions';
|
||||
|
||||
_component2['default'].registerComponent('DescriptionsButton', DescriptionsButton);
|
||||
exports['default'] = DescriptionsButton;
|
||||
@@ -0,0 +1,91 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _textTrackMenuItem = require('./text-track-menu-item.js');
|
||||
|
||||
var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file off-text-track-menu-item.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A special menu item for turning of a specific type of text track
|
||||
*
|
||||
* @extends TextTrackMenuItem
|
||||
*/
|
||||
var OffTextTrackMenuItem = function (_TextTrackMenuItem) {
|
||||
_inherits(OffTextTrackMenuItem, _TextTrackMenuItem);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function OffTextTrackMenuItem(player, options) {
|
||||
_classCallCheck(this, OffTextTrackMenuItem);
|
||||
|
||||
// Create pseudo track info
|
||||
// Requires options['kind']
|
||||
options.track = {
|
||||
player: player,
|
||||
kind: options.kind,
|
||||
label: options.kind + ' off',
|
||||
'default': false,
|
||||
mode: 'disabled'
|
||||
};
|
||||
|
||||
// MenuItem is selectable
|
||||
options.selectable = true;
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
|
||||
|
||||
_this.selected(true);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle text track change
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The event that caused this function to run
|
||||
*/
|
||||
|
||||
|
||||
OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
|
||||
var tracks = this.player().textTracks();
|
||||
var selected = true;
|
||||
|
||||
for (var i = 0, l = tracks.length; i < l; i++) {
|
||||
var track = tracks[i];
|
||||
|
||||
if (track.kind === this.track.kind && track.mode === 'showing') {
|
||||
selected = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.selected(selected);
|
||||
};
|
||||
|
||||
return OffTextTrackMenuItem;
|
||||
}(_textTrackMenuItem2['default']);
|
||||
|
||||
_component2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem);
|
||||
exports['default'] = OffTextTrackMenuItem;
|
||||
@@ -0,0 +1,87 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _textTrackButton = require('./text-track-button.js');
|
||||
|
||||
var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file subtitles-button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The button component for toggling and selecting subtitles
|
||||
*
|
||||
* @extends TextTrackButton
|
||||
*/
|
||||
var SubtitlesButton = function (_TextTrackButton) {
|
||||
_inherits(SubtitlesButton, _TextTrackButton);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*
|
||||
* @param {Component~ReadyCallback} [ready]
|
||||
* The function to call when this component is ready.
|
||||
*/
|
||||
function SubtitlesButton(player, options, ready) {
|
||||
_classCallCheck(this, SubtitlesButton);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
|
||||
|
||||
_this.el_.setAttribute('aria-label', 'Subtitles Menu');
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
return SubtitlesButton;
|
||||
}(_textTrackButton2['default']);
|
||||
|
||||
/**
|
||||
* `kind` of TextTrack to look for to associate it with this menu.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
SubtitlesButton.prototype.kind_ = 'subtitles';
|
||||
|
||||
/**
|
||||
* The text that should display over the `SubtitlesButton`s controls. Added for localization.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
SubtitlesButton.prototype.controlText_ = 'Subtitles';
|
||||
|
||||
_component2['default'].registerComponent('SubtitlesButton', SubtitlesButton);
|
||||
exports['default'] = SubtitlesButton;
|
||||
@@ -0,0 +1,102 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _trackButton = require('../track-button.js');
|
||||
|
||||
var _trackButton2 = _interopRequireDefault(_trackButton);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _textTrackMenuItem = require('./text-track-menu-item.js');
|
||||
|
||||
var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
|
||||
|
||||
var _offTextTrackMenuItem = require('./off-text-track-menu-item.js');
|
||||
|
||||
var _offTextTrackMenuItem2 = _interopRequireDefault(_offTextTrackMenuItem);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file text-track-button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The base class for buttons that toggle specific text track types (e.g. subtitles)
|
||||
*
|
||||
* @extends MenuButton
|
||||
*/
|
||||
var TextTrackButton = function (_TrackButton) {
|
||||
_inherits(TextTrackButton, _TrackButton);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options={}]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function TextTrackButton(player) {
|
||||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
_classCallCheck(this, TextTrackButton);
|
||||
|
||||
options.tracks = player.textTracks();
|
||||
|
||||
return _possibleConstructorReturn(this, _TrackButton.call(this, player, options));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a menu item for each text track
|
||||
*
|
||||
* @param {TextTrackMenuItem[]} [items=[]]
|
||||
* Existing array of items to use during creation
|
||||
*
|
||||
* @return {TextTrackMenuItem[]}
|
||||
* Array of menu items that were created
|
||||
*/
|
||||
|
||||
|
||||
TextTrackButton.prototype.createItems = function createItems() {
|
||||
var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
||||
|
||||
// Add an OFF menu item to turn all tracks off
|
||||
items.push(new _offTextTrackMenuItem2['default'](this.player_, { kind: this.kind_ }));
|
||||
|
||||
var tracks = this.player_.textTracks();
|
||||
|
||||
if (!tracks) {
|
||||
return items;
|
||||
}
|
||||
|
||||
for (var i = 0; i < tracks.length; i++) {
|
||||
var track = tracks[i];
|
||||
|
||||
// only add tracks that are of the appropriate kind and have a label
|
||||
if (track.kind === this.kind_) {
|
||||
items.push(new _textTrackMenuItem2['default'](this.player_, {
|
||||
track: track,
|
||||
// MenuItem is selectable
|
||||
selectable: true
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
return TextTrackButton;
|
||||
}(_trackButton2['default']);
|
||||
|
||||
_component2['default'].registerComponent('TextTrackButton', TextTrackButton);
|
||||
exports['default'] = TextTrackButton;
|
||||
@@ -0,0 +1,170 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
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; };
|
||||
|
||||
var _menuItem = require('../../menu/menu-item.js');
|
||||
|
||||
var _menuItem2 = _interopRequireDefault(_menuItem);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _fn = require('../../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _window = require('global/window');
|
||||
|
||||
var _window2 = _interopRequireDefault(_window);
|
||||
|
||||
var _document = require('global/document');
|
||||
|
||||
var _document2 = _interopRequireDefault(_document);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file text-track-menu-item.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The specific menu item type for selecting a language within a text track kind
|
||||
*
|
||||
* @extends MenuItem
|
||||
*/
|
||||
var TextTrackMenuItem = function (_MenuItem) {
|
||||
_inherits(TextTrackMenuItem, _MenuItem);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function TextTrackMenuItem(player, options) {
|
||||
_classCallCheck(this, TextTrackMenuItem);
|
||||
|
||||
var track = options.track;
|
||||
var tracks = player.textTracks();
|
||||
|
||||
// Modify options for parent MenuItem class's init.
|
||||
options.label = track.label || track.language || 'Unknown';
|
||||
options.selected = track['default'] || track.mode === 'showing';
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
|
||||
|
||||
_this.track = track;
|
||||
|
||||
if (tracks) {
|
||||
(function () {
|
||||
var changeHandler = Fn.bind(_this, _this.handleTracksChange);
|
||||
|
||||
tracks.addEventListener('change', changeHandler);
|
||||
_this.on('dispose', function () {
|
||||
tracks.removeEventListener('change', changeHandler);
|
||||
});
|
||||
})();
|
||||
}
|
||||
|
||||
// iOS7 doesn't dispatch change events to TextTrackLists when an
|
||||
// associated track's mode changes. Without something like
|
||||
// Object.observe() (also not present on iOS7), it's not
|
||||
// possible to detect changes to the mode attribute and polyfill
|
||||
// the change event. As a poor substitute, we manually dispatch
|
||||
// change events whenever the controls modify the mode.
|
||||
if (tracks && tracks.onchange === undefined) {
|
||||
(function () {
|
||||
var event = void 0;
|
||||
|
||||
_this.on(['tap', 'click'], function () {
|
||||
if (_typeof(_window2['default'].Event) !== 'object') {
|
||||
// Android 2.3 throws an Illegal Constructor error for window.Event
|
||||
try {
|
||||
event = new _window2['default'].Event('change');
|
||||
} catch (err) {
|
||||
// continue regardless of error
|
||||
}
|
||||
}
|
||||
|
||||
if (!event) {
|
||||
event = _document2['default'].createEvent('Event');
|
||||
event.initEvent('change', true, true);
|
||||
}
|
||||
|
||||
tracks.dispatchEvent(event);
|
||||
});
|
||||
})();
|
||||
}
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called when an `TextTrackMenuItem` is "clicked". See
|
||||
* {@link ClickableComponent} for more detailed information on what a click can be.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
*/
|
||||
|
||||
|
||||
TextTrackMenuItem.prototype.handleClick = function handleClick(event) {
|
||||
var kind = this.track.kind;
|
||||
var tracks = this.player_.textTracks();
|
||||
|
||||
_MenuItem.prototype.handleClick.call(this, event);
|
||||
|
||||
if (!tracks) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < tracks.length; i++) {
|
||||
var track = tracks[i];
|
||||
|
||||
if (track.kind !== kind) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (track === this.track) {
|
||||
track.mode = 'showing';
|
||||
} else {
|
||||
track.mode = 'disabled';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle text track list change
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `change` event that caused this function to be called.
|
||||
*
|
||||
* @listens TextTrackList#change
|
||||
*/
|
||||
|
||||
|
||||
TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
|
||||
this.selected(this.track.mode === 'showing');
|
||||
};
|
||||
|
||||
return TextTrackMenuItem;
|
||||
}(_menuItem2['default']);
|
||||
|
||||
_component2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem);
|
||||
exports['default'] = TextTrackMenuItem;
|
||||
@@ -0,0 +1,108 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _dom = require('../../utils/dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
var _formatTime = require('../../utils/format-time.js');
|
||||
|
||||
var _formatTime2 = _interopRequireDefault(_formatTime);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file current-time-display.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Displays the current time
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var CurrentTimeDisplay = function (_Component) {
|
||||
_inherits(CurrentTimeDisplay, _Component);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function CurrentTimeDisplay(player, options) {
|
||||
_classCallCheck(this, CurrentTimeDisplay);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
|
||||
|
||||
_this.on(player, 'timeupdate', _this.updateContent);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
CurrentTimeDisplay.prototype.createEl = function createEl() {
|
||||
var el = _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-current-time vjs-time-control vjs-control'
|
||||
});
|
||||
|
||||
this.contentEl_ = Dom.createEl('div', {
|
||||
className: 'vjs-current-time-display',
|
||||
// label the current time for screen reader users
|
||||
innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00'
|
||||
}, {
|
||||
// tell screen readers not to automatically read the time as it changes
|
||||
'aria-live': 'off'
|
||||
});
|
||||
|
||||
el.appendChild(this.contentEl_);
|
||||
return el;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update current time display
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `timeupdate` event that caused this function to run.
|
||||
*
|
||||
* @listens Player#timeupdate
|
||||
*/
|
||||
|
||||
|
||||
CurrentTimeDisplay.prototype.updateContent = function updateContent(event) {
|
||||
// Allows for smooth scrubbing, when player can't keep up.
|
||||
var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
|
||||
var localizedText = this.localize('Current Time');
|
||||
var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration());
|
||||
|
||||
if (formattedTime !== this.formattedTime_) {
|
||||
this.formattedTime_ = formattedTime;
|
||||
this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
|
||||
}
|
||||
};
|
||||
|
||||
return CurrentTimeDisplay;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
|
||||
exports['default'] = CurrentTimeDisplay;
|
||||
@@ -0,0 +1,118 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _dom = require('../../utils/dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
var _formatTime = require('../../utils/format-time.js');
|
||||
|
||||
var _formatTime2 = _interopRequireDefault(_formatTime);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file duration-display.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Displays the duration
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var DurationDisplay = function (_Component) {
|
||||
_inherits(DurationDisplay, _Component);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function DurationDisplay(player, options) {
|
||||
_classCallCheck(this, DurationDisplay);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
|
||||
|
||||
_this.on(player, 'durationchange', _this.updateContent);
|
||||
|
||||
// Also listen for timeupdate and loadedmetadata because removing those
|
||||
// listeners could have broken dependent applications/libraries. These
|
||||
// can likely be removed for 6.0.
|
||||
_this.on(player, 'timeupdate', _this.updateContent);
|
||||
_this.on(player, 'loadedmetadata', _this.updateContent);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
DurationDisplay.prototype.createEl = function createEl() {
|
||||
var el = _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-duration vjs-time-control vjs-control'
|
||||
});
|
||||
|
||||
this.contentEl_ = Dom.createEl('div', {
|
||||
className: 'vjs-duration-display',
|
||||
// label the duration time for screen reader users
|
||||
innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00'
|
||||
}, {
|
||||
// tell screen readers not to automatically read the time as it changes
|
||||
'aria-live': 'off'
|
||||
});
|
||||
|
||||
el.appendChild(this.contentEl_);
|
||||
return el;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update duration time display.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `durationchange`, `timeupdate`, or `loadedmetadata` event that caused
|
||||
* this function to be called.
|
||||
*
|
||||
* @listens Player#durationchange
|
||||
* @listens Player#timeupdate
|
||||
* @listens Player#loadedmetadata
|
||||
*/
|
||||
|
||||
|
||||
DurationDisplay.prototype.updateContent = function updateContent(event) {
|
||||
var duration = this.player_.duration();
|
||||
|
||||
if (duration && this.duration_ !== duration) {
|
||||
this.duration_ = duration;
|
||||
var localizedText = this.localize('Duration Time');
|
||||
var formattedTime = (0, _formatTime2['default'])(duration);
|
||||
|
||||
// label the duration time for screen reader users
|
||||
this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
|
||||
}
|
||||
};
|
||||
|
||||
return DurationDisplay;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('DurationDisplay', DurationDisplay);
|
||||
exports['default'] = DurationDisplay;
|
||||
@@ -0,0 +1,114 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _dom = require('../../utils/dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
var _formatTime = require('../../utils/format-time.js');
|
||||
|
||||
var _formatTime2 = _interopRequireDefault(_formatTime);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file remaining-time-display.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Displays the time left in the video
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var RemainingTimeDisplay = function (_Component) {
|
||||
_inherits(RemainingTimeDisplay, _Component);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function RemainingTimeDisplay(player, options) {
|
||||
_classCallCheck(this, RemainingTimeDisplay);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
|
||||
|
||||
_this.on(player, 'timeupdate', _this.updateContent);
|
||||
_this.on(player, 'durationchange', _this.updateContent);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
RemainingTimeDisplay.prototype.createEl = function createEl() {
|
||||
var el = _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-remaining-time vjs-time-control vjs-control'
|
||||
});
|
||||
|
||||
this.contentEl_ = Dom.createEl('div', {
|
||||
className: 'vjs-remaining-time-display',
|
||||
// label the remaining time for screen reader users
|
||||
innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00'
|
||||
}, {
|
||||
// tell screen readers not to automatically read the time as it changes
|
||||
'aria-live': 'off'
|
||||
});
|
||||
|
||||
el.appendChild(this.contentEl_);
|
||||
return el;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update remaining time display.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `timeupdate` or `durationchange` event that caused this to run.
|
||||
*
|
||||
* @listens Player#timeupdate
|
||||
* @listens Player#durationchange
|
||||
*/
|
||||
|
||||
|
||||
RemainingTimeDisplay.prototype.updateContent = function updateContent(event) {
|
||||
if (this.player_.duration()) {
|
||||
var localizedText = this.localize('Remaining Time');
|
||||
var formattedTime = (0, _formatTime2['default'])(this.player_.remainingTime());
|
||||
|
||||
if (formattedTime !== this.formattedTime_) {
|
||||
this.formattedTime_ = formattedTime;
|
||||
this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime;
|
||||
}
|
||||
}
|
||||
|
||||
// Allows for smooth scrubbing, when player can't keep up.
|
||||
// var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
|
||||
// this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration());
|
||||
};
|
||||
|
||||
return RemainingTimeDisplay;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
|
||||
exports['default'] = RemainingTimeDisplay;
|
||||
@@ -0,0 +1,52 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file time-divider.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The separator between the current time and duration.
|
||||
* Can be hidden if it's not needed in the design.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var TimeDivider = function (_Component) {
|
||||
_inherits(TimeDivider, _Component);
|
||||
|
||||
function TimeDivider() {
|
||||
_classCallCheck(this, TimeDivider);
|
||||
|
||||
return _possibleConstructorReturn(this, _Component.apply(this, arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the component's DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
TimeDivider.prototype.createEl = function createEl() {
|
||||
return _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-time-control vjs-time-divider',
|
||||
innerHTML: '<div><span>/</span></div>'
|
||||
});
|
||||
};
|
||||
|
||||
return TimeDivider;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('TimeDivider', TimeDivider);
|
||||
exports['default'] = TimeDivider;
|
||||
@@ -0,0 +1,78 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _menuButton = require('../menu/menu-button.js');
|
||||
|
||||
var _menuButton2 = _interopRequireDefault(_menuButton);
|
||||
|
||||
var _component = require('../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _fn = require('../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file track-button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The base class for buttons that toggle specific track types (e.g. subtitles).
|
||||
*
|
||||
* @extends MenuButton
|
||||
*/
|
||||
var TrackButton = function (_MenuButton) {
|
||||
_inherits(TrackButton, _MenuButton);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function TrackButton(player, options) {
|
||||
_classCallCheck(this, TrackButton);
|
||||
|
||||
var tracks = options.tracks;
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options));
|
||||
|
||||
if (_this.items.length <= 1) {
|
||||
_this.hide();
|
||||
}
|
||||
|
||||
if (!tracks) {
|
||||
return _possibleConstructorReturn(_this);
|
||||
}
|
||||
|
||||
var updateHandler = Fn.bind(_this, _this.update);
|
||||
|
||||
tracks.addEventListener('removetrack', updateHandler);
|
||||
tracks.addEventListener('addtrack', updateHandler);
|
||||
|
||||
_this.player_.on('dispose', function () {
|
||||
tracks.removeEventListener('removetrack', updateHandler);
|
||||
tracks.removeEventListener('addtrack', updateHandler);
|
||||
});
|
||||
return _this;
|
||||
}
|
||||
|
||||
return TrackButton;
|
||||
}(_menuButton2['default']);
|
||||
|
||||
_component2['default'].registerComponent('TrackButton', TrackButton);
|
||||
exports['default'] = TrackButton;
|
||||
@@ -0,0 +1,181 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _slider = require('../../slider/slider.js');
|
||||
|
||||
var _slider2 = _interopRequireDefault(_slider);
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _fn = require('../../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
require('./volume-level.js');
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file volume-bar.js
|
||||
*/
|
||||
|
||||
|
||||
// Required children
|
||||
|
||||
|
||||
/**
|
||||
* The bar that contains the volume level and can be clicked on to adjust the level
|
||||
*
|
||||
* @extends Slider
|
||||
*/
|
||||
var VolumeBar = function (_Slider) {
|
||||
_inherits(VolumeBar, _Slider);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function VolumeBar(player, options) {
|
||||
_classCallCheck(this, VolumeBar);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options));
|
||||
|
||||
_this.on(player, 'volumechange', _this.updateARIAAttributes);
|
||||
player.ready(Fn.bind(_this, _this.updateARIAAttributes));
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
VolumeBar.prototype.createEl = function createEl() {
|
||||
return _Slider.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-volume-bar vjs-slider-bar'
|
||||
}, {
|
||||
'aria-label': 'volume level'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle movement events on the {@link VolumeMenuButton}.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The event that caused this function to run.
|
||||
*
|
||||
* @listens mousemove
|
||||
*/
|
||||
|
||||
|
||||
VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) {
|
||||
this.checkMuted();
|
||||
this.player_.volume(this.calculateDistance(event));
|
||||
};
|
||||
|
||||
/**
|
||||
* If the player is muted unmute it.
|
||||
*/
|
||||
|
||||
|
||||
VolumeBar.prototype.checkMuted = function checkMuted() {
|
||||
if (this.player_.muted()) {
|
||||
this.player_.muted(false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get percent of volume level
|
||||
*
|
||||
* @return {number}
|
||||
* Volume level percent as a decimal number.
|
||||
*/
|
||||
|
||||
|
||||
VolumeBar.prototype.getPercent = function getPercent() {
|
||||
if (this.player_.muted()) {
|
||||
return 0;
|
||||
}
|
||||
return this.player_.volume();
|
||||
};
|
||||
|
||||
/**
|
||||
* Increase volume level for keyboard users
|
||||
*/
|
||||
|
||||
|
||||
VolumeBar.prototype.stepForward = function stepForward() {
|
||||
this.checkMuted();
|
||||
this.player_.volume(this.player_.volume() + 0.1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decrease volume level for keyboard users
|
||||
*/
|
||||
|
||||
|
||||
VolumeBar.prototype.stepBack = function stepBack() {
|
||||
this.checkMuted();
|
||||
this.player_.volume(this.player_.volume() - 0.1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update ARIA accessibility attributes
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `volumechange` event that caused this function to run.
|
||||
*
|
||||
* @listens Player#volumechange
|
||||
*/
|
||||
|
||||
|
||||
VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes(event) {
|
||||
// Current value of volume bar as a percentage
|
||||
var volume = (this.player_.volume() * 100).toFixed(2);
|
||||
|
||||
this.el_.setAttribute('aria-valuenow', volume);
|
||||
this.el_.setAttribute('aria-valuetext', volume + '%');
|
||||
};
|
||||
|
||||
return VolumeBar;
|
||||
}(_slider2['default']);
|
||||
|
||||
/**
|
||||
* Default options for the `VolumeBar`
|
||||
*
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
VolumeBar.prototype.options_ = {
|
||||
children: ['volumeLevel'],
|
||||
barName: 'volumeLevel'
|
||||
};
|
||||
|
||||
/**
|
||||
* Call the update event for this Slider when this event happens on the player.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
VolumeBar.prototype.playerEvent = 'volumechange';
|
||||
|
||||
_component2['default'].registerComponent('VolumeBar', VolumeBar);
|
||||
exports['default'] = VolumeBar;
|
||||
@@ -0,0 +1,91 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
require('./volume-bar.js');
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file volume-control.js
|
||||
*/
|
||||
|
||||
|
||||
// Required children
|
||||
|
||||
|
||||
/**
|
||||
* The component for controlling the volume level
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var VolumeControl = function (_Component) {
|
||||
_inherits(VolumeControl, _Component);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options={}]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function VolumeControl(player, options) {
|
||||
_classCallCheck(this, VolumeControl);
|
||||
|
||||
// hide volume controls when they're not supported by the current tech
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
|
||||
|
||||
if (player.tech_ && player.tech_.featuresVolumeControl === false) {
|
||||
_this.addClass('vjs-hidden');
|
||||
}
|
||||
_this.on(player, 'loadstart', function () {
|
||||
if (player.tech_.featuresVolumeControl === false) {
|
||||
this.addClass('vjs-hidden');
|
||||
} else {
|
||||
this.removeClass('vjs-hidden');
|
||||
}
|
||||
});
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
VolumeControl.prototype.createEl = function createEl() {
|
||||
return _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-volume-control vjs-control'
|
||||
});
|
||||
};
|
||||
|
||||
return VolumeControl;
|
||||
}(_component2['default']);
|
||||
|
||||
/**
|
||||
* Default options for the `VolumeControl`
|
||||
*
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
VolumeControl.prototype.options_ = {
|
||||
children: ['volumeBar']
|
||||
};
|
||||
|
||||
_component2['default'].registerComponent('VolumeControl', VolumeControl);
|
||||
exports['default'] = VolumeControl;
|
||||
@@ -0,0 +1,51 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file volume-level.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Shows volume level
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var VolumeLevel = function (_Component) {
|
||||
_inherits(VolumeLevel, _Component);
|
||||
|
||||
function VolumeLevel() {
|
||||
_classCallCheck(this, VolumeLevel);
|
||||
|
||||
return _possibleConstructorReturn(this, _Component.apply(this, arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Component`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
VolumeLevel.prototype.createEl = function createEl() {
|
||||
return _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-volume-level',
|
||||
innerHTML: '<span class="vjs-control-text"></span>'
|
||||
});
|
||||
};
|
||||
|
||||
return VolumeLevel;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('VolumeLevel', VolumeLevel);
|
||||
exports['default'] = VolumeLevel;
|
||||
@@ -0,0 +1,243 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _fn = require('../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _component = require('../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _popup = require('../popup/popup.js');
|
||||
|
||||
var _popup2 = _interopRequireDefault(_popup);
|
||||
|
||||
var _popupButton = require('../popup/popup-button.js');
|
||||
|
||||
var _popupButton2 = _interopRequireDefault(_popupButton);
|
||||
|
||||
var _muteToggle = require('./mute-toggle.js');
|
||||
|
||||
var _muteToggle2 = _interopRequireDefault(_muteToggle);
|
||||
|
||||
var _volumeBar = require('./volume-control/volume-bar.js');
|
||||
|
||||
var _volumeBar2 = _interopRequireDefault(_volumeBar);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
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; } }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file volume-menu-button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Button for volume popup
|
||||
*
|
||||
* @extends PopupButton
|
||||
*/
|
||||
var VolumeMenuButton = function (_PopupButton) {
|
||||
_inherits(VolumeMenuButton, _PopupButton);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options={}]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function VolumeMenuButton(player) {
|
||||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
_classCallCheck(this, VolumeMenuButton);
|
||||
|
||||
// Default to inline
|
||||
if (options.inline === undefined) {
|
||||
options.inline = true;
|
||||
}
|
||||
|
||||
// If the vertical option isn't passed at all, default to true.
|
||||
if (options.vertical === undefined) {
|
||||
// If an inline volumeMenuButton is used, we should default to using
|
||||
// a horizontal slider for obvious reasons.
|
||||
if (options.inline) {
|
||||
options.vertical = false;
|
||||
} else {
|
||||
options.vertical = true;
|
||||
}
|
||||
}
|
||||
|
||||
// The vertical option needs to be set on the volumeBar as well,
|
||||
// since that will need to be passed along to the VolumeBar constructor
|
||||
options.volumeBar = options.volumeBar || {};
|
||||
options.volumeBar.vertical = !!options.vertical;
|
||||
|
||||
// Same listeners as MuteToggle
|
||||
var _this = _possibleConstructorReturn(this, _PopupButton.call(this, player, options));
|
||||
|
||||
_this.on(player, 'volumechange', _this.volumeUpdate);
|
||||
_this.on(player, 'loadstart', _this.volumeUpdate);
|
||||
|
||||
// hide mute toggle if the current tech doesn't support volume control
|
||||
function updateVisibility() {
|
||||
if (player.tech_ && player.tech_.featuresVolumeControl === false) {
|
||||
this.addClass('vjs-hidden');
|
||||
} else {
|
||||
this.removeClass('vjs-hidden');
|
||||
}
|
||||
}
|
||||
|
||||
updateVisibility.call(_this);
|
||||
_this.on(player, 'loadstart', updateVisibility);
|
||||
|
||||
_this.on(_this.volumeBar, ['slideractive', 'focus'], function () {
|
||||
this.addClass('vjs-slider-active');
|
||||
});
|
||||
|
||||
_this.on(_this.volumeBar, ['sliderinactive', 'blur'], function () {
|
||||
this.removeClass('vjs-slider-active');
|
||||
});
|
||||
|
||||
_this.on(_this.volumeBar, ['focus'], function () {
|
||||
this.addClass('vjs-lock-showing');
|
||||
});
|
||||
|
||||
_this.on(_this.volumeBar, ['blur'], function () {
|
||||
this.removeClass('vjs-lock-showing');
|
||||
});
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() {
|
||||
var orientationClass = '';
|
||||
|
||||
if (this.options_.vertical) {
|
||||
orientationClass = 'vjs-volume-menu-button-vertical';
|
||||
} else {
|
||||
orientationClass = 'vjs-volume-menu-button-horizontal';
|
||||
}
|
||||
|
||||
return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the VolumeMenuButton popup
|
||||
*
|
||||
* @return {Popup}
|
||||
* The popup that was created
|
||||
*/
|
||||
|
||||
|
||||
VolumeMenuButton.prototype.createPopup = function createPopup() {
|
||||
var popup = new _popup2['default'](this.player_, {
|
||||
contentElType: 'div'
|
||||
});
|
||||
|
||||
var vb = new _volumeBar2['default'](this.player_, this.options_.volumeBar);
|
||||
|
||||
popup.addChild(vb);
|
||||
|
||||
this.menuContent = popup;
|
||||
this.volumeBar = vb;
|
||||
|
||||
this.attachVolumeBarEvents();
|
||||
|
||||
return popup;
|
||||
};
|
||||
|
||||
/**
|
||||
* This gets called when an `VolumeMenuButton` is "clicked". See
|
||||
* {@link ClickableComponent} for more detailed information on what a click can be.
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
*/
|
||||
|
||||
|
||||
VolumeMenuButton.prototype.handleClick = function handleClick(event) {
|
||||
_muteToggle2['default'].prototype.handleClick.call(this);
|
||||
_PopupButton.prototype.handleClick.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add events listeners to the created `VolumeBar`.
|
||||
*/
|
||||
|
||||
|
||||
VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() {
|
||||
this.menuContent.on(['mousedown', 'touchdown'], Fn.bind(this, this.handleMouseDown));
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle the `mousedown` and `touchdown` events on the `VolumeBar`
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `mousedown` or `touchdown` event that caused this to run.
|
||||
*
|
||||
* @listens mousedown
|
||||
* @listens touchdown
|
||||
*/
|
||||
|
||||
|
||||
VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) {
|
||||
this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
|
||||
this.on(this.el_.ownerDocument, ['mouseup', 'touchend'], this.handleMouseUp);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle the `mouseup` and `touchend` events on the `VolumeBar`
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `mouseup` or `touchend` event that caused this to run.
|
||||
*
|
||||
* @listens mouseup
|
||||
* @listens touchend
|
||||
*/
|
||||
|
||||
|
||||
VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) {
|
||||
this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
|
||||
};
|
||||
|
||||
return VolumeMenuButton;
|
||||
}(_popupButton2['default']);
|
||||
|
||||
/**
|
||||
* @borrows MuteToggle#update as VolumeMenuButton#volumeUpdate
|
||||
*/
|
||||
|
||||
|
||||
VolumeMenuButton.prototype.volumeUpdate = _muteToggle2['default'].prototype.update;
|
||||
|
||||
/**
|
||||
* The text that should display over the `VolumeMenuButton`s controls. Added for localization.
|
||||
*
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
VolumeMenuButton.prototype.controlText_ = 'Mute';
|
||||
|
||||
_component2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton);
|
||||
exports['default'] = VolumeMenuButton;
|
||||
@@ -0,0 +1,100 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('./component');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _modalDialog = require('./modal-dialog');
|
||||
|
||||
var _modalDialog2 = _interopRequireDefault(_modalDialog);
|
||||
|
||||
var _mergeOptions = require('./utils/merge-options');
|
||||
|
||||
var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file error-display.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A display that indicates an error has occurred. This means that the video
|
||||
* is unplayable.
|
||||
*
|
||||
* @extends ModalDialog
|
||||
*/
|
||||
var ErrorDisplay = function (_ModalDialog) {
|
||||
_inherits(ErrorDisplay, _ModalDialog);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function ErrorDisplay(player, options) {
|
||||
_classCallCheck(this, ErrorDisplay);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _ModalDialog.call(this, player, options));
|
||||
|
||||
_this.on(player, 'error', _this.open);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*
|
||||
* @deprecated Since version 5.
|
||||
*/
|
||||
|
||||
|
||||
ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the localized error message based on the `Player`s error.
|
||||
*
|
||||
* @return {string}
|
||||
* The `Player`s error message localized or an empty string.
|
||||
*/
|
||||
|
||||
|
||||
ErrorDisplay.prototype.content = function content() {
|
||||
var error = this.player().error();
|
||||
|
||||
return error ? this.localize(error.message) : '';
|
||||
};
|
||||
|
||||
return ErrorDisplay;
|
||||
}(_modalDialog2['default']);
|
||||
|
||||
/**
|
||||
* The default options for an `ErrorDisplay`.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
ErrorDisplay.prototype.options_ = (0, _mergeOptions2['default'])(_modalDialog2['default'].prototype.options_, {
|
||||
fillAlways: true,
|
||||
temporary: false,
|
||||
uncloseable: true
|
||||
});
|
||||
|
||||
_component2['default'].registerComponent('ErrorDisplay', ErrorDisplay);
|
||||
exports['default'] = ErrorDisplay;
|
||||
@@ -0,0 +1,169 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _events = require('./utils/events.js');
|
||||
|
||||
var Events = _interopRequireWildcard(_events);
|
||||
|
||||
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; } }
|
||||
|
||||
/**
|
||||
* `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It
|
||||
* adds shorthand functions that wrap around lengthy functions. For example:
|
||||
* the `on` function is a wrapper around `addEventListener`.
|
||||
*
|
||||
* @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget}
|
||||
* @class EventTarget
|
||||
*/
|
||||
var EventTarget = function EventTarget() {};
|
||||
|
||||
/**
|
||||
* A Custom DOM event.
|
||||
*
|
||||
* @typedef {Object} EventTarget~Event
|
||||
* @see [Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
|
||||
*/
|
||||
|
||||
/**
|
||||
* All event listeners should follow the following format.
|
||||
*
|
||||
* @callback EventTarget~EventListener
|
||||
* @this {EventTarget}
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* the event that triggered this function
|
||||
*
|
||||
* @param {Object} [hash]
|
||||
* hash of data sent during the event
|
||||
*/
|
||||
|
||||
/**
|
||||
* An object containing event names as keys and booleans as values.
|
||||
*
|
||||
* > NOTE: If an event name is set to a true value here {@link EventTarget#trigger}
|
||||
* will have extra functionality. See that function for more information.
|
||||
*
|
||||
* @property EventTarget.prototype.allowedEvents_
|
||||
* @private
|
||||
*/
|
||||
/**
|
||||
* @file src/js/event-target.js
|
||||
*/
|
||||
EventTarget.prototype.allowedEvents_ = {};
|
||||
|
||||
/**
|
||||
* Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a
|
||||
* function that will get called when an event with a certain name gets triggered.
|
||||
*
|
||||
* @param {string|string[]} type
|
||||
* An event name or an array of event names.
|
||||
*
|
||||
* @param {EventTarget~EventListener} fn
|
||||
* The function to call with `EventTarget`s
|
||||
*/
|
||||
EventTarget.prototype.on = function (type, fn) {
|
||||
// Remove the addEventListener alias before calling Events.on
|
||||
// so we don't get into an infinite type loop
|
||||
var ael = this.addEventListener;
|
||||
|
||||
this.addEventListener = function () {};
|
||||
Events.on(this, type, fn);
|
||||
this.addEventListener = ael;
|
||||
};
|
||||
|
||||
/**
|
||||
* An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic
|
||||
* the standard DOM API.
|
||||
*
|
||||
* @function
|
||||
* @see {@link EventTarget#on}
|
||||
*/
|
||||
EventTarget.prototype.addEventListener = EventTarget.prototype.on;
|
||||
|
||||
/**
|
||||
* Removes an `event listener` for a specific event from an instance of `EventTarget`.
|
||||
* This makes it so that the `event listener` will no longer get called when the
|
||||
* named event happens.
|
||||
*
|
||||
* @param {string|string[]} type
|
||||
* An event name or an array of event names.
|
||||
*
|
||||
* @param {EventTarget~EventListener} fn
|
||||
* The function to remove.
|
||||
*/
|
||||
EventTarget.prototype.off = function (type, fn) {
|
||||
Events.off(this, type, fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic
|
||||
* the standard DOM API.
|
||||
*
|
||||
* @function
|
||||
* @see {@link EventTarget#off}
|
||||
*/
|
||||
EventTarget.prototype.removeEventListener = EventTarget.prototype.off;
|
||||
|
||||
/**
|
||||
* This function will add an `event listener` that gets triggered only once. After the
|
||||
* first trigger it will get removed. This is like adding an `event listener`
|
||||
* with {@link EventTarget#on} that calls {@link EventTarget#off} on itself.
|
||||
*
|
||||
* @param {string|string[]} type
|
||||
* An event name or an array of event names.
|
||||
*
|
||||
* @param {EventTarget~EventListener} fn
|
||||
* The function to be called once for each event name.
|
||||
*/
|
||||
EventTarget.prototype.one = function (type, fn) {
|
||||
// Remove the addEventListener alialing Events.on
|
||||
// so we don't get into an infinite type loop
|
||||
var ael = this.addEventListener;
|
||||
|
||||
this.addEventListener = function () {};
|
||||
Events.one(this, type, fn);
|
||||
this.addEventListener = ael;
|
||||
};
|
||||
|
||||
/**
|
||||
* This function causes an event to happen. This will then cause any `event listeners`
|
||||
* that are waiting for that event, to get called. If there are no `event listeners`
|
||||
* for an event then nothing will happen.
|
||||
*
|
||||
* If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`.
|
||||
* Trigger will also call the `on` + `uppercaseEventName` function.
|
||||
*
|
||||
* Example:
|
||||
* 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call
|
||||
* `onClick` if it exists.
|
||||
*
|
||||
* @param {string|EventTarget~Event|Object} event
|
||||
* The name of the event, an `Event`, or an object with a key of type set to
|
||||
* an event name.
|
||||
*/
|
||||
EventTarget.prototype.trigger = function (event) {
|
||||
var type = event.type || event;
|
||||
|
||||
if (typeof event === 'string') {
|
||||
event = { type: type };
|
||||
}
|
||||
event = Events.fixEvent(event);
|
||||
|
||||
if (this.allowedEvents_[type] && this['on' + type]) {
|
||||
this['on' + type](event);
|
||||
}
|
||||
|
||||
Events.trigger(this, event);
|
||||
};
|
||||
|
||||
/**
|
||||
* An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic
|
||||
* the standard DOM API.
|
||||
*
|
||||
* @function
|
||||
* @see {@link EventTarget#trigger}
|
||||
*/
|
||||
EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;
|
||||
|
||||
exports['default'] = EventTarget;
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
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; };
|
||||
|
||||
var _log = require('./utils/log');
|
||||
|
||||
var _log2 = _interopRequireDefault(_log);
|
||||
|
||||
var _obj = require('./utils/obj');
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
/**
|
||||
* @file extend.js
|
||||
* @module extend
|
||||
*/
|
||||
|
||||
/**
|
||||
* A combination of node inherits and babel's inherits (after transpile).
|
||||
* Both work the same but node adds `super_` to the subClass
|
||||
* and Bable adds the superClass as __proto__. Both seem useful.
|
||||
*
|
||||
* @param {Object} subClass
|
||||
* The class to inherit to
|
||||
*
|
||||
* @param {Object} superClass
|
||||
* The class to inherit from
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var _inherits = 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 === 'undefined' ? 'undefined' : _typeof(superClass)));
|
||||
}
|
||||
|
||||
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
||||
constructor: {
|
||||
value: subClass,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true
|
||||
}
|
||||
});
|
||||
|
||||
if (superClass) {
|
||||
// node
|
||||
subClass.super_ = superClass;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function for subclassing using the same inheritance that
|
||||
* videojs uses internally
|
||||
*
|
||||
* @param {Object} superClass
|
||||
* The class to inherit from
|
||||
*
|
||||
* @param {Object} [subClassMethods={}]
|
||||
* The class to inherit to
|
||||
*
|
||||
* @return {Object}
|
||||
* The new object with subClassMethods that inherited superClass.
|
||||
*/
|
||||
var extendFn = function extendFn(superClass) {
|
||||
var subClassMethods = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
var subClass = function subClass() {
|
||||
superClass.apply(this, arguments);
|
||||
};
|
||||
|
||||
var methods = {};
|
||||
|
||||
if ((0, _obj.isObject)(subClassMethods)) {
|
||||
if (typeof subClassMethods.init === 'function') {
|
||||
_log2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.');
|
||||
subClassMethods.constructor = subClassMethods.init;
|
||||
}
|
||||
if (subClassMethods.constructor !== Object.prototype.constructor) {
|
||||
subClass = subClassMethods.constructor;
|
||||
}
|
||||
methods = subClassMethods;
|
||||
} else if (typeof subClassMethods === 'function') {
|
||||
subClass = subClassMethods;
|
||||
}
|
||||
|
||||
_inherits(subClass, superClass);
|
||||
|
||||
// Extend subObj's prototype with functions and other properties from props
|
||||
for (var name in methods) {
|
||||
if (methods.hasOwnProperty(name)) {
|
||||
subClass.prototype[name] = methods[name];
|
||||
}
|
||||
}
|
||||
|
||||
return subClass;
|
||||
};
|
||||
|
||||
exports['default'] = extendFn;
|
||||
@@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _document = require('global/document');
|
||||
|
||||
var _document2 = _interopRequireDefault(_document);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
/**
|
||||
* Store the browser-specific methods for the fullscreen API.
|
||||
*
|
||||
* @type {Object}
|
||||
* @see [Specification]{@link https://fullscreen.spec.whatwg.org}
|
||||
* @see [Map Approach From Screenfull.js]{@link https://github.com/sindresorhus/screenfull.js}
|
||||
*/
|
||||
var FullscreenApi = {};
|
||||
|
||||
// browser API methods
|
||||
/**
|
||||
* @file fullscreen-api.js
|
||||
* @module fullscreen-api
|
||||
* @private
|
||||
*/
|
||||
var apiMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'],
|
||||
// WebKit
|
||||
['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'],
|
||||
// Old WebKit (Safari 5.1)
|
||||
['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'],
|
||||
// Mozilla
|
||||
['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'],
|
||||
// Microsoft
|
||||
['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']];
|
||||
|
||||
var specApi = apiMap[0];
|
||||
var browserApi = void 0;
|
||||
|
||||
// determine the supported set of functions
|
||||
for (var i = 0; i < apiMap.length; i++) {
|
||||
// check for exitFullscreen function
|
||||
if (apiMap[i][1] in _document2['default']) {
|
||||
browserApi = apiMap[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// map the browser API names to the spec API names
|
||||
if (browserApi) {
|
||||
for (var _i = 0; _i < browserApi.length; _i++) {
|
||||
FullscreenApi[specApi[_i]] = browserApi[_i];
|
||||
}
|
||||
}
|
||||
|
||||
exports['default'] = FullscreenApi;
|
||||
@@ -0,0 +1,51 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('./component');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file loading-spinner.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A loading spinner for use during waiting/loading events.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var LoadingSpinner = function (_Component) {
|
||||
_inherits(LoadingSpinner, _Component);
|
||||
|
||||
function LoadingSpinner() {
|
||||
_classCallCheck(this, LoadingSpinner);
|
||||
|
||||
return _possibleConstructorReturn(this, _Component.apply(this, arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `LoadingSpinner`s DOM element.
|
||||
*
|
||||
* @return {Element}
|
||||
* The dom element that gets created.
|
||||
*/
|
||||
LoadingSpinner.prototype.createEl = function createEl() {
|
||||
return _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-loading-spinner',
|
||||
dir: 'ltr'
|
||||
});
|
||||
};
|
||||
|
||||
return LoadingSpinner;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('LoadingSpinner', LoadingSpinner);
|
||||
exports['default'] = LoadingSpinner;
|
||||
@@ -0,0 +1,211 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _obj = require('./utils/obj');
|
||||
|
||||
/**
|
||||
* A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class.
|
||||
*
|
||||
* @param {number|string|Object|MediaError} value
|
||||
* This can be of multiple types:
|
||||
* - number: should be a standard error code
|
||||
* - string: an error message (the code will be 0)
|
||||
* - Object: arbitrary properties
|
||||
* - `MediaError` (native): used to populate a video.js `MediaError` object
|
||||
* - `MediaError` (video.js): will return itself if it's already a
|
||||
* video.js `MediaError` object.
|
||||
*
|
||||
* @see [MediaError Spec]{@link https://dev.w3.org/html5/spec-author-view/video.html#mediaerror}
|
||||
* @see [Encrypted MediaError Spec]{@link https://www.w3.org/TR/2013/WD-encrypted-media-20130510/#error-codes}
|
||||
*
|
||||
* @class MediaError
|
||||
*/
|
||||
function MediaError(value) {
|
||||
|
||||
// Allow redundant calls to this constructor to avoid having `instanceof`
|
||||
// checks peppered around the code.
|
||||
if (value instanceof MediaError) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (typeof value === 'number') {
|
||||
this.code = value;
|
||||
} else if (typeof value === 'string') {
|
||||
// default code is zero, so this is a custom error
|
||||
this.message = value;
|
||||
} else if ((0, _obj.isObject)(value)) {
|
||||
|
||||
// We assign the `code` property manually because native `MediaError` objects
|
||||
// do not expose it as an own/enumerable property of the object.
|
||||
if (typeof value.code === 'number') {
|
||||
this.code = value.code;
|
||||
}
|
||||
|
||||
(0, _obj.assign)(this, value);
|
||||
}
|
||||
|
||||
if (!this.message) {
|
||||
this.message = MediaError.defaultMessages[this.code] || '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The error code that refers two one of the defined `MediaError` types
|
||||
*
|
||||
* @type {Number}
|
||||
*/
|
||||
/**
|
||||
* @file media-error.js
|
||||
*/
|
||||
MediaError.prototype.code = 0;
|
||||
|
||||
/**
|
||||
* An optional message that to show with the error. Message is not part of the HTML5
|
||||
* video spec but allows for more informative custom errors.
|
||||
*
|
||||
* @type {String}
|
||||
*/
|
||||
MediaError.prototype.message = '';
|
||||
|
||||
/**
|
||||
* An optional status code that can be set by plugins to allow even more detail about
|
||||
* the error. For example a plugin might provide a specific HTTP status code and an
|
||||
* error message for that code. Then when the plugin gets that error this class will
|
||||
* know how to display an error message for it. This allows a custom message to show
|
||||
* up on the `Player` error overlay.
|
||||
*
|
||||
* @type {Array}
|
||||
*/
|
||||
MediaError.prototype.status = null;
|
||||
|
||||
/**
|
||||
* Errors indexed by the W3C standard. The order **CANNOT CHANGE**! See the
|
||||
* specification listed under {@link MediaError} for more information.
|
||||
*
|
||||
* @enum {array}
|
||||
* @readonly
|
||||
* @property {string} 0 - MEDIA_ERR_CUSTOM
|
||||
* @property {string} 1 - MEDIA_ERR_CUSTOM
|
||||
* @property {string} 2 - MEDIA_ERR_ABORTED
|
||||
* @property {string} 3 - MEDIA_ERR_NETWORK
|
||||
* @property {string} 4 - MEDIA_ERR_SRC_NOT_SUPPORTED
|
||||
* @property {string} 5 - MEDIA_ERR_ENCRYPTED
|
||||
*/
|
||||
MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED'];
|
||||
|
||||
/**
|
||||
* The default `MediaError` messages based on the {@link MediaError.errorTypes}.
|
||||
*
|
||||
* @type {Array}
|
||||
* @constant
|
||||
*/
|
||||
MediaError.defaultMessages = {
|
||||
1: 'You aborted the media playback',
|
||||
2: 'A network error caused the media download to fail part-way.',
|
||||
3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.',
|
||||
4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.',
|
||||
5: 'The media is encrypted and we do not have the keys to decrypt it.'
|
||||
};
|
||||
|
||||
// Add types as properties on MediaError
|
||||
// e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
|
||||
for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) {
|
||||
MediaError[MediaError.errorTypes[errNum]] = errNum;
|
||||
// values should be accessible on both the class and instance
|
||||
MediaError.prototype[MediaError.errorTypes[errNum]] = errNum;
|
||||
}
|
||||
|
||||
// jsdocs for instance/static members added above
|
||||
// instance methods use `#` and static methods use `.`
|
||||
/**
|
||||
* W3C error code for any custom error.
|
||||
*
|
||||
* @member MediaError#MEDIA_ERR_CUSTOM
|
||||
* @constant {number}
|
||||
* @default 0
|
||||
*/
|
||||
/**
|
||||
* W3C error code for any custom error.
|
||||
*
|
||||
* @member MediaError.MEDIA_ERR_CUSTOM
|
||||
* @constant {number}
|
||||
* @default 0
|
||||
*/
|
||||
|
||||
/**
|
||||
* W3C error code for media error aborted.
|
||||
*
|
||||
* @member MediaError#MEDIA_ERR_ABORTED
|
||||
* @constant {number}
|
||||
* @default 1
|
||||
*/
|
||||
/**
|
||||
* W3C error code for media error aborted.
|
||||
*
|
||||
* @member MediaError.MEDIA_ERR_ABORTED
|
||||
* @constant {number}
|
||||
* @default 1
|
||||
*/
|
||||
|
||||
/**
|
||||
* W3C error code for any network error.
|
||||
*
|
||||
* @member MediaError#MEDIA_ERR_NETWORK
|
||||
* @constant {number}
|
||||
* @default 2
|
||||
*/
|
||||
/**
|
||||
* W3C error code for any network error.
|
||||
*
|
||||
* @member MediaError.MEDIA_ERR_NETWORK
|
||||
* @constant {number}
|
||||
* @default 2
|
||||
*/
|
||||
|
||||
/**
|
||||
* W3C error code for any decoding error.
|
||||
*
|
||||
* @member MediaError#MEDIA_ERR_DECODE
|
||||
* @constant {number}
|
||||
* @default 3
|
||||
*/
|
||||
/**
|
||||
* W3C error code for any decoding error.
|
||||
*
|
||||
* @member MediaError.MEDIA_ERR_DECODE
|
||||
* @constant {number}
|
||||
* @default 3
|
||||
*/
|
||||
|
||||
/**
|
||||
* W3C error code for any time that a source is not supported.
|
||||
*
|
||||
* @member MediaError#MEDIA_ERR_SRC_NOT_SUPPORTED
|
||||
* @constant {number}
|
||||
* @default 4
|
||||
*/
|
||||
/**
|
||||
* W3C error code for any time that a source is not supported.
|
||||
*
|
||||
* @member MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED
|
||||
* @constant {number}
|
||||
* @default 4
|
||||
*/
|
||||
|
||||
/**
|
||||
* W3C error code for any time that a source is encrypted.
|
||||
*
|
||||
* @member MediaError#MEDIA_ERR_ENCRYPTED
|
||||
* @constant {number}
|
||||
* @default 5
|
||||
*/
|
||||
/**
|
||||
* W3C error code for any time that a source is encrypted.
|
||||
*
|
||||
* @member MediaError.MEDIA_ERR_ENCRYPTED
|
||||
* @constant {number}
|
||||
* @default 5
|
||||
*/
|
||||
|
||||
exports['default'] = MediaError;
|
||||
@@ -0,0 +1,340 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _clickableComponent = require('../clickable-component.js');
|
||||
|
||||
var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
|
||||
|
||||
var _component = require('../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _menu = require('./menu.js');
|
||||
|
||||
var _menu2 = _interopRequireDefault(_menu);
|
||||
|
||||
var _dom = require('../utils/dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
var _fn = require('../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _toTitleCase = require('../utils/to-title-case.js');
|
||||
|
||||
var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file menu-button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A `MenuButton` class for any popup {@link Menu}.
|
||||
*
|
||||
* @extends ClickableComponent
|
||||
*/
|
||||
var MenuButton = function (_ClickableComponent) {
|
||||
_inherits(MenuButton, _ClickableComponent);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options={}]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function MenuButton(player) {
|
||||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
_classCallCheck(this, MenuButton);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
|
||||
|
||||
_this.update();
|
||||
|
||||
_this.enabled_ = true;
|
||||
|
||||
_this.el_.setAttribute('aria-haspopup', 'true');
|
||||
_this.el_.setAttribute('role', 'menuitem');
|
||||
_this.on('keydown', _this.handleSubmenuKeyPress);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the menu based on the current state of its items.
|
||||
*/
|
||||
|
||||
|
||||
MenuButton.prototype.update = function update() {
|
||||
var menu = this.createMenu();
|
||||
|
||||
if (this.menu) {
|
||||
this.removeChild(this.menu);
|
||||
}
|
||||
|
||||
this.menu = menu;
|
||||
this.addChild(menu);
|
||||
|
||||
/**
|
||||
* Track the state of the menu button
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @private
|
||||
*/
|
||||
this.buttonPressed_ = false;
|
||||
this.el_.setAttribute('aria-expanded', 'false');
|
||||
|
||||
if (this.items && this.items.length === 0) {
|
||||
this.hide();
|
||||
} else if (this.items && this.items.length > 1) {
|
||||
this.show();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the menu and add all items to it.
|
||||
*
|
||||
* @return {Menu}
|
||||
* The constructed menu
|
||||
*/
|
||||
|
||||
|
||||
MenuButton.prototype.createMenu = function createMenu() {
|
||||
var menu = new _menu2['default'](this.player_);
|
||||
|
||||
// Add a title list item to the top
|
||||
if (this.options_.title) {
|
||||
var title = Dom.createEl('li', {
|
||||
className: 'vjs-menu-title',
|
||||
innerHTML: (0, _toTitleCase2['default'])(this.options_.title),
|
||||
tabIndex: -1
|
||||
});
|
||||
|
||||
menu.children_.unshift(title);
|
||||
Dom.insertElFirst(title, menu.contentEl());
|
||||
}
|
||||
|
||||
this.items = this.createItems();
|
||||
|
||||
if (this.items) {
|
||||
// Add menu items to the menu
|
||||
for (var i = 0; i < this.items.length; i++) {
|
||||
menu.addItem(this.items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return menu;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the list of menu items. Specific to each subclass.
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
|
||||
MenuButton.prototype.createItems = function createItems() {};
|
||||
|
||||
/**
|
||||
* Create the `MenuButtons`s DOM element.
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that gets created.
|
||||
*/
|
||||
|
||||
|
||||
MenuButton.prototype.createEl = function createEl() {
|
||||
return _ClickableComponent.prototype.createEl.call(this, 'div', {
|
||||
className: this.buildCSSClass()
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
MenuButton.prototype.buildCSSClass = function buildCSSClass() {
|
||||
var menuButtonClass = 'vjs-menu-button';
|
||||
|
||||
// If the inline option is passed, we want to use different styles altogether.
|
||||
if (this.options_.inline === true) {
|
||||
menuButtonClass += '-inline';
|
||||
} else {
|
||||
menuButtonClass += '-popup';
|
||||
}
|
||||
|
||||
return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a click on a `MenuButton`.
|
||||
* See {@link ClickableComponent#handleClick} for instances where this is called.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
*/
|
||||
|
||||
|
||||
MenuButton.prototype.handleClick = function handleClick(event) {
|
||||
// When you click the button it adds focus, which will show the menu.
|
||||
// So we'll remove focus when the mouse leaves the button. Focus is needed
|
||||
// for tab navigation.
|
||||
|
||||
this.one(this.menu.contentEl(), 'mouseleave', Fn.bind(this, function (e) {
|
||||
this.unpressButton();
|
||||
this.el_.blur();
|
||||
}));
|
||||
if (this.buttonPressed_) {
|
||||
this.unpressButton();
|
||||
} else {
|
||||
this.pressButton();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle tab, escape, down arrow, and up arrow keys for `MenuButton`. See
|
||||
* {@link ClickableComponent#handleKeyPress} for instances where this is called.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `keydown` event that caused this function to be called.
|
||||
*
|
||||
* @listens keydown
|
||||
*/
|
||||
|
||||
|
||||
MenuButton.prototype.handleKeyPress = function handleKeyPress(event) {
|
||||
|
||||
// Escape (27) key or Tab (9) key unpress the 'button'
|
||||
if (event.which === 27 || event.which === 9) {
|
||||
if (this.buttonPressed_) {
|
||||
this.unpressButton();
|
||||
}
|
||||
// Don't preventDefault for Tab key - we still want to lose focus
|
||||
if (event.which !== 9) {
|
||||
event.preventDefault();
|
||||
}
|
||||
// Up (38) key or Down (40) key press the 'button'
|
||||
} else if (event.which === 38 || event.which === 40) {
|
||||
if (!this.buttonPressed_) {
|
||||
this.pressButton();
|
||||
event.preventDefault();
|
||||
}
|
||||
} else {
|
||||
_ClickableComponent.prototype.handleKeyPress.call(this, event);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a `keydown` event on a sub-menu. The listener for this is added in
|
||||
* the constructor.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* Key press event
|
||||
*
|
||||
* @listens keydown
|
||||
*/
|
||||
|
||||
|
||||
MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) {
|
||||
|
||||
// Escape (27) key or Tab (9) key unpress the 'button'
|
||||
if (event.which === 27 || event.which === 9) {
|
||||
if (this.buttonPressed_) {
|
||||
this.unpressButton();
|
||||
}
|
||||
// Don't preventDefault for Tab key - we still want to lose focus
|
||||
if (event.which !== 9) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Put the current `MenuButton` into a pressed state.
|
||||
*/
|
||||
|
||||
|
||||
MenuButton.prototype.pressButton = function pressButton() {
|
||||
if (this.enabled_) {
|
||||
this.buttonPressed_ = true;
|
||||
this.menu.lockShowing();
|
||||
this.el_.setAttribute('aria-expanded', 'true');
|
||||
// set the focus into the submenu
|
||||
this.menu.focus();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Take the current `MenuButton` out of a pressed state.
|
||||
*/
|
||||
|
||||
|
||||
MenuButton.prototype.unpressButton = function unpressButton() {
|
||||
if (this.enabled_) {
|
||||
this.buttonPressed_ = false;
|
||||
this.menu.unlockShowing();
|
||||
this.el_.setAttribute('aria-expanded', 'false');
|
||||
// Set focus back to this menu button
|
||||
this.el_.focus();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable the `MenuButton`. Don't allow it to be clicked.
|
||||
*
|
||||
* @return {MenuButton}
|
||||
* Returns itself; method can be chained.
|
||||
*/
|
||||
|
||||
|
||||
MenuButton.prototype.disable = function disable() {
|
||||
// Unpress, but don't force focus on this button
|
||||
this.buttonPressed_ = false;
|
||||
this.menu.unlockShowing();
|
||||
this.el_.setAttribute('aria-expanded', 'false');
|
||||
|
||||
this.enabled_ = false;
|
||||
|
||||
return _ClickableComponent.prototype.disable.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable the `MenuButton`. Allow it to be clicked.
|
||||
*
|
||||
* @return {MenuButton}
|
||||
* Returns itself; method can be chained.
|
||||
*/
|
||||
|
||||
|
||||
MenuButton.prototype.enable = function enable() {
|
||||
this.enabled_ = true;
|
||||
|
||||
return _ClickableComponent.prototype.enable.call(this);
|
||||
};
|
||||
|
||||
return MenuButton;
|
||||
}(_clickableComponent2['default']);
|
||||
|
||||
_component2['default'].registerComponent('MenuButton', MenuButton);
|
||||
exports['default'] = MenuButton;
|
||||
@@ -0,0 +1,135 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _clickableComponent = require('../clickable-component.js');
|
||||
|
||||
var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
|
||||
|
||||
var _component = require('../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _obj = require('../utils/obj');
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file menu-item.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The component for a menu item. `<li>`
|
||||
*
|
||||
* @extends ClickableComponent
|
||||
*/
|
||||
var MenuItem = function (_ClickableComponent) {
|
||||
_inherits(MenuItem, _ClickableComponent);
|
||||
|
||||
/**
|
||||
* Creates an instance of the this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options={}]
|
||||
* The key/value store of player options.
|
||||
*
|
||||
*/
|
||||
function MenuItem(player, options) {
|
||||
_classCallCheck(this, MenuItem);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
|
||||
|
||||
_this.selectable = options.selectable;
|
||||
|
||||
_this.selected(options.selected);
|
||||
|
||||
if (_this.selectable) {
|
||||
// TODO: May need to be either menuitemcheckbox or menuitemradio,
|
||||
// and may need logical grouping of menu items.
|
||||
_this.el_.setAttribute('role', 'menuitemcheckbox');
|
||||
} else {
|
||||
_this.el_.setAttribute('role', 'menuitem');
|
||||
}
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `MenuItem's DOM element
|
||||
*
|
||||
* @param {string} [type=li]
|
||||
* Element's node type, not actually used, always set to `li`.
|
||||
*
|
||||
* @param {Object} [props={}]
|
||||
* An object of properties that should be set on the element
|
||||
*
|
||||
* @param {Object} [attrs={}]
|
||||
* An object of attributes that should be set on the element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that gets created.
|
||||
*/
|
||||
|
||||
|
||||
MenuItem.prototype.createEl = function createEl(type, props, attrs) {
|
||||
return _ClickableComponent.prototype.createEl.call(this, 'li', (0, _obj.assign)({
|
||||
className: 'vjs-menu-item',
|
||||
innerHTML: this.localize(this.options_.label),
|
||||
tabIndex: -1
|
||||
}, props), attrs);
|
||||
};
|
||||
|
||||
/**
|
||||
* Any click on a `MenuItem` puts int into the selected state.
|
||||
* See {@link ClickableComponent#handleClick} for instances where this is called.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `keydown`, `tap`, or `click` event that caused this function to be
|
||||
* called.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
*/
|
||||
|
||||
|
||||
MenuItem.prototype.handleClick = function handleClick(event) {
|
||||
this.selected(true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the state for this menu item as selected or not.
|
||||
*
|
||||
* @param {boolean} selected
|
||||
* if the menu item is selected or not
|
||||
*/
|
||||
|
||||
|
||||
MenuItem.prototype.selected = function selected(_selected) {
|
||||
if (this.selectable) {
|
||||
if (_selected) {
|
||||
this.addClass('vjs-selected');
|
||||
this.el_.setAttribute('aria-checked', 'true');
|
||||
// aria-checked isn't fully supported by browsers/screen readers,
|
||||
// so indicate selected state to screen reader in the control text.
|
||||
this.controlText(', selected');
|
||||
} else {
|
||||
this.removeClass('vjs-selected');
|
||||
this.el_.setAttribute('aria-checked', 'false');
|
||||
// Indicate un-selected state to screen reader
|
||||
// Note that a space clears out the selected state text
|
||||
this.controlText(' ');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return MenuItem;
|
||||
}(_clickableComponent2['default']);
|
||||
|
||||
_component2['default'].registerComponent('MenuItem', MenuItem);
|
||||
exports['default'] = MenuItem;
|
||||
@@ -0,0 +1,202 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _dom = require('../utils/dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
var _fn = require('../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _events = require('../utils/events.js');
|
||||
|
||||
var Events = _interopRequireWildcard(_events);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file menu.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The Menu component is used to build popup menus, including subtitle and
|
||||
* captions selection menus.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var Menu = function (_Component) {
|
||||
_inherits(Menu, _Component);
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* the player that this component should attach to
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* Object of option names and values
|
||||
*
|
||||
*/
|
||||
function Menu(player, options) {
|
||||
_classCallCheck(this, Menu);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
|
||||
|
||||
_this.focusedChild_ = -1;
|
||||
|
||||
_this.on('keydown', _this.handleKeyPress);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link MenuItem} to the menu.
|
||||
*
|
||||
* @param {Object|string} component
|
||||
* The name or instance of the `MenuItem` to add.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
Menu.prototype.addItem = function addItem(component) {
|
||||
this.addChild(component);
|
||||
component.on('click', Fn.bind(this, function (event) {
|
||||
this.unlockShowing();
|
||||
// TODO: Need to set keyboard focus back to the menuButton
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the `Menu`s DOM element.
|
||||
*
|
||||
* @return {Element}
|
||||
* the element that was created
|
||||
*/
|
||||
|
||||
|
||||
Menu.prototype.createEl = function createEl() {
|
||||
var contentElType = this.options_.contentElType || 'ul';
|
||||
|
||||
this.contentEl_ = Dom.createEl(contentElType, {
|
||||
className: 'vjs-menu-content'
|
||||
});
|
||||
|
||||
this.contentEl_.setAttribute('role', 'menu');
|
||||
|
||||
var el = _Component.prototype.createEl.call(this, 'div', {
|
||||
append: this.contentEl_,
|
||||
className: 'vjs-menu'
|
||||
});
|
||||
|
||||
el.setAttribute('role', 'presentation');
|
||||
el.appendChild(this.contentEl_);
|
||||
|
||||
// Prevent clicks from bubbling up. Needed for Menu Buttons,
|
||||
// where a click on the parent is significant
|
||||
Events.on(el, 'click', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
});
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a `keydown` event on this menu. This listener is added in the constructor.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* A `keydown` event that happened on the menu.
|
||||
*
|
||||
* @listens keydown
|
||||
*/
|
||||
|
||||
|
||||
Menu.prototype.handleKeyPress = function handleKeyPress(event) {
|
||||
// Left and Down Arrows
|
||||
if (event.which === 37 || event.which === 40) {
|
||||
event.preventDefault();
|
||||
this.stepForward();
|
||||
|
||||
// Up and Right Arrows
|
||||
} else if (event.which === 38 || event.which === 39) {
|
||||
event.preventDefault();
|
||||
this.stepBack();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Move to next (lower) menu item for keyboard users.
|
||||
*/
|
||||
|
||||
|
||||
Menu.prototype.stepForward = function stepForward() {
|
||||
var stepChild = 0;
|
||||
|
||||
if (this.focusedChild_ !== undefined) {
|
||||
stepChild = this.focusedChild_ + 1;
|
||||
}
|
||||
this.focus(stepChild);
|
||||
};
|
||||
|
||||
/**
|
||||
* Move to previous (higher) menu item for keyboard users.
|
||||
*/
|
||||
|
||||
|
||||
Menu.prototype.stepBack = function stepBack() {
|
||||
var stepChild = 0;
|
||||
|
||||
if (this.focusedChild_ !== undefined) {
|
||||
stepChild = this.focusedChild_ - 1;
|
||||
}
|
||||
this.focus(stepChild);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set focus on a {@link MenuItem} in the `Menu`.
|
||||
*
|
||||
* @param {Object|string} [item=0]
|
||||
* Index of child item set focus on.
|
||||
*/
|
||||
|
||||
|
||||
Menu.prototype.focus = function focus() {
|
||||
var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
||||
|
||||
var children = this.children().slice();
|
||||
var haveTitle = children.length && children[0].className && /vjs-menu-title/.test(children[0].className);
|
||||
|
||||
if (haveTitle) {
|
||||
children.shift();
|
||||
}
|
||||
|
||||
if (children.length > 0) {
|
||||
if (item < 0) {
|
||||
item = 0;
|
||||
} else if (item >= children.length) {
|
||||
item = children.length - 1;
|
||||
}
|
||||
|
||||
this.focusedChild_ = item;
|
||||
|
||||
children[item].el_.focus();
|
||||
}
|
||||
};
|
||||
|
||||
return Menu;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('Menu', Menu);
|
||||
exports['default'] = Menu;
|
||||
@@ -0,0 +1,492 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _dom = require('./utils/dom');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
var _fn = require('./utils/fn');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _component = require('./component');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
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; } }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file modal-dialog.js
|
||||
*/
|
||||
|
||||
|
||||
var MODAL_CLASS_NAME = 'vjs-modal-dialog';
|
||||
var ESC = 27;
|
||||
|
||||
/**
|
||||
* The `ModalDialog` displays over the video and its controls, which blocks
|
||||
* interaction with the player until it is closed.
|
||||
*
|
||||
* Modal dialogs include a "Close" button and will close when that button
|
||||
* is activated - or when ESC is pressed anywhere.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
|
||||
var ModalDialog = function (_Component) {
|
||||
_inherits(ModalDialog, _Component);
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*
|
||||
* @param {Mixed} [options.content=undefined]
|
||||
* Provide customized content for this modal.
|
||||
*
|
||||
* @param {string} [options.description]
|
||||
* A text description for the modal, primarily for accessibility.
|
||||
*
|
||||
* @param {boolean} [options.fillAlways=false]
|
||||
* Normally, modals are automatically filled only the first time
|
||||
* they open. This tells the modal to refresh its content
|
||||
* every time it opens.
|
||||
*
|
||||
* @param {string} [options.label]
|
||||
* A text label for the modal, primarily for accessibility.
|
||||
*
|
||||
* @param {boolean} [options.temporary=true]
|
||||
* If `true`, the modal can only be opened once; it will be
|
||||
* disposed as soon as it's closed.
|
||||
*
|
||||
* @param {boolean} [options.uncloseable=false]
|
||||
* If `true`, the user will not be able to close the modal
|
||||
* through the UI in the normal ways. Programmatic closing is
|
||||
* still possible.
|
||||
*/
|
||||
function ModalDialog(player, options) {
|
||||
_classCallCheck(this, ModalDialog);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
|
||||
|
||||
_this.opened_ = _this.hasBeenOpened_ = _this.hasBeenFilled_ = false;
|
||||
|
||||
_this.closeable(!_this.options_.uncloseable);
|
||||
_this.content(_this.options_.content);
|
||||
|
||||
// Make sure the contentEl is defined AFTER any children are initialized
|
||||
// because we only want the contents of the modal in the contentEl
|
||||
// (not the UI elements like the close button).
|
||||
_this.contentEl_ = Dom.createEl('div', {
|
||||
className: MODAL_CLASS_NAME + '-content'
|
||||
}, {
|
||||
role: 'document'
|
||||
});
|
||||
|
||||
_this.descEl_ = Dom.createEl('p', {
|
||||
className: MODAL_CLASS_NAME + '-description vjs-offscreen',
|
||||
id: _this.el().getAttribute('aria-describedby')
|
||||
});
|
||||
|
||||
Dom.textContent(_this.descEl_, _this.description());
|
||||
_this.el_.appendChild(_this.descEl_);
|
||||
_this.el_.appendChild(_this.contentEl_);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `ModalDialog`'s DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The DOM element that gets created.
|
||||
*/
|
||||
|
||||
|
||||
ModalDialog.prototype.createEl = function createEl() {
|
||||
return _Component.prototype.createEl.call(this, 'div', {
|
||||
className: this.buildCSSClass(),
|
||||
tabIndex: -1
|
||||
}, {
|
||||
'aria-describedby': this.id() + '_description',
|
||||
'aria-hidden': 'true',
|
||||
'aria-label': this.label(),
|
||||
'role': 'dialog'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
ModalDialog.prototype.buildCSSClass = function buildCSSClass() {
|
||||
return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles `keydown` events on the document, looking for ESC, which closes
|
||||
* the modal.
|
||||
*
|
||||
* @param {EventTarget~Event} e
|
||||
* The keypress that triggered this event.
|
||||
*
|
||||
* @listens keydown
|
||||
*/
|
||||
|
||||
|
||||
ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) {
|
||||
if (e.which === ESC && this.closeable()) {
|
||||
this.close();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the label string for this modal. Primarily used for accessibility.
|
||||
*
|
||||
* @return {string}
|
||||
* the localized or raw label of this modal.
|
||||
*/
|
||||
|
||||
|
||||
ModalDialog.prototype.label = function label() {
|
||||
return this.options_.label || this.localize('Modal Window');
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the description string for this modal. Primarily used for
|
||||
* accessibility.
|
||||
*
|
||||
* @return {string}
|
||||
* The localized or raw description of this modal.
|
||||
*/
|
||||
|
||||
|
||||
ModalDialog.prototype.description = function description() {
|
||||
var desc = this.options_.description || this.localize('This is a modal window.');
|
||||
|
||||
// Append a universal closeability message if the modal is closeable.
|
||||
if (this.closeable()) {
|
||||
desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.');
|
||||
}
|
||||
|
||||
return desc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Opens the modal.
|
||||
*
|
||||
* @fires ModalDialog#beforemodalopen
|
||||
* @fires ModalDialog#modalopen
|
||||
*
|
||||
* @return {ModalDialog}
|
||||
* Returns itself; method can be chained.
|
||||
*/
|
||||
|
||||
|
||||
ModalDialog.prototype.open = function open() {
|
||||
if (!this.opened_) {
|
||||
var player = this.player();
|
||||
|
||||
/**
|
||||
* Fired just before a `ModalDialog` is opened.
|
||||
*
|
||||
* @event ModalDialog#beforemodalopen
|
||||
* @type {EventTarget~Event}
|
||||
*/
|
||||
this.trigger('beforemodalopen');
|
||||
this.opened_ = true;
|
||||
|
||||
// Fill content if the modal has never opened before and
|
||||
// never been filled.
|
||||
if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) {
|
||||
this.fill();
|
||||
}
|
||||
|
||||
// If the player was playing, pause it and take note of its previously
|
||||
// playing state.
|
||||
this.wasPlaying_ = !player.paused();
|
||||
|
||||
if (this.wasPlaying_) {
|
||||
player.pause();
|
||||
}
|
||||
|
||||
if (this.closeable()) {
|
||||
this.on(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
|
||||
}
|
||||
|
||||
player.controls(false);
|
||||
this.show();
|
||||
this.el().setAttribute('aria-hidden', 'false');
|
||||
|
||||
/**
|
||||
* Fired just after a `ModalDialog` is opened.
|
||||
*
|
||||
* @event ModalDialog#modalopen
|
||||
* @type {EventTarget~Event}
|
||||
*/
|
||||
this.trigger('modalopen');
|
||||
this.hasBeenOpened_ = true;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* If the `ModalDialog` is currently open or closed.
|
||||
*
|
||||
* @param {boolean} [value]
|
||||
* If given, it will open (`true`) or close (`false`) the modal.
|
||||
*
|
||||
* @return {boolean}
|
||||
* the current open state of the modaldialog
|
||||
*/
|
||||
|
||||
|
||||
ModalDialog.prototype.opened = function opened(value) {
|
||||
if (typeof value === 'boolean') {
|
||||
this[value ? 'open' : 'close']();
|
||||
}
|
||||
return this.opened_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes the modal, does nothing if the `ModalDialog` is
|
||||
* not open.
|
||||
*
|
||||
* @fires ModalDialog#beforemodalclose
|
||||
* @fires ModalDialog#modalclose
|
||||
*
|
||||
* @return {ModalDialog}
|
||||
* Returns itself; method can be chained.
|
||||
*/
|
||||
|
||||
|
||||
ModalDialog.prototype.close = function close() {
|
||||
if (this.opened_) {
|
||||
var player = this.player();
|
||||
|
||||
/**
|
||||
* Fired just before a `ModalDialog` is closed.
|
||||
*
|
||||
* @event ModalDialog#beforemodalclose
|
||||
* @type {EventTarget~Event}
|
||||
*/
|
||||
this.trigger('beforemodalclose');
|
||||
this.opened_ = false;
|
||||
|
||||
if (this.wasPlaying_) {
|
||||
player.play();
|
||||
}
|
||||
|
||||
if (this.closeable()) {
|
||||
this.off(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
|
||||
}
|
||||
|
||||
player.controls(true);
|
||||
this.hide();
|
||||
this.el().setAttribute('aria-hidden', 'true');
|
||||
|
||||
/**
|
||||
* Fired just after a `ModalDialog` is closed.
|
||||
*
|
||||
* @event ModalDialog#modalclose
|
||||
* @type {EventTarget~Event}
|
||||
*/
|
||||
this.trigger('modalclose');
|
||||
|
||||
if (this.options_.temporary) {
|
||||
this.dispose();
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check to see if the `ModalDialog` is closeable via the UI.
|
||||
*
|
||||
* @param {boolean} [value]
|
||||
* If given as a boolean, it will set the `closeable` option.
|
||||
*
|
||||
* @return {boolean}
|
||||
* Returns the final value of the closable option.
|
||||
*/
|
||||
|
||||
|
||||
ModalDialog.prototype.closeable = function closeable(value) {
|
||||
if (typeof value === 'boolean') {
|
||||
var closeable = this.closeable_ = !!value;
|
||||
var close = this.getChild('closeButton');
|
||||
|
||||
// If this is being made closeable and has no close button, add one.
|
||||
if (closeable && !close) {
|
||||
|
||||
// The close button should be a child of the modal - not its
|
||||
// content element, so temporarily change the content element.
|
||||
var temp = this.contentEl_;
|
||||
|
||||
this.contentEl_ = this.el_;
|
||||
close = this.addChild('closeButton', { controlText: 'Close Modal Dialog' });
|
||||
this.contentEl_ = temp;
|
||||
this.on(close, 'close', this.close);
|
||||
}
|
||||
|
||||
// If this is being made uncloseable and has a close button, remove it.
|
||||
if (!closeable && close) {
|
||||
this.off(close, 'close', this.close);
|
||||
this.removeChild(close);
|
||||
close.dispose();
|
||||
}
|
||||
}
|
||||
return this.closeable_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fill the modal's content element with the modal's "content" option.
|
||||
* The content element will be emptied before this change takes place.
|
||||
*
|
||||
* @return {ModalDialog}
|
||||
* Returns itself; method can be chained.
|
||||
*/
|
||||
|
||||
|
||||
ModalDialog.prototype.fill = function fill() {
|
||||
return this.fillWith(this.content());
|
||||
};
|
||||
|
||||
/**
|
||||
* Fill the modal's content element with arbitrary content.
|
||||
* The content element will be emptied before this change takes place.
|
||||
*
|
||||
* @fires ModalDialog#beforemodalfill
|
||||
* @fires ModalDialog#modalfill
|
||||
*
|
||||
* @param {Mixed} [content]
|
||||
* The same rules apply to this as apply to the `content` option.
|
||||
*
|
||||
* @return {ModalDialog}
|
||||
* Returns itself; method can be chained.
|
||||
*/
|
||||
|
||||
|
||||
ModalDialog.prototype.fillWith = function fillWith(content) {
|
||||
var contentEl = this.contentEl();
|
||||
var parentEl = contentEl.parentNode;
|
||||
var nextSiblingEl = contentEl.nextSibling;
|
||||
|
||||
/**
|
||||
* Fired just before a `ModalDialog` is filled with content.
|
||||
*
|
||||
* @event ModalDialog#beforemodalfill
|
||||
* @type {EventTarget~Event}
|
||||
*/
|
||||
this.trigger('beforemodalfill');
|
||||
this.hasBeenFilled_ = true;
|
||||
|
||||
// Detach the content element from the DOM before performing
|
||||
// manipulation to avoid modifying the live DOM multiple times.
|
||||
parentEl.removeChild(contentEl);
|
||||
this.empty();
|
||||
Dom.insertContent(contentEl, content);
|
||||
/**
|
||||
* Fired just after a `ModalDialog` is filled with content.
|
||||
*
|
||||
* @event ModalDialog#modalfill
|
||||
* @type {EventTarget~Event}
|
||||
*/
|
||||
this.trigger('modalfill');
|
||||
|
||||
// Re-inject the re-filled content element.
|
||||
if (nextSiblingEl) {
|
||||
parentEl.insertBefore(contentEl, nextSiblingEl);
|
||||
} else {
|
||||
parentEl.appendChild(contentEl);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Empties the content element. This happens anytime the modal is filled.
|
||||
*
|
||||
* @fires ModalDialog#beforemodalempty
|
||||
* @fires ModalDialog#modalempty
|
||||
*
|
||||
* @return {ModalDialog}
|
||||
* Returns itself; method can be chained.
|
||||
*/
|
||||
|
||||
|
||||
ModalDialog.prototype.empty = function empty() {
|
||||
/**
|
||||
* Fired just before a `ModalDialog` is emptied.
|
||||
*
|
||||
* @event ModalDialog#beforemodalempty
|
||||
* @type {EventTarget~Event}
|
||||
*/
|
||||
this.trigger('beforemodalempty');
|
||||
Dom.emptyEl(this.contentEl());
|
||||
|
||||
/**
|
||||
* Fired just after a `ModalDialog` is emptied.
|
||||
*
|
||||
* @event ModalDialog#modalempty
|
||||
* @type {EventTarget~Event}
|
||||
*/
|
||||
this.trigger('modalempty');
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets or sets the modal content, which gets normalized before being
|
||||
* rendered into the DOM.
|
||||
*
|
||||
* This does not update the DOM or fill the modal, but it is called during
|
||||
* that process.
|
||||
*
|
||||
* @param {Mixed} [value]
|
||||
* If defined, sets the internal content value to be used on the
|
||||
* next call(s) to `fill`. This value is normalized before being
|
||||
* inserted. To "clear" the internal content value, pass `null`.
|
||||
*
|
||||
* @return {Mixed}
|
||||
* The current content of the modal dialog
|
||||
*/
|
||||
|
||||
|
||||
ModalDialog.prototype.content = function content(value) {
|
||||
if (typeof value !== 'undefined') {
|
||||
this.content_ = value;
|
||||
}
|
||||
return this.content_;
|
||||
};
|
||||
|
||||
return ModalDialog;
|
||||
}(_component2['default']);
|
||||
|
||||
/**
|
||||
* Default options for `ModalDialog` default options.
|
||||
*
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
ModalDialog.prototype.options_ = {
|
||||
temporary: true
|
||||
};
|
||||
|
||||
_component2['default'].registerComponent('ModalDialog', ModalDialog);
|
||||
exports['default'] = ModalDialog;
|
||||
+3637
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,26 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _player = require('./player.js');
|
||||
|
||||
var _player2 = _interopRequireDefault(_player);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
/**
|
||||
* The method for registering a video.js plugin. {@link videojs:videojs.registerPlugin].
|
||||
*
|
||||
* @param {string} name
|
||||
* The name of the plugin that is being registered
|
||||
*
|
||||
* @param {plugins:PluginFn} init
|
||||
* The function that gets run when a `Player` initializes.
|
||||
*/
|
||||
var plugin = function plugin(name, init) {
|
||||
_player2['default'].prototype[name] = init;
|
||||
}; /**
|
||||
* @file plugins.js
|
||||
* @module plugins
|
||||
*/
|
||||
exports['default'] = plugin;
|
||||
@@ -0,0 +1,122 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _clickableComponent = require('../clickable-component.js');
|
||||
|
||||
var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
|
||||
|
||||
var _component = require('../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file popup-button.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A button class for use with {@link Popup} controls
|
||||
*
|
||||
* @extends ClickableComponent
|
||||
*/
|
||||
var PopupButton = function (_ClickableComponent) {
|
||||
_inherits(PopupButton, _ClickableComponent);
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function PopupButton(player) {
|
||||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
_classCallCheck(this, PopupButton);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
|
||||
|
||||
_this.update();
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the `Popup` that this button is attached to.
|
||||
*/
|
||||
|
||||
|
||||
PopupButton.prototype.update = function update() {
|
||||
var popup = this.createPopup();
|
||||
|
||||
if (this.popup) {
|
||||
this.removeChild(this.popup);
|
||||
}
|
||||
|
||||
this.popup = popup;
|
||||
this.addChild(popup);
|
||||
|
||||
if (this.items && this.items.length === 0) {
|
||||
this.hide();
|
||||
} else if (this.items && this.items.length > 1) {
|
||||
this.show();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a `Popup`. - Override with specific functionality for component
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
|
||||
PopupButton.prototype.createPopup = function createPopup() {};
|
||||
|
||||
/**
|
||||
* Create the `PopupButton`s DOM element.
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that gets created.
|
||||
*/
|
||||
|
||||
|
||||
PopupButton.prototype.createEl = function createEl() {
|
||||
return _ClickableComponent.prototype.createEl.call(this, 'div', {
|
||||
className: this.buildCSSClass()
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds the default DOM `className`.
|
||||
*
|
||||
* @return {string}
|
||||
* The DOM `className` for this object.
|
||||
*/
|
||||
|
||||
|
||||
PopupButton.prototype.buildCSSClass = function buildCSSClass() {
|
||||
var menuButtonClass = 'vjs-menu-button';
|
||||
|
||||
// If the inline option is passed, we want to use different styles altogether.
|
||||
if (this.options_.inline === true) {
|
||||
menuButtonClass += '-inline';
|
||||
} else {
|
||||
menuButtonClass += '-popup';
|
||||
}
|
||||
|
||||
return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
|
||||
};
|
||||
|
||||
return PopupButton;
|
||||
}(_clickableComponent2['default']);
|
||||
|
||||
_component2['default'].registerComponent('PopupButton', PopupButton);
|
||||
exports['default'] = PopupButton;
|
||||
@@ -0,0 +1,98 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _dom = require('../utils/dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
var _fn = require('../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _events = require('../utils/events.js');
|
||||
|
||||
var Events = _interopRequireWildcard(_events);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file popup.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The Popup component is used to build pop up controls.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var Popup = function (_Component) {
|
||||
_inherits(Popup, _Component);
|
||||
|
||||
function Popup() {
|
||||
_classCallCheck(this, Popup);
|
||||
|
||||
return _possibleConstructorReturn(this, _Component.apply(this, arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a popup item to the popup
|
||||
*
|
||||
* @param {Object|string} component
|
||||
* Component or component type to add
|
||||
*
|
||||
*/
|
||||
Popup.prototype.addItem = function addItem(component) {
|
||||
this.addChild(component);
|
||||
component.on('click', Fn.bind(this, function () {
|
||||
this.unlockShowing();
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the `PopupButton`s DOM element.
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that gets created.
|
||||
*/
|
||||
|
||||
|
||||
Popup.prototype.createEl = function createEl() {
|
||||
var contentElType = this.options_.contentElType || 'ul';
|
||||
|
||||
this.contentEl_ = Dom.createEl(contentElType, {
|
||||
className: 'vjs-menu-content'
|
||||
});
|
||||
|
||||
var el = _Component.prototype.createEl.call(this, 'div', {
|
||||
append: this.contentEl_,
|
||||
className: 'vjs-menu'
|
||||
});
|
||||
|
||||
el.appendChild(this.contentEl_);
|
||||
|
||||
// Prevent clicks from bubbling up. Needed for Popup Buttons,
|
||||
// where a click on the parent is significant
|
||||
Events.on(el, 'click', function (event) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
});
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
return Popup;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('Popup', Popup);
|
||||
exports['default'] = Popup;
|
||||
@@ -0,0 +1,181 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _clickableComponent = require('./clickable-component.js');
|
||||
|
||||
var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
|
||||
|
||||
var _component = require('./component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _fn = require('./utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _dom = require('./utils/dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
var _browser = require('./utils/browser.js');
|
||||
|
||||
var browser = _interopRequireWildcard(_browser);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file poster-image.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A `ClickableComponent` that handles showing the poster image for the player.
|
||||
*
|
||||
* @extends ClickableComponent
|
||||
*/
|
||||
var PosterImage = function (_ClickableComponent) {
|
||||
_inherits(PosterImage, _ClickableComponent);
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should attach to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function PosterImage(player, options) {
|
||||
_classCallCheck(this, PosterImage);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
|
||||
|
||||
_this.update();
|
||||
player.on('posterchange', Fn.bind(_this, _this.update));
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up and dispose of the `PosterImage`.
|
||||
*/
|
||||
|
||||
|
||||
PosterImage.prototype.dispose = function dispose() {
|
||||
this.player().off('posterchange', this.update);
|
||||
_ClickableComponent.prototype.dispose.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the `PosterImage`s DOM element.
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that gets created.
|
||||
*/
|
||||
|
||||
|
||||
PosterImage.prototype.createEl = function createEl() {
|
||||
var el = Dom.createEl('div', {
|
||||
className: 'vjs-poster',
|
||||
|
||||
// Don't want poster to be tabbable.
|
||||
tabIndex: -1
|
||||
});
|
||||
|
||||
// To ensure the poster image resizes while maintaining its original aspect
|
||||
// ratio, use a div with `background-size` when available. For browsers that
|
||||
// do not support `background-size` (e.g. IE8), fall back on using a regular
|
||||
// img element.
|
||||
if (!browser.BACKGROUND_SIZE_SUPPORTED) {
|
||||
this.fallbackImg_ = Dom.createEl('img');
|
||||
el.appendChild(this.fallbackImg_);
|
||||
}
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
/**
|
||||
* An {@link EventTarget~EventListener} for {@link Player#posterchange} events.
|
||||
*
|
||||
* @listens Player#posterchange
|
||||
*
|
||||
* @param {EventTarget~Event} [event]
|
||||
* The `Player#posterchange` event that triggered this function.
|
||||
*/
|
||||
|
||||
|
||||
PosterImage.prototype.update = function update(event) {
|
||||
var url = this.player().poster();
|
||||
|
||||
this.setSrc(url);
|
||||
|
||||
// If there's no poster source we should display:none on this component
|
||||
// so it's not still clickable or right-clickable
|
||||
if (url) {
|
||||
this.show();
|
||||
} else {
|
||||
this.hide();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the source of the `PosterImage` depending on the display method.
|
||||
*
|
||||
* @param {string} url
|
||||
* The URL to the source for the `PosterImage`.
|
||||
*/
|
||||
|
||||
|
||||
PosterImage.prototype.setSrc = function setSrc(url) {
|
||||
if (this.fallbackImg_) {
|
||||
this.fallbackImg_.src = url;
|
||||
} else {
|
||||
var backgroundImage = '';
|
||||
|
||||
// Any falsey values should stay as an empty string, otherwise
|
||||
// this will throw an extra error
|
||||
if (url) {
|
||||
backgroundImage = 'url("' + url + '")';
|
||||
}
|
||||
|
||||
this.el_.style.backgroundImage = backgroundImage;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* An {@link EventTarget~EventListener} for clicks on the `PosterImage`. See
|
||||
* {@link ClickableComponent#handleClick} for instances where this will be triggered.
|
||||
*
|
||||
* @listens tap
|
||||
* @listens click
|
||||
* @listens keydown
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
+ The `click`, `tap` or `keydown` event that caused this function to be called.
|
||||
*/
|
||||
|
||||
|
||||
PosterImage.prototype.handleClick = function handleClick(event) {
|
||||
// We don't want a click to trigger playback when controls are disabled
|
||||
if (!this.player_.controls()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.player_.paused()) {
|
||||
this.player_.play();
|
||||
} else {
|
||||
this.player_.pause();
|
||||
}
|
||||
};
|
||||
|
||||
return PosterImage;
|
||||
}(_clickableComponent2['default']);
|
||||
|
||||
_component2['default'].registerComponent('PosterImage', PosterImage);
|
||||
exports['default'] = PosterImage;
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
exports.hasLoaded = exports.autoSetupTimeout = exports.autoSetup = undefined;
|
||||
|
||||
var _dom = require('./utils/dom');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
var _events = require('./utils/events.js');
|
||||
|
||||
var Events = _interopRequireWildcard(_events);
|
||||
|
||||
var _document = require('global/document');
|
||||
|
||||
var _document2 = _interopRequireDefault(_document);
|
||||
|
||||
var _window = require('global/window');
|
||||
|
||||
var _window2 = _interopRequireDefault(_window);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
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; } }
|
||||
|
||||
/**
|
||||
* @file setup.js - Functions for setting up a player without
|
||||
* user interaction based on the data-setup `attribute` of the video tag.
|
||||
*
|
||||
* @module setup
|
||||
*/
|
||||
var _windowLoaded = false;
|
||||
var videojs = void 0;
|
||||
|
||||
/**
|
||||
* Set up any tags that have a data-setup `attribute` when the player is started.
|
||||
*/
|
||||
var autoSetup = function autoSetup() {
|
||||
|
||||
// Protect against breakage in non-browser environments.
|
||||
if (!Dom.isReal()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack*
|
||||
// var vids = Array.prototype.slice.call(document.getElementsByTagName('video'));
|
||||
// var audios = Array.prototype.slice.call(document.getElementsByTagName('audio'));
|
||||
// var mediaEls = vids.concat(audios);
|
||||
|
||||
// Because IE8 doesn't support calling slice on a node list, we need to loop
|
||||
// through each list of elements to build up a new, combined list of elements.
|
||||
var vids = _document2['default'].getElementsByTagName('video');
|
||||
var audios = _document2['default'].getElementsByTagName('audio');
|
||||
var mediaEls = [];
|
||||
|
||||
if (vids && vids.length > 0) {
|
||||
for (var i = 0, e = vids.length; i < e; i++) {
|
||||
mediaEls.push(vids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (audios && audios.length > 0) {
|
||||
for (var _i = 0, _e = audios.length; _i < _e; _i++) {
|
||||
mediaEls.push(audios[_i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if any media elements exist
|
||||
if (mediaEls && mediaEls.length > 0) {
|
||||
|
||||
for (var _i2 = 0, _e2 = mediaEls.length; _i2 < _e2; _i2++) {
|
||||
var mediaEl = mediaEls[_i2];
|
||||
|
||||
// Check if element exists, has getAttribute func.
|
||||
// IE seems to consider typeof el.getAttribute == 'object' instead of
|
||||
// 'function' like expected, at least when loading the player immediately.
|
||||
if (mediaEl && mediaEl.getAttribute) {
|
||||
|
||||
// Make sure this player hasn't already been set up.
|
||||
if (mediaEl.player === undefined) {
|
||||
var options = mediaEl.getAttribute('data-setup');
|
||||
|
||||
// Check if data-setup attr exists.
|
||||
// We only auto-setup if they've added the data-setup attr.
|
||||
if (options !== null) {
|
||||
// Create new video.js instance.
|
||||
videojs(mediaEl);
|
||||
}
|
||||
}
|
||||
|
||||
// If getAttribute isn't defined, we need to wait for the DOM.
|
||||
} else {
|
||||
autoSetupTimeout(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// No videos were found, so keep looping unless page is finished loading.
|
||||
} else if (!_windowLoaded) {
|
||||
autoSetupTimeout(1);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Wait until the page is loaded before running autoSetup. This will be called in
|
||||
* autoSetup if `hasLoaded` returns false.
|
||||
*
|
||||
* @param {number} wait
|
||||
* How long to wait in ms
|
||||
*
|
||||
* @param {videojs} [vjs]
|
||||
* The videojs library function
|
||||
*/
|
||||
function autoSetupTimeout(wait, vjs) {
|
||||
if (vjs) {
|
||||
videojs = vjs;
|
||||
}
|
||||
|
||||
_window2['default'].setTimeout(autoSetup, wait);
|
||||
}
|
||||
|
||||
if (Dom.isReal() && _document2['default'].readyState === 'complete') {
|
||||
_windowLoaded = true;
|
||||
} else {
|
||||
/**
|
||||
* Listen for the load event on window, and set _windowLoaded to true.
|
||||
*
|
||||
* @listens load
|
||||
*/
|
||||
Events.one(_window2['default'], 'load', function () {
|
||||
_windowLoaded = true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the document has been loaded
|
||||
*/
|
||||
var hasLoaded = function hasLoaded() {
|
||||
return _windowLoaded;
|
||||
};
|
||||
|
||||
exports.autoSetup = autoSetup;
|
||||
exports.autoSetupTimeout = autoSetupTimeout;
|
||||
exports.hasLoaded = hasLoaded;
|
||||
@@ -0,0 +1,353 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _dom = require('../utils/dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
var _obj = require('../utils/obj');
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file slider.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The base functionality for a slider. Can be vertical or horizontal.
|
||||
* For instance the volume bar or the seek bar on a video is a slider.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var Slider = function (_Component) {
|
||||
_inherits(Slider, _Component);
|
||||
|
||||
/**
|
||||
* Create an instance of this class
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function Slider(player, options) {
|
||||
_classCallCheck(this, Slider);
|
||||
|
||||
// Set property names to bar to match with the child Slider class is looking for
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
|
||||
|
||||
_this.bar = _this.getChild(_this.options_.barName);
|
||||
|
||||
// Set a horizontal or vertical class on the slider depending on the slider type
|
||||
_this.vertical(!!_this.options_.vertical);
|
||||
|
||||
_this.on('mousedown', _this.handleMouseDown);
|
||||
_this.on('touchstart', _this.handleMouseDown);
|
||||
_this.on('focus', _this.handleFocus);
|
||||
_this.on('blur', _this.handleBlur);
|
||||
_this.on('click', _this.handleClick);
|
||||
|
||||
_this.on(player, 'controlsvisible', _this.update);
|
||||
_this.on(player, _this.playerEvent, _this.update);
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `Button`s DOM element.
|
||||
*
|
||||
* @param {string} type
|
||||
* Type of element to create.
|
||||
*
|
||||
* @param {Object} [props={}]
|
||||
* List of properties in Object form.
|
||||
*
|
||||
* @param {Object} [attributes={}]
|
||||
* list of attributes in Object form.
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that gets created.
|
||||
*/
|
||||
|
||||
|
||||
Slider.prototype.createEl = function createEl(type) {
|
||||
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
||||
|
||||
// Add the slider element class to all sub classes
|
||||
props.className = props.className + ' vjs-slider';
|
||||
props = (0, _obj.assign)({
|
||||
tabIndex: 0
|
||||
}, props);
|
||||
|
||||
attributes = (0, _obj.assign)({
|
||||
'role': 'slider',
|
||||
'aria-valuenow': 0,
|
||||
'aria-valuemin': 0,
|
||||
'aria-valuemax': 100,
|
||||
'tabIndex': 0
|
||||
}, attributes);
|
||||
|
||||
return _Component.prototype.createEl.call(this, type, props, attributes);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle `mousedown` or `touchstart` events on the `Slider`.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* `mousedown` or `touchstart` event that triggered this function
|
||||
*
|
||||
* @listens mousedown
|
||||
* @listens touchstart
|
||||
* @fires Slider#slideractive
|
||||
*/
|
||||
|
||||
|
||||
Slider.prototype.handleMouseDown = function handleMouseDown(event) {
|
||||
var doc = this.bar.el_.ownerDocument;
|
||||
|
||||
event.preventDefault();
|
||||
Dom.blockTextSelection();
|
||||
|
||||
this.addClass('vjs-sliding');
|
||||
/**
|
||||
* Triggered when the slider is in an active state
|
||||
*
|
||||
* @event Slider#slideractive
|
||||
* @type {EventTarget~Event}
|
||||
*/
|
||||
this.trigger('slideractive');
|
||||
|
||||
this.on(doc, 'mousemove', this.handleMouseMove);
|
||||
this.on(doc, 'mouseup', this.handleMouseUp);
|
||||
this.on(doc, 'touchmove', this.handleMouseMove);
|
||||
this.on(doc, 'touchend', this.handleMouseUp);
|
||||
|
||||
this.handleMouseMove(event);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle the `mousemove`, `touchmove`, and `mousedown` events on this `Slider`.
|
||||
* The `mousemove` and `touchmove` events will only only trigger this function during
|
||||
* `mousedown` and `touchstart`. This is due to {@link Slider#handleMouseDown} and
|
||||
* {@link Slider#handleMouseUp}.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* `mousedown`, `mousemove`, `touchstart`, or `touchmove` event that triggered
|
||||
* this function
|
||||
*
|
||||
* @listens mousemove
|
||||
* @listens touchmove
|
||||
*/
|
||||
|
||||
|
||||
Slider.prototype.handleMouseMove = function handleMouseMove(event) {};
|
||||
|
||||
/**
|
||||
* Handle `mouseup` or `touchend` events on the `Slider`.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* `mouseup` or `touchend` event that triggered this function.
|
||||
*
|
||||
* @listens touchend
|
||||
* @listens mouseup
|
||||
* @fires Slider#sliderinactive
|
||||
*/
|
||||
|
||||
|
||||
Slider.prototype.handleMouseUp = function handleMouseUp() {
|
||||
var doc = this.bar.el_.ownerDocument;
|
||||
|
||||
Dom.unblockTextSelection();
|
||||
|
||||
this.removeClass('vjs-sliding');
|
||||
/**
|
||||
* Triggered when the slider is no longer in an active state.
|
||||
*
|
||||
* @event Slider#sliderinactive
|
||||
* @type {EventTarget~Event}
|
||||
*/
|
||||
this.trigger('sliderinactive');
|
||||
|
||||
this.off(doc, 'mousemove', this.handleMouseMove);
|
||||
this.off(doc, 'mouseup', this.handleMouseUp);
|
||||
this.off(doc, 'touchmove', this.handleMouseMove);
|
||||
this.off(doc, 'touchend', this.handleMouseUp);
|
||||
|
||||
this.update();
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the progress bar of the `Slider`.
|
||||
*/
|
||||
|
||||
|
||||
Slider.prototype.update = function update() {
|
||||
// In VolumeBar init we have a setTimeout for update that pops and update to the end of the
|
||||
// execution stack. The player is destroyed before then update will cause an error
|
||||
if (!this.el_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.
|
||||
// On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.
|
||||
// var progress = (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration();
|
||||
var progress = this.getPercent();
|
||||
var bar = this.bar;
|
||||
|
||||
// If there's no bar...
|
||||
if (!bar) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Protect against no duration and other division issues
|
||||
if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) {
|
||||
progress = 0;
|
||||
}
|
||||
|
||||
// Convert to a percentage for setting
|
||||
var percentage = (progress * 100).toFixed(2) + '%';
|
||||
|
||||
// Set the new bar width or height
|
||||
if (this.vertical()) {
|
||||
bar.el().style.height = percentage;
|
||||
} else {
|
||||
bar.el().style.width = percentage;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate distance for slider
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The event that caused this function to run.
|
||||
*
|
||||
* @return {number}
|
||||
* The current position of the Slider.
|
||||
* - postition.x for vertical `Slider`s
|
||||
* - postition.y for horizontal `Slider`s
|
||||
*/
|
||||
|
||||
|
||||
Slider.prototype.calculateDistance = function calculateDistance(event) {
|
||||
var position = Dom.getPointerPosition(this.el_, event);
|
||||
|
||||
if (this.vertical()) {
|
||||
return position.y;
|
||||
}
|
||||
return position.x;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a `focus` event on this `Slider`.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `focus` event that caused this function to run.
|
||||
*
|
||||
* @listens focus
|
||||
*/
|
||||
|
||||
|
||||
Slider.prototype.handleFocus = function handleFocus() {
|
||||
this.on(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a `keydown` event on the `Slider`. Watches for left, rigth, up, and down
|
||||
* arrow keys. This function will only be called when the slider has focus. See
|
||||
* {@link Slider#handleFocus} and {@link Slider#handleBlur}.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* the `keydown` event that caused this function to run.
|
||||
*
|
||||
* @listens keydown
|
||||
*/
|
||||
|
||||
|
||||
Slider.prototype.handleKeyPress = function handleKeyPress(event) {
|
||||
// Left and Down Arrows
|
||||
if (event.which === 37 || event.which === 40) {
|
||||
event.preventDefault();
|
||||
this.stepBack();
|
||||
|
||||
// Up and Right Arrows
|
||||
} else if (event.which === 38 || event.which === 39) {
|
||||
event.preventDefault();
|
||||
this.stepForward();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a `blur` event on this `Slider`.
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* The `blur` event that caused this function to run.
|
||||
*
|
||||
* @listens blur
|
||||
*/
|
||||
|
||||
Slider.prototype.handleBlur = function handleBlur() {
|
||||
this.off(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
|
||||
};
|
||||
|
||||
/**
|
||||
* Listener for click events on slider, used to prevent clicks
|
||||
* from bubbling up to parent elements like button menus.
|
||||
*
|
||||
* @param {Object} event
|
||||
* Event that caused this object to run
|
||||
*/
|
||||
|
||||
|
||||
Slider.prototype.handleClick = function handleClick(event) {
|
||||
event.stopImmediatePropagation();
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get/set if slider is horizontal for vertical
|
||||
*
|
||||
* @param {boolean} [bool]
|
||||
* - true if slider is vertical,
|
||||
* - false is horizontal
|
||||
*
|
||||
* @return {boolean|Slider}
|
||||
* - true if slider is vertical, and getting
|
||||
* - false is horizontal, and getting
|
||||
* - a reference to this object when setting
|
||||
*/
|
||||
|
||||
|
||||
Slider.prototype.vertical = function vertical(bool) {
|
||||
if (bool === undefined) {
|
||||
return this.vertical_ || false;
|
||||
}
|
||||
|
||||
this.vertical_ = !!bool;
|
||||
|
||||
if (this.vertical_) {
|
||||
this.addClass('vjs-slider-vertical');
|
||||
} else {
|
||||
this.addClass('vjs-slider-horizontal');
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
return Slider;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('Slider', Slider);
|
||||
exports['default'] = Slider;
|
||||
@@ -0,0 +1,202 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
/**
|
||||
* @file flash-rtmp.js
|
||||
* @module flash-rtmp
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add RTMP properties to the {@link Flash} Tech.
|
||||
*
|
||||
* @param {Flash} Flash
|
||||
* The flash tech class.
|
||||
*
|
||||
* @mixin FlashRtmpDecorator
|
||||
*/
|
||||
function FlashRtmpDecorator(Flash) {
|
||||
Flash.streamingFormats = {
|
||||
'rtmp/mp4': 'MP4',
|
||||
'rtmp/flv': 'FLV'
|
||||
};
|
||||
|
||||
/**
|
||||
* Join connection and stream with an ampersand.
|
||||
*
|
||||
* @param {string} connection
|
||||
* The connection string.
|
||||
*
|
||||
* @param {string} stream
|
||||
* The stream string.
|
||||
*/
|
||||
Flash.streamFromParts = function (connection, stream) {
|
||||
return connection + '&' + stream;
|
||||
};
|
||||
|
||||
/**
|
||||
* The flash parts object that contains connection and stream info.
|
||||
*
|
||||
* @typedef {Object} Flash~PartsObject
|
||||
*
|
||||
* @property {string} connection
|
||||
* The connection string of a source, defaults to an empty string.
|
||||
*
|
||||
* @property {string} stream
|
||||
* The stream string of the source, defaults to an empty string.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convert a source url into a stream and connection parts.
|
||||
*
|
||||
* @param {string} src
|
||||
* the source url
|
||||
*
|
||||
* @return {Flash~PartsObject}
|
||||
* The parts object that contains a connection and a stream
|
||||
*/
|
||||
Flash.streamToParts = function (src) {
|
||||
var parts = {
|
||||
connection: '',
|
||||
stream: ''
|
||||
};
|
||||
|
||||
if (!src) {
|
||||
return parts;
|
||||
}
|
||||
|
||||
// Look for the normal URL separator we expect, '&'.
|
||||
// If found, we split the URL into two pieces around the
|
||||
// first '&'.
|
||||
var connEnd = src.search(/&(?!\w+=)/);
|
||||
var streamBegin = void 0;
|
||||
|
||||
if (connEnd !== -1) {
|
||||
streamBegin = connEnd + 1;
|
||||
} else {
|
||||
// If there's not a '&', we use the last '/' as the delimiter.
|
||||
connEnd = streamBegin = src.lastIndexOf('/') + 1;
|
||||
if (connEnd === 0) {
|
||||
// really, there's not a '/'?
|
||||
connEnd = streamBegin = src.length;
|
||||
}
|
||||
}
|
||||
|
||||
parts.connection = src.substring(0, connEnd);
|
||||
parts.stream = src.substring(streamBegin, src.length);
|
||||
|
||||
return parts;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the source type is a streaming type.
|
||||
*
|
||||
* @param {string} srcType
|
||||
* The mime type to check.
|
||||
*
|
||||
* @return {boolean}
|
||||
* - True if the source type is a streaming type.
|
||||
* - False if the source type is not a streaming type.
|
||||
*/
|
||||
Flash.isStreamingType = function (srcType) {
|
||||
return srcType in Flash.streamingFormats;
|
||||
};
|
||||
|
||||
// RTMP has four variations, any string starting
|
||||
// with one of these protocols should be valid
|
||||
|
||||
/**
|
||||
* Regular expression used to check if the source is an rtmp source.
|
||||
*
|
||||
* @property {RegExp} Flash.RTMP_RE
|
||||
*/
|
||||
Flash.RTMP_RE = /^rtmp[set]?:\/\//i;
|
||||
|
||||
/**
|
||||
* Check if the source itself is a streaming type.
|
||||
*
|
||||
* @param {string} src
|
||||
* The url to the source.
|
||||
*
|
||||
* @return {boolean}
|
||||
* - True if the source url indicates that the source is streaming.
|
||||
* - False if the shource url indicates that the source url is not streaming.
|
||||
*/
|
||||
Flash.isStreamingSrc = function (src) {
|
||||
return Flash.RTMP_RE.test(src);
|
||||
};
|
||||
|
||||
/**
|
||||
* A source handler for RTMP urls
|
||||
* @type {Object}
|
||||
*/
|
||||
Flash.rtmpSourceHandler = {};
|
||||
|
||||
/**
|
||||
* Check if Flash can play the given mime type.
|
||||
*
|
||||
* @param {string} type
|
||||
* The mime type to check
|
||||
*
|
||||
* @return {string}
|
||||
* 'maybe', or '' (empty string)
|
||||
*/
|
||||
Flash.rtmpSourceHandler.canPlayType = function (type) {
|
||||
if (Flash.isStreamingType(type)) {
|
||||
return 'maybe';
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if Flash can handle the source natively
|
||||
*
|
||||
* @param {Object} source
|
||||
* The source object
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The options passed to the tech
|
||||
*
|
||||
* @return {string}
|
||||
* 'maybe', or '' (empty string)
|
||||
*/
|
||||
Flash.rtmpSourceHandler.canHandleSource = function (source, options) {
|
||||
var can = Flash.rtmpSourceHandler.canPlayType(source.type);
|
||||
|
||||
if (can) {
|
||||
return can;
|
||||
}
|
||||
|
||||
if (Flash.isStreamingSrc(source.src)) {
|
||||
return 'maybe';
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Pass the source to the flash object.
|
||||
*
|
||||
* @param {Object} source
|
||||
* The source object
|
||||
*
|
||||
* @param {Flash} tech
|
||||
* The instance of the Flash tech
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The options to pass to the source
|
||||
*/
|
||||
Flash.rtmpSourceHandler.handleSource = function (source, tech, options) {
|
||||
var srcParts = Flash.streamToParts(source.src);
|
||||
|
||||
tech.setRtmpConnection(srcParts.connection);
|
||||
tech.setRtmpStream(srcParts.stream);
|
||||
};
|
||||
|
||||
// Register the native source handler
|
||||
Flash.registerSourceHandler(Flash.rtmpSourceHandler);
|
||||
|
||||
return Flash;
|
||||
}
|
||||
|
||||
exports['default'] = FlashRtmpDecorator;
|
||||
+1157
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+1769
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,88 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../component.js');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _tech = require('./tech.js');
|
||||
|
||||
var _tech2 = _interopRequireDefault(_tech);
|
||||
|
||||
var _toTitleCase = require('../utils/to-title-case.js');
|
||||
|
||||
var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file loader.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The `MediaLoader` is the `Component` that decides which playback technology to load
|
||||
* when a player is initialized.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
var MediaLoader = function (_Component) {
|
||||
_inherits(MediaLoader, _Component);
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should attach to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value stroe of player options.
|
||||
*
|
||||
* @param {Component~ReadyCallback} [ready]
|
||||
* The function that is run when this component is ready.
|
||||
*/
|
||||
function MediaLoader(player, options, ready) {
|
||||
_classCallCheck(this, MediaLoader);
|
||||
|
||||
// If there are no sources when the player is initialized,
|
||||
// load the first supported playback technology.
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready));
|
||||
|
||||
if (!options.playerOptions.sources || options.playerOptions.sources.length === 0) {
|
||||
for (var i = 0, j = options.playerOptions.techOrder; i < j.length; i++) {
|
||||
var techName = (0, _toTitleCase2['default'])(j[i]);
|
||||
var tech = _tech2['default'].getTech(techName);
|
||||
|
||||
// Support old behavior of techs being registered as components.
|
||||
// Remove once that deprecated behavior is removed.
|
||||
if (!techName) {
|
||||
tech = _component2['default'].getComponent(techName);
|
||||
}
|
||||
|
||||
// Check if the browser supports this technology
|
||||
if (tech && tech.isSupported()) {
|
||||
player.loadTech_(techName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Loop through playback technologies (HTML5, Flash) and check for support.
|
||||
// Then load the best source.
|
||||
// A few assumptions here:
|
||||
// All playback technologies respect preload false.
|
||||
player.src(options.playerOptions.sources);
|
||||
}
|
||||
return _this;
|
||||
}
|
||||
|
||||
return MediaLoader;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('MediaLoader', MediaLoader);
|
||||
exports['default'] = MediaLoader;
|
||||
+1369
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,181 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _trackList = require('./track-list');
|
||||
|
||||
var _trackList2 = _interopRequireDefault(_trackList);
|
||||
|
||||
var _browser = require('../utils/browser.js');
|
||||
|
||||
var browser = _interopRequireWildcard(_browser);
|
||||
|
||||
var _document = require('global/document');
|
||||
|
||||
var _document2 = _interopRequireDefault(_document);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file audio-track-list.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Anywhere we call this function we diverge from the spec
|
||||
* as we only support one enabled audiotrack at a time
|
||||
*
|
||||
* @param {AudioTrackList} list
|
||||
* list to work on
|
||||
*
|
||||
* @param {AudioTrack} track
|
||||
* The track to skip
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var disableOthers = function disableOthers(list, track) {
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (track.id === list[i].id) {
|
||||
continue;
|
||||
}
|
||||
// another audio track is enabled, disable it
|
||||
list[i].enabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The current list of {@link AudioTrack} for a media file.
|
||||
*
|
||||
* @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist}
|
||||
* @extends TrackList
|
||||
*/
|
||||
|
||||
var AudioTrackList = function (_TrackList) {
|
||||
_inherits(AudioTrackList, _TrackList);
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*
|
||||
* @param {AudioTrack[]} [tracks=[]]
|
||||
* A list of `AudioTrack` to instantiate the list with.
|
||||
*/
|
||||
function AudioTrackList() {
|
||||
var _this, _ret;
|
||||
|
||||
var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
||||
|
||||
_classCallCheck(this, AudioTrackList);
|
||||
|
||||
var list = void 0;
|
||||
|
||||
// make sure only 1 track is enabled
|
||||
// sorted from last index to first index
|
||||
for (var i = tracks.length - 1; i >= 0; i--) {
|
||||
if (tracks[i].enabled) {
|
||||
disableOthers(tracks, tracks[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// IE8 forces us to implement inheritance ourselves
|
||||
// as it does not support Object.defineProperty properly
|
||||
if (browser.IS_IE8) {
|
||||
list = _document2['default'].createElement('custom');
|
||||
for (var prop in _trackList2['default'].prototype) {
|
||||
if (prop !== 'constructor') {
|
||||
list[prop] = _trackList2['default'].prototype[prop];
|
||||
}
|
||||
}
|
||||
for (var _prop in AudioTrackList.prototype) {
|
||||
if (_prop !== 'constructor') {
|
||||
list[_prop] = AudioTrackList.prototype[_prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
|
||||
list.changing_ = false;
|
||||
|
||||
return _ret = list, _possibleConstructorReturn(_this, _ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an {@link AudioTrack} to the `AudioTrackList`.
|
||||
*
|
||||
* @param {AudioTrack} track
|
||||
* The AudioTrack to add to the list
|
||||
*
|
||||
* @fires Track#addtrack
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
AudioTrackList.prototype.addTrack_ = function addTrack_(track) {
|
||||
var _this2 = this;
|
||||
|
||||
if (track.enabled) {
|
||||
disableOthers(this, track);
|
||||
}
|
||||
|
||||
_TrackList.prototype.addTrack_.call(this, track);
|
||||
// native tracks don't have this
|
||||
if (!track.addEventListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @listens AudioTrack#enabledchange
|
||||
* @fires TrackList#change
|
||||
*/
|
||||
track.addEventListener('enabledchange', function () {
|
||||
// when we are disabling other tracks (since we don't support
|
||||
// more than one track at a time) we will set changing_
|
||||
// to true so that we don't trigger additional change events
|
||||
if (_this2.changing_) {
|
||||
return;
|
||||
}
|
||||
_this2.changing_ = true;
|
||||
disableOthers(_this2, track);
|
||||
_this2.changing_ = false;
|
||||
_this2.trigger('change');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Add an {@link AudioTrack} to the `AudioTrackList`.
|
||||
*
|
||||
* @param {AudioTrack} track
|
||||
* The AudioTrack to add to the list
|
||||
*
|
||||
* @fires Track#addtrack
|
||||
*/
|
||||
|
||||
|
||||
AudioTrackList.prototype.addTrack = function addTrack(track) {
|
||||
this.addTrack_(track);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove an {@link AudioTrack} from the `AudioTrackList`.
|
||||
*
|
||||
* @param {AudioTrack} track
|
||||
* The AudioTrack to remove from the list
|
||||
*
|
||||
* @fires Track#removetrack
|
||||
*/
|
||||
|
||||
|
||||
AudioTrackList.prototype.removeTrack = function removeTrack(track) {
|
||||
_TrackList.prototype.removeTrack_.call(this, track);
|
||||
};
|
||||
|
||||
return AudioTrackList;
|
||||
}(_trackList2['default']);
|
||||
|
||||
exports['default'] = AudioTrackList;
|
||||
@@ -0,0 +1,129 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _trackEnums = require('./track-enums');
|
||||
|
||||
var _track = require('./track');
|
||||
|
||||
var _track2 = _interopRequireDefault(_track);
|
||||
|
||||
var _mergeOptions = require('../utils/merge-options');
|
||||
|
||||
var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
|
||||
|
||||
var _browser = require('../utils/browser.js');
|
||||
|
||||
var browser = _interopRequireWildcard(_browser);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; }
|
||||
|
||||
/**
|
||||
* A representation of a single `AudioTrack`. If it is part of an {@link AudioTrackList}
|
||||
* only one `AudioTrack` in the list will be enabled at a time.
|
||||
*
|
||||
* @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack}
|
||||
* @extends Track
|
||||
*/
|
||||
var AudioTrack = function (_Track) {
|
||||
_inherits(AudioTrack, _Track);
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*
|
||||
* @param {Object} [options={}]
|
||||
* Object of option names and values
|
||||
*
|
||||
* @param {AudioTrack~Kind} [options.kind='']
|
||||
* A valid audio track kind
|
||||
*
|
||||
* @param {string} [options.id='vjs_track_' + Guid.newGUID()]
|
||||
* A unique id for this AudioTrack.
|
||||
*
|
||||
* @param {string} [options.label='']
|
||||
* The menu label for this track.
|
||||
*
|
||||
* @param {string} [options.language='']
|
||||
* A valid two character language code.
|
||||
*
|
||||
* @param {boolean} [options.enabled]
|
||||
* If this track is the one that is currently playing. If this track is part of
|
||||
* an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled.
|
||||
*/
|
||||
function AudioTrack() {
|
||||
var _this, _ret;
|
||||
|
||||
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
||||
|
||||
_classCallCheck(this, AudioTrack);
|
||||
|
||||
var settings = (0, _mergeOptions2['default'])(options, {
|
||||
kind: _trackEnums.AudioTrackKind[options.kind] || ''
|
||||
});
|
||||
// on IE8 this will be a document element
|
||||
// for every other browser this will be a normal object
|
||||
var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
|
||||
var enabled = false;
|
||||
|
||||
if (browser.IS_IE8) {
|
||||
for (var prop in AudioTrack.prototype) {
|
||||
if (prop !== 'constructor') {
|
||||
track[prop] = AudioTrack.prototype[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @member {boolean} enabled
|
||||
* If this `AudioTrack` is enabled or not. When setting this will
|
||||
* fire {@link AudioTrack#enabledchange} if the state of enabled is changed.
|
||||
*
|
||||
* @fires VideoTrack#selectedchange
|
||||
*/
|
||||
Object.defineProperty(track, 'enabled', {
|
||||
get: function get() {
|
||||
return enabled;
|
||||
},
|
||||
set: function set(newEnabled) {
|
||||
// an invalid or unchanged value
|
||||
if (typeof newEnabled !== 'boolean' || newEnabled === enabled) {
|
||||
return;
|
||||
}
|
||||
enabled = newEnabled;
|
||||
|
||||
/**
|
||||
* An event that fires when enabled changes on this track. This allows
|
||||
* the AudioTrackList that holds this track to act accordingly.
|
||||
*
|
||||
* > Note: This is not part of the spec! Native tracks will do
|
||||
* this internally without an event.
|
||||
*
|
||||
* @event AudioTrack#enabledchange
|
||||
* @type {EventTarget~Event}
|
||||
*/
|
||||
this.trigger('enabledchange');
|
||||
}
|
||||
});
|
||||
|
||||
// if the user sets this track to selected then
|
||||
// set selected to that true value otherwise
|
||||
// we keep it false
|
||||
if (settings.enabled) {
|
||||
track.enabled = settings.enabled;
|
||||
}
|
||||
track.loaded_ = true;
|
||||
|
||||
return _ret = track, _possibleConstructorReturn(_this, _ret);
|
||||
}
|
||||
|
||||
return AudioTrack;
|
||||
}(_track2['default']);
|
||||
|
||||
exports['default'] = AudioTrack;
|
||||
@@ -0,0 +1,148 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _browser = require('../utils/browser.js');
|
||||
|
||||
var browser = _interopRequireWildcard(_browser);
|
||||
|
||||
var _document = require('global/document');
|
||||
|
||||
var _document2 = _interopRequireDefault(_document);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
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; } }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
|
||||
* @file html-track-element-list.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* The current list of {@link HtmlTrackElement}s.
|
||||
*/
|
||||
var HtmlTrackElementList = function () {
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*
|
||||
* @param {HtmlTrackElement[]} [tracks=[]]
|
||||
* A list of `HtmlTrackElement` to instantiate the list with.
|
||||
*/
|
||||
function HtmlTrackElementList() {
|
||||
var trackElements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
||||
|
||||
_classCallCheck(this, HtmlTrackElementList);
|
||||
|
||||
var list = this; // eslint-disable-line
|
||||
|
||||
if (browser.IS_IE8) {
|
||||
list = _document2['default'].createElement('custom');
|
||||
|
||||
for (var prop in HtmlTrackElementList.prototype) {
|
||||
if (prop !== 'constructor') {
|
||||
list[prop] = HtmlTrackElementList.prototype[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list.trackElements_ = [];
|
||||
|
||||
/**
|
||||
* @member {number} length
|
||||
* The current number of `Track`s in the this Trackist.
|
||||
*/
|
||||
Object.defineProperty(list, 'length', {
|
||||
get: function get() {
|
||||
return this.trackElements_.length;
|
||||
}
|
||||
});
|
||||
|
||||
for (var i = 0, length = trackElements.length; i < length; i++) {
|
||||
list.addTrackElement_(trackElements[i]);
|
||||
}
|
||||
|
||||
if (browser.IS_IE8) {
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an {@link HtmlTrackElement} to the `HtmlTrackElementList`
|
||||
*
|
||||
* @param {HtmlTrackElement} trackElement
|
||||
* The track element to add to the list.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) {
|
||||
var index = this.trackElements_.length;
|
||||
|
||||
if (!('' + index in this)) {
|
||||
Object.defineProperty(this, index, {
|
||||
get: function get() {
|
||||
return this.trackElements_[index];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Do not add duplicate elements
|
||||
if (this.trackElements_.indexOf(trackElement) === -1) {
|
||||
this.trackElements_.push(trackElement);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an
|
||||
* {@link TextTrack}.
|
||||
*
|
||||
* @param {TextTrack} track
|
||||
* The track associated with a track element.
|
||||
*
|
||||
* @return {HtmlTrackElement|undefined}
|
||||
* The track element that was found or undefined.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) {
|
||||
var trackElement_ = void 0;
|
||||
|
||||
for (var i = 0, length = this.trackElements_.length; i < length; i++) {
|
||||
if (track === this.trackElements_[i].track) {
|
||||
trackElement_ = this.trackElements_[i];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return trackElement_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList`
|
||||
*
|
||||
* @param {HtmlTrackElement} trackElement
|
||||
* The track element to remove from the list.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) {
|
||||
for (var i = 0, length = this.trackElements_.length; i < length; i++) {
|
||||
if (trackElement === this.trackElements_[i]) {
|
||||
this.trackElements_.splice(i, 1);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return HtmlTrackElementList;
|
||||
}();
|
||||
|
||||
exports['default'] = HtmlTrackElementList;
|
||||
@@ -0,0 +1,169 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _browser = require('../utils/browser.js');
|
||||
|
||||
var browser = _interopRequireWildcard(_browser);
|
||||
|
||||
var _document = require('global/document');
|
||||
|
||||
var _document2 = _interopRequireDefault(_document);
|
||||
|
||||
var _eventTarget = require('../event-target');
|
||||
|
||||
var _eventTarget2 = _interopRequireDefault(_eventTarget);
|
||||
|
||||
var _textTrack = require('../tracks/text-track');
|
||||
|
||||
var _textTrack2 = _interopRequireDefault(_textTrack);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
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; } }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file html-track-element.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {HTMLTrackElement~ReadyState}
|
||||
* @enum {number}
|
||||
*/
|
||||
var NONE = 0;
|
||||
var LOADING = 1;
|
||||
var LOADED = 2;
|
||||
var ERROR = 3;
|
||||
|
||||
/**
|
||||
* A single track represented in the DOM.
|
||||
*
|
||||
* @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement}
|
||||
* @extends EventTarget
|
||||
*/
|
||||
|
||||
var HTMLTrackElement = function (_EventTarget) {
|
||||
_inherits(HTMLTrackElement, _EventTarget);
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*
|
||||
* @param {Object} options={}
|
||||
* Object of option names and values
|
||||
*
|
||||
* @param {Tech} options.tech
|
||||
* A reference to the tech that owns this HTMLTrackElement.
|
||||
*
|
||||
* @param {TextTrack~Kind} [options.kind='subtitles']
|
||||
* A valid text track kind.
|
||||
*
|
||||
* @param {TextTrack~Mode} [options.mode='disabled']
|
||||
* A valid text track mode.
|
||||
*
|
||||
* @param {string} [options.id='vjs_track_' + Guid.newGUID()]
|
||||
* A unique id for this TextTrack.
|
||||
*
|
||||
* @param {string} [options.label='']
|
||||
* The menu label for this track.
|
||||
*
|
||||
* @param {string} [options.language='']
|
||||
* A valid two character language code.
|
||||
*
|
||||
* @param {string} [options.srclang='']
|
||||
* A valid two character language code. An alternative, but deprioritized
|
||||
* vesion of `options.language`
|
||||
*
|
||||
* @param {string} [options.src]
|
||||
* A url to TextTrack cues.
|
||||
*
|
||||
* @param {boolean} [options.default]
|
||||
* If this track should default to on or off.
|
||||
*/
|
||||
function HTMLTrackElement() {
|
||||
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
||||
|
||||
_classCallCheck(this, HTMLTrackElement);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
|
||||
|
||||
var readyState = void 0;
|
||||
var trackElement = _this; // eslint-disable-line
|
||||
|
||||
if (browser.IS_IE8) {
|
||||
trackElement = _document2['default'].createElement('custom');
|
||||
|
||||
for (var prop in HTMLTrackElement.prototype) {
|
||||
if (prop !== 'constructor') {
|
||||
trackElement[prop] = HTMLTrackElement.prototype[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var track = new _textTrack2['default'](options);
|
||||
|
||||
trackElement.kind = track.kind;
|
||||
trackElement.src = track.src;
|
||||
trackElement.srclang = track.language;
|
||||
trackElement.label = track.label;
|
||||
trackElement['default'] = track['default'];
|
||||
|
||||
/**
|
||||
* @member {HTMLTrackElement~ReadyState} readyState
|
||||
* The current ready state of the track element.
|
||||
*/
|
||||
Object.defineProperty(trackElement, 'readyState', {
|
||||
get: function get() {
|
||||
return readyState;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @member {TextTrack} track
|
||||
* The underlying TextTrack object.
|
||||
*/
|
||||
Object.defineProperty(trackElement, 'track', {
|
||||
get: function get() {
|
||||
return track;
|
||||
}
|
||||
});
|
||||
|
||||
readyState = NONE;
|
||||
|
||||
/**
|
||||
* @listens TextTrack#loadeddata
|
||||
* @fires HTMLTrackElement#load
|
||||
*/
|
||||
track.addEventListener('loadeddata', function () {
|
||||
readyState = LOADED;
|
||||
|
||||
trackElement.trigger({
|
||||
type: 'load',
|
||||
target: trackElement
|
||||
});
|
||||
});
|
||||
|
||||
if (browser.IS_IE8) {
|
||||
var _ret;
|
||||
|
||||
return _ret = trackElement, _possibleConstructorReturn(_this, _ret);
|
||||
}
|
||||
return _this;
|
||||
}
|
||||
|
||||
return HTMLTrackElement;
|
||||
}(_eventTarget2['default']);
|
||||
|
||||
HTMLTrackElement.prototype.allowedEvents_ = {
|
||||
load: 'load'
|
||||
};
|
||||
|
||||
HTMLTrackElement.NONE = NONE;
|
||||
HTMLTrackElement.LOADING = LOADING;
|
||||
HTMLTrackElement.LOADED = LOADED;
|
||||
HTMLTrackElement.ERROR = ERROR;
|
||||
|
||||
exports['default'] = HTMLTrackElement;
|
||||
@@ -0,0 +1,152 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _browser = require('../utils/browser.js');
|
||||
|
||||
var browser = _interopRequireWildcard(_browser);
|
||||
|
||||
var _document = require('global/document');
|
||||
|
||||
var _document2 = _interopRequireDefault(_document);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
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; } }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
|
||||
* @file text-track-cue-list.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} TextTrackCue
|
||||
*
|
||||
* @property {string} id
|
||||
* The unique id for this text track cue
|
||||
*
|
||||
* @property {number} startTime
|
||||
* The start time for this text track cue
|
||||
*
|
||||
* @property {number} endTime
|
||||
* The end time for this text track cue
|
||||
*
|
||||
* @property {boolean} pauseOnExit
|
||||
* Pause when the end time is reached if true.
|
||||
*
|
||||
* @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcue}
|
||||
*/
|
||||
|
||||
/**
|
||||
* A List of TextTrackCues.
|
||||
*
|
||||
* @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist}
|
||||
*/
|
||||
var TextTrackCueList = function () {
|
||||
|
||||
/**
|
||||
* Create an instance of this class..
|
||||
*
|
||||
* @param {Array} cues
|
||||
* A list of cues to be initialized with
|
||||
*/
|
||||
function TextTrackCueList(cues) {
|
||||
_classCallCheck(this, TextTrackCueList);
|
||||
|
||||
var list = this; // eslint-disable-line
|
||||
|
||||
if (browser.IS_IE8) {
|
||||
list = _document2['default'].createElement('custom');
|
||||
|
||||
for (var prop in TextTrackCueList.prototype) {
|
||||
if (prop !== 'constructor') {
|
||||
list[prop] = TextTrackCueList.prototype[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextTrackCueList.prototype.setCues_.call(list, cues);
|
||||
|
||||
/**
|
||||
* @member {number} length
|
||||
* The current number of `TextTrackCue`s in the TextTrackCueList.
|
||||
*/
|
||||
Object.defineProperty(list, 'length', {
|
||||
get: function get() {
|
||||
return this.length_;
|
||||
}
|
||||
});
|
||||
|
||||
if (browser.IS_IE8) {
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A setter for cues in this list. Creates getters
|
||||
* an an index for the cues.
|
||||
*
|
||||
* @param {Array} cues
|
||||
* An array of cues to set
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
TextTrackCueList.prototype.setCues_ = function setCues_(cues) {
|
||||
var oldLength = this.length || 0;
|
||||
var i = 0;
|
||||
var l = cues.length;
|
||||
|
||||
this.cues_ = cues;
|
||||
this.length_ = cues.length;
|
||||
|
||||
var defineProp = function defineProp(index) {
|
||||
if (!('' + index in this)) {
|
||||
Object.defineProperty(this, '' + index, {
|
||||
get: function get() {
|
||||
return this.cues_[index];
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (oldLength < l) {
|
||||
i = oldLength;
|
||||
|
||||
for (; i < l; i++) {
|
||||
defineProp.call(this, i);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id.
|
||||
*
|
||||
* @param {string} id
|
||||
* The id of the cue that should be searched for.
|
||||
*
|
||||
* @return {TextTrackCue|null}
|
||||
* A single cue or null if none was found.
|
||||
*/
|
||||
|
||||
|
||||
TextTrackCueList.prototype.getCueById = function getCueById(id) {
|
||||
var result = null;
|
||||
|
||||
for (var i = 0, l = this.length; i < l; i++) {
|
||||
var cue = this[i];
|
||||
|
||||
if (cue.id === id) {
|
||||
result = cue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
return TextTrackCueList;
|
||||
}();
|
||||
|
||||
exports['default'] = TextTrackCueList;
|
||||
@@ -0,0 +1,350 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _component = require('../component');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _fn = require('../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _window = require('global/window');
|
||||
|
||||
var _window2 = _interopRequireDefault(_window);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file text-track-display.js
|
||||
*/
|
||||
|
||||
|
||||
var darkGray = '#222';
|
||||
var lightGray = '#ccc';
|
||||
var fontMap = {
|
||||
monospace: 'monospace',
|
||||
sansSerif: 'sans-serif',
|
||||
serif: 'serif',
|
||||
monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace',
|
||||
monospaceSerif: '"Courier New", monospace',
|
||||
proportionalSansSerif: 'sans-serif',
|
||||
proportionalSerif: 'serif',
|
||||
casual: '"Comic Sans MS", Impact, fantasy',
|
||||
script: '"Monotype Corsiva", cursive',
|
||||
smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif'
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct an rgba color from a given hex color code.
|
||||
*
|
||||
* @param {number} color
|
||||
* Hex number for color, like #f0e.
|
||||
*
|
||||
* @param {number} opacity
|
||||
* Value for opacity, 0.0 - 1.0.
|
||||
*
|
||||
* @return {string}
|
||||
* The rgba color that was created, like 'rgba(255, 0, 0, 0.3)'.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function constructColor(color, opacity) {
|
||||
return 'rgba(' +
|
||||
// color looks like "#f0e"
|
||||
parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to update the style of a DOM element. Some style changes will throw an error,
|
||||
* particularly in IE8. Those should be noops.
|
||||
*
|
||||
* @param {Element} el
|
||||
* The DOM element to be styled.
|
||||
*
|
||||
* @param {string} style
|
||||
* The CSS property on the element that should be styled.
|
||||
*
|
||||
* @param {string} rule
|
||||
* The style rule that should be applied to the property.
|
||||
*/
|
||||
function tryUpdateStyle(el, style, rule) {
|
||||
try {
|
||||
el.style[style] = rule;
|
||||
} catch (e) {
|
||||
|
||||
// Satisfies linter.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The component for displaying text track cues.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
|
||||
var TextTrackDisplay = function (_Component) {
|
||||
_inherits(TextTrackDisplay, _Component);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*
|
||||
* @param {Component~ReadyCallback} [ready]
|
||||
* The function to call when `TextTrackDisplay` is ready.
|
||||
*/
|
||||
function TextTrackDisplay(player, options, ready) {
|
||||
_classCallCheck(this, TextTrackDisplay);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready));
|
||||
|
||||
player.on('loadstart', Fn.bind(_this, _this.toggleDisplay));
|
||||
player.on('texttrackchange', Fn.bind(_this, _this.updateDisplay));
|
||||
|
||||
// This used to be called during player init, but was causing an error
|
||||
// if a track should show by default and the display hadn't loaded yet.
|
||||
// Should probably be moved to an external track loader when we support
|
||||
// tracks that don't need a display.
|
||||
player.ready(Fn.bind(_this, function () {
|
||||
if (player.tech_ && player.tech_.featuresNativeTextTracks) {
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
player.on('fullscreenchange', Fn.bind(this, this.updateDisplay));
|
||||
|
||||
var tracks = this.options_.playerOptions.tracks || [];
|
||||
|
||||
for (var i = 0; i < tracks.length; i++) {
|
||||
this.player_.addRemoteTextTrack(tracks[i], true);
|
||||
}
|
||||
|
||||
var modes = { captions: 1, subtitles: 1 };
|
||||
var trackList = this.player_.textTracks();
|
||||
var firstDesc = void 0;
|
||||
var firstCaptions = void 0;
|
||||
|
||||
if (trackList) {
|
||||
for (var _i = 0; _i < trackList.length; _i++) {
|
||||
var track = trackList[_i];
|
||||
|
||||
if (track['default']) {
|
||||
if (track.kind === 'descriptions' && !firstDesc) {
|
||||
firstDesc = track;
|
||||
} else if (track.kind in modes && !firstCaptions) {
|
||||
firstCaptions = track;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We want to show the first default track but captions and subtitles
|
||||
// take precedence over descriptions.
|
||||
// So, display the first default captions or subtitles track
|
||||
// and otherwise the first default descriptions track.
|
||||
if (firstCaptions) {
|
||||
firstCaptions.mode = 'showing';
|
||||
} else if (firstDesc) {
|
||||
firstDesc.mode = 'showing';
|
||||
}
|
||||
}
|
||||
}));
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn display of {@link TextTrack}'s from the current state into the other state.
|
||||
* There are only two states:
|
||||
* - 'shown'
|
||||
* - 'hidden'
|
||||
*
|
||||
* @listens Player#loadstart
|
||||
*/
|
||||
|
||||
|
||||
TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() {
|
||||
if (this.player_.tech_ && this.player_.tech_.featuresNativeTextTracks) {
|
||||
this.hide();
|
||||
} else {
|
||||
this.show();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the {@link Component}'s DOM element.
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
TextTrackDisplay.prototype.createEl = function createEl() {
|
||||
return _Component.prototype.createEl.call(this, 'div', {
|
||||
className: 'vjs-text-track-display'
|
||||
}, {
|
||||
'aria-live': 'off',
|
||||
'aria-atomic': 'true'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear all displayed {@link TextTrack}s.
|
||||
*/
|
||||
|
||||
|
||||
TextTrackDisplay.prototype.clearDisplay = function clearDisplay() {
|
||||
if (typeof _window2['default'].WebVTT === 'function') {
|
||||
_window2['default'].WebVTT.processCues(_window2['default'], [], this.el_);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the displayed TextTrack when a either a {@link Player#texttrackchange} or
|
||||
* a {@link Player#fullscreenchange} is fired.
|
||||
*
|
||||
* @listens Player#texttrackchange
|
||||
* @listens Player#fullscreenchange
|
||||
*/
|
||||
|
||||
|
||||
TextTrackDisplay.prototype.updateDisplay = function updateDisplay() {
|
||||
var tracks = this.player_.textTracks();
|
||||
|
||||
this.clearDisplay();
|
||||
|
||||
if (!tracks) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Track display prioritization model: if multiple tracks are 'showing',
|
||||
// display the first 'subtitles' or 'captions' track which is 'showing',
|
||||
// otherwise display the first 'descriptions' track which is 'showing'
|
||||
|
||||
var descriptionsTrack = null;
|
||||
var captionsSubtitlesTrack = null;
|
||||
|
||||
var i = tracks.length;
|
||||
|
||||
while (i--) {
|
||||
var track = tracks[i];
|
||||
|
||||
if (track.mode === 'showing') {
|
||||
if (track.kind === 'descriptions') {
|
||||
descriptionsTrack = track;
|
||||
} else {
|
||||
captionsSubtitlesTrack = track;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (captionsSubtitlesTrack) {
|
||||
if (this.getAttribute('aria-live') !== 'off') {
|
||||
this.setAttribute('aria-live', 'off');
|
||||
}
|
||||
this.updateForTrack(captionsSubtitlesTrack);
|
||||
} else if (descriptionsTrack) {
|
||||
if (this.getAttribute('aria-live') !== 'assertive') {
|
||||
this.setAttribute('aria-live', 'assertive');
|
||||
}
|
||||
this.updateForTrack(descriptionsTrack);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Add an {@link Texttrack} to to the {@link Tech}s {@link TextTrackList}.
|
||||
*
|
||||
* @param {TextTrack} track
|
||||
* Text track object to be added to the list.
|
||||
*/
|
||||
|
||||
|
||||
TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) {
|
||||
if (typeof _window2['default'].WebVTT !== 'function' || !track.activeCues) {
|
||||
return;
|
||||
}
|
||||
|
||||
var overrides = this.player_.textTrackSettings.getValues();
|
||||
var cues = [];
|
||||
|
||||
for (var _i2 = 0; _i2 < track.activeCues.length; _i2++) {
|
||||
cues.push(track.activeCues[_i2]);
|
||||
}
|
||||
|
||||
_window2['default'].WebVTT.processCues(_window2['default'], cues, this.el_);
|
||||
|
||||
var i = cues.length;
|
||||
|
||||
while (i--) {
|
||||
var cue = cues[i];
|
||||
|
||||
if (!cue) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var cueDiv = cue.displayState;
|
||||
|
||||
if (overrides.color) {
|
||||
cueDiv.firstChild.style.color = overrides.color;
|
||||
}
|
||||
if (overrides.textOpacity) {
|
||||
tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity));
|
||||
}
|
||||
if (overrides.backgroundColor) {
|
||||
cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor;
|
||||
}
|
||||
if (overrides.backgroundOpacity) {
|
||||
tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity));
|
||||
}
|
||||
if (overrides.windowColor) {
|
||||
if (overrides.windowOpacity) {
|
||||
tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity));
|
||||
} else {
|
||||
cueDiv.style.backgroundColor = overrides.windowColor;
|
||||
}
|
||||
}
|
||||
if (overrides.edgeStyle) {
|
||||
if (overrides.edgeStyle === 'dropshadow') {
|
||||
cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray;
|
||||
} else if (overrides.edgeStyle === 'raised') {
|
||||
cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray;
|
||||
} else if (overrides.edgeStyle === 'depressed') {
|
||||
cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray;
|
||||
} else if (overrides.edgeStyle === 'uniform') {
|
||||
cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray;
|
||||
}
|
||||
}
|
||||
if (overrides.fontPercent && overrides.fontPercent !== 1) {
|
||||
var fontSize = _window2['default'].parseFloat(cueDiv.style.fontSize);
|
||||
|
||||
cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px';
|
||||
cueDiv.style.height = 'auto';
|
||||
cueDiv.style.top = 'auto';
|
||||
cueDiv.style.bottom = '2px';
|
||||
}
|
||||
if (overrides.fontFamily && overrides.fontFamily !== 'default') {
|
||||
if (overrides.fontFamily === 'small-caps') {
|
||||
cueDiv.firstChild.style.fontVariant = 'small-caps';
|
||||
} else {
|
||||
cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return TextTrackDisplay;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay);
|
||||
exports['default'] = TextTrackDisplay;
|
||||
@@ -0,0 +1,102 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
/**
|
||||
* @file text-track-list-converter.js Utilities for capturing text track state and
|
||||
* re-creating tracks based on a capture.
|
||||
*
|
||||
* @module text-track-list-converter
|
||||
*/
|
||||
|
||||
/**
|
||||
* Examine a single {@link TextTrack} and return a JSON-compatible javascript object that
|
||||
* represents the {@link TextTrack}'s state.
|
||||
*
|
||||
* @param {TextTrack} track
|
||||
* The text track to query.
|
||||
*
|
||||
* @return {Object}
|
||||
* A serializable javascript representation of the TextTrack.
|
||||
* @private
|
||||
*/
|
||||
var trackToJson_ = function trackToJson_(track) {
|
||||
var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) {
|
||||
|
||||
if (track[prop]) {
|
||||
acc[prop] = track[prop];
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {
|
||||
cues: track.cues && Array.prototype.map.call(track.cues, function (cue) {
|
||||
return {
|
||||
startTime: cue.startTime,
|
||||
endTime: cue.endTime,
|
||||
text: cue.text,
|
||||
id: cue.id
|
||||
};
|
||||
})
|
||||
});
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Examine a {@link Tech} and return a JSON-compatible javascript array that represents the
|
||||
* state of all {@link TextTrack}s currently configured. The return array is compatible with
|
||||
* {@link text-track-list-converter:jsonToTextTracks}.
|
||||
*
|
||||
* @param {Tech} tech
|
||||
* The tech object to query
|
||||
*
|
||||
* @return {Array}
|
||||
* A serializable javascript representation of the {@link Tech}s
|
||||
* {@link TextTrackList}.
|
||||
*/
|
||||
var textTracksToJson = function textTracksToJson(tech) {
|
||||
|
||||
var trackEls = tech.$$('track');
|
||||
|
||||
var trackObjs = Array.prototype.map.call(trackEls, function (t) {
|
||||
return t.track;
|
||||
});
|
||||
var tracks = Array.prototype.map.call(trackEls, function (trackEl) {
|
||||
var json = trackToJson_(trackEl.track);
|
||||
|
||||
if (trackEl.src) {
|
||||
json.src = trackEl.src;
|
||||
}
|
||||
return json;
|
||||
});
|
||||
|
||||
return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) {
|
||||
return trackObjs.indexOf(track) === -1;
|
||||
}).map(trackToJson_));
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript
|
||||
* object {@link TextTrack} representations.
|
||||
*
|
||||
* @param {Array} json
|
||||
* An array of `TextTrack` representation objects, like those that would be
|
||||
* produced by `textTracksToJson`.
|
||||
*
|
||||
* @param {Tech} tech
|
||||
* The `Tech` to create the `TextTrack`s on.
|
||||
*/
|
||||
var jsonToTextTracks = function jsonToTextTracks(json, tech) {
|
||||
json.forEach(function (track) {
|
||||
var addedTrack = tech.addRemoteTextTrack(track).track;
|
||||
|
||||
if (!track.src && track.cues) {
|
||||
track.cues.forEach(function (cue) {
|
||||
return addedTrack.addCue(cue);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return tech.textTracks();
|
||||
};
|
||||
|
||||
exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ };
|
||||
@@ -0,0 +1,104 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _trackList = require('./track-list');
|
||||
|
||||
var _trackList2 = _interopRequireDefault(_trackList);
|
||||
|
||||
var _fn = require('../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _browser = require('../utils/browser.js');
|
||||
|
||||
var browser = _interopRequireWildcard(_browser);
|
||||
|
||||
var _document = require('global/document');
|
||||
|
||||
var _document2 = _interopRequireDefault(_document);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file text-track-list.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The current list of {@link TextTrack} for a media file.
|
||||
*
|
||||
* @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist}
|
||||
* @extends TrackList
|
||||
*/
|
||||
var TextTrackList = function (_TrackList) {
|
||||
_inherits(TextTrackList, _TrackList);
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*
|
||||
* @param {TextTrack[]} [tracks=[]]
|
||||
* A list of `TextTrack` to instantiate the list with.
|
||||
*/
|
||||
function TextTrackList() {
|
||||
var _this, _ret;
|
||||
|
||||
var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
||||
|
||||
_classCallCheck(this, TextTrackList);
|
||||
|
||||
var list = void 0;
|
||||
|
||||
// IE8 forces us to implement inheritance ourselves
|
||||
// as it does not support Object.defineProperty properly
|
||||
if (browser.IS_IE8) {
|
||||
list = _document2['default'].createElement('custom');
|
||||
for (var prop in _trackList2['default'].prototype) {
|
||||
if (prop !== 'constructor') {
|
||||
list[prop] = _trackList2['default'].prototype[prop];
|
||||
}
|
||||
}
|
||||
for (var _prop in TextTrackList.prototype) {
|
||||
if (_prop !== 'constructor') {
|
||||
list[_prop] = TextTrackList.prototype[_prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
|
||||
return _ret = list, _possibleConstructorReturn(_this, _ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link TextTrack} to the `TextTrackList`
|
||||
*
|
||||
* @param {TextTrack} track
|
||||
* The text track to add to the list.
|
||||
*
|
||||
* @fires TrackList#addtrack
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
TextTrackList.prototype.addTrack_ = function addTrack_(track) {
|
||||
_TrackList.prototype.addTrack_.call(this, track);
|
||||
|
||||
/**
|
||||
* @listens TextTrack#modechange
|
||||
* @fires TrackList#change
|
||||
*/
|
||||
track.addEventListener('modechange', Fn.bind(this, function () {
|
||||
this.trigger('change');
|
||||
}));
|
||||
};
|
||||
|
||||
return TextTrackList;
|
||||
}(_trackList2['default']);
|
||||
|
||||
exports['default'] = TextTrackList;
|
||||
@@ -0,0 +1,601 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _window = require('global/window');
|
||||
|
||||
var _window2 = _interopRequireDefault(_window);
|
||||
|
||||
var _component = require('../component');
|
||||
|
||||
var _component2 = _interopRequireDefault(_component);
|
||||
|
||||
var _dom = require('../utils/dom');
|
||||
|
||||
var _fn = require('../utils/fn');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _obj = require('../utils/obj');
|
||||
|
||||
var Obj = _interopRequireWildcard(_obj);
|
||||
|
||||
var _log = require('../utils/log');
|
||||
|
||||
var _log2 = _interopRequireDefault(_log);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file text-track-settings.js
|
||||
*/
|
||||
|
||||
|
||||
var LOCAL_STORAGE_KEY = 'vjs-text-track-settings';
|
||||
|
||||
var COLOR_BLACK = ['#000', 'Black'];
|
||||
var COLOR_BLUE = ['#00F', 'Blue'];
|
||||
var COLOR_CYAN = ['#0FF', 'Cyan'];
|
||||
var COLOR_GREEN = ['#0F0', 'Green'];
|
||||
var COLOR_MAGENTA = ['#F0F', 'Magenta'];
|
||||
var COLOR_RED = ['#F00', 'Red'];
|
||||
var COLOR_WHITE = ['#FFF', 'White'];
|
||||
var COLOR_YELLOW = ['#FF0', 'Yellow'];
|
||||
|
||||
var OPACITY_OPAQUE = ['1', 'Opaque'];
|
||||
var OPACITY_SEMI = ['0.5', 'Semi-Transparent'];
|
||||
var OPACITY_TRANS = ['0', 'Transparent'];
|
||||
|
||||
// Configuration for the various <select> elements in the DOM of this component.
|
||||
//
|
||||
// Possible keys include:
|
||||
//
|
||||
// `default`:
|
||||
// The default option index. Only needs to be provided if not zero.
|
||||
// `parser`:
|
||||
// A function which is used to parse the value from the selected option in
|
||||
// a customized way.
|
||||
// `selector`:
|
||||
// The selector used to find the associated <select> element.
|
||||
var selectConfigs = {
|
||||
backgroundColor: {
|
||||
selector: '.vjs-bg-color > select',
|
||||
id: 'captions-background-color-%s',
|
||||
label: 'Color',
|
||||
options: [COLOR_BLACK, COLOR_WHITE, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
|
||||
},
|
||||
|
||||
backgroundOpacity: {
|
||||
selector: '.vjs-bg-opacity > select',
|
||||
id: 'captions-background-opacity-%s',
|
||||
label: 'Transparency',
|
||||
options: [OPACITY_OPAQUE, OPACITY_SEMI, OPACITY_TRANS]
|
||||
},
|
||||
|
||||
color: {
|
||||
selector: '.vjs-fg-color > select',
|
||||
id: 'captions-foreground-color-%s',
|
||||
label: 'Color',
|
||||
options: [COLOR_WHITE, COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
|
||||
},
|
||||
|
||||
edgeStyle: {
|
||||
selector: '.vjs-edge-style > select',
|
||||
id: '%s',
|
||||
label: 'Text Edge Style',
|
||||
options: [['none', 'None'], ['raised', 'Raised'], ['depressed', 'Depressed'], ['uniform', 'Uniform'], ['dropshadow', 'Dropshadow']]
|
||||
},
|
||||
|
||||
fontFamily: {
|
||||
selector: '.vjs-font-family > select',
|
||||
id: 'captions-font-family-%s',
|
||||
label: 'Font Family',
|
||||
options: [['proportionalSansSerif', 'Proportional Sans-Serif'], ['monospaceSansSerif', 'Monospace Sans-Serif'], ['proportionalSerif', 'Proportional Serif'], ['monospaceSerif', 'Monospace Serif'], ['casual', 'Casual'], ['script', 'Script'], ['small-caps', 'Small Caps']]
|
||||
},
|
||||
|
||||
fontPercent: {
|
||||
selector: '.vjs-font-percent > select',
|
||||
id: 'captions-font-size-%s',
|
||||
label: 'Font Size',
|
||||
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%']],
|
||||
'default': 2,
|
||||
parser: function parser(v) {
|
||||
return v === '1.00' ? null : Number(v);
|
||||
}
|
||||
},
|
||||
|
||||
textOpacity: {
|
||||
selector: '.vjs-text-opacity > select',
|
||||
id: 'captions-foreground-opacity-%s',
|
||||
label: 'Transparency',
|
||||
options: [OPACITY_OPAQUE, OPACITY_SEMI]
|
||||
},
|
||||
|
||||
// Options for this object are defined below.
|
||||
windowColor: {
|
||||
selector: '.vjs-window-color > select',
|
||||
id: 'captions-window-color-%s',
|
||||
label: 'Color'
|
||||
},
|
||||
|
||||
// Options for this object are defined below.
|
||||
windowOpacity: {
|
||||
selector: '.vjs-window-opacity > select',
|
||||
id: 'captions-window-opacity-%s',
|
||||
label: 'Transparency',
|
||||
options: [OPACITY_TRANS, OPACITY_SEMI, OPACITY_OPAQUE]
|
||||
}
|
||||
};
|
||||
|
||||
selectConfigs.windowColor.options = selectConfigs.backgroundColor.options;
|
||||
|
||||
/**
|
||||
* Get the actual value of an option.
|
||||
*
|
||||
* @param {string} value
|
||||
* The value to get
|
||||
*
|
||||
* @param {Function} [parser]
|
||||
* Optional function to adjust the value.
|
||||
*
|
||||
* @return {Mixed}
|
||||
* - Will be `undefined` if no value exists
|
||||
* - Will be `undefined` if the given value is "none".
|
||||
* - Will be the actual value otherwise.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function parseOptionValue(value, parser) {
|
||||
if (parser) {
|
||||
value = parser(value);
|
||||
}
|
||||
|
||||
if (value && value !== 'none') {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the selected <option> element within a <select> element.
|
||||
*
|
||||
* @param {Element} el
|
||||
* the element to look in
|
||||
*
|
||||
* @param {Function} [parser]
|
||||
* Optional function to adjust the value.
|
||||
*
|
||||
* @return {Mixed}
|
||||
* - Will be `undefined` if no value exists
|
||||
* - Will be `undefined` if the given value is "none".
|
||||
* - Will be the actual value otherwise.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function getSelectedOptionValue(el, parser) {
|
||||
var value = el.options[el.options.selectedIndex].value;
|
||||
|
||||
return parseOptionValue(value, parser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected <option> element within a <select> element based on a
|
||||
* given value.
|
||||
*
|
||||
* @param {Element} el
|
||||
* The element to look in.
|
||||
*
|
||||
* @param {string} value
|
||||
* the property to look on.
|
||||
*
|
||||
* @param {Function} [parser]
|
||||
* Optional function to adjust the value before comparing.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function setSelectedOption(el, value, parser) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < el.options.length; i++) {
|
||||
if (parseOptionValue(el.options[i].value, parser) === value) {
|
||||
el.selectedIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manipulate Text Tracks settings.
|
||||
*
|
||||
* @extends Component
|
||||
*/
|
||||
|
||||
var TextTrackSettings = function (_Component) {
|
||||
_inherits(TextTrackSettings, _Component);
|
||||
|
||||
/**
|
||||
* Creates an instance of this class.
|
||||
*
|
||||
* @param {Player} player
|
||||
* The `Player` that this class should be attached to.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* The key/value store of player options.
|
||||
*/
|
||||
function TextTrackSettings(player, options) {
|
||||
_classCallCheck(this, TextTrackSettings);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
|
||||
|
||||
_this.setDefaults();
|
||||
_this.hide();
|
||||
|
||||
_this.updateDisplay = Fn.bind(_this, _this.updateDisplay);
|
||||
|
||||
// Grab `persistTextTrackSettings` from the player options if not passed in child options
|
||||
if (options.persistTextTrackSettings === undefined) {
|
||||
_this.options_.persistTextTrackSettings = _this.options_.playerOptions.persistTextTrackSettings;
|
||||
}
|
||||
|
||||
_this.on(_this.$('.vjs-done-button'), 'click', function () {
|
||||
_this.saveSettings();
|
||||
_this.hide();
|
||||
});
|
||||
|
||||
_this.on(_this.$('.vjs-default-button'), 'click', function () {
|
||||
_this.setDefaults();
|
||||
_this.updateDisplay();
|
||||
});
|
||||
|
||||
Obj.each(selectConfigs, function (config) {
|
||||
_this.on(_this.$(config.selector), 'change', _this.updateDisplay);
|
||||
});
|
||||
|
||||
if (_this.options_.persistTextTrackSettings) {
|
||||
_this.restoreSettings();
|
||||
}
|
||||
return _this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a <select> element with configured options.
|
||||
*
|
||||
* @param {string} key
|
||||
* Configuration key to use during creation.
|
||||
*
|
||||
* @return {Element}
|
||||
* The DOM element that gets created.
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
TextTrackSettings.prototype.createElSelect_ = function createElSelect_(key) {
|
||||
var _this2 = this;
|
||||
|
||||
var config = selectConfigs[key];
|
||||
var id = config.id.replace('%s', this.id_);
|
||||
|
||||
return [(0, _dom.createEl)('label', {
|
||||
className: 'vjs-label',
|
||||
textContent: config.label
|
||||
}, {
|
||||
'for': id
|
||||
}), (0, _dom.createEl)('select', { id: id }, undefined, config.options.map(function (o) {
|
||||
return (0, _dom.createEl)('option', {
|
||||
textContent: _this2.localize(o[1]),
|
||||
value: o[0]
|
||||
});
|
||||
}))];
|
||||
};
|
||||
|
||||
/**
|
||||
* Create foreground color element for the component
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
TextTrackSettings.prototype.createElFgColor_ = function createElFgColor_() {
|
||||
var legend = (0, _dom.createEl)('legend', {
|
||||
textContent: this.localize('Text')
|
||||
});
|
||||
|
||||
var select = this.createElSelect_('color');
|
||||
|
||||
var opacity = (0, _dom.createEl)('span', {
|
||||
className: 'vjs-text-opacity vjs-opacity'
|
||||
}, undefined, this.createElSelect_('textOpacity'));
|
||||
|
||||
return (0, _dom.createEl)('fieldset', {
|
||||
className: 'vjs-fg-color vjs-tracksetting'
|
||||
}, undefined, [legend].concat(select, opacity));
|
||||
};
|
||||
|
||||
/**
|
||||
* Create background color element for the component
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
TextTrackSettings.prototype.createElBgColor_ = function createElBgColor_() {
|
||||
var legend = (0, _dom.createEl)('legend', {
|
||||
textContent: this.localize('Background')
|
||||
});
|
||||
|
||||
var select = this.createElSelect_('backgroundColor');
|
||||
|
||||
var opacity = (0, _dom.createEl)('span', {
|
||||
className: 'vjs-bg-opacity vjs-opacity'
|
||||
}, undefined, this.createElSelect_('backgroundOpacity'));
|
||||
|
||||
return (0, _dom.createEl)('fieldset', {
|
||||
className: 'vjs-bg-color vjs-tracksetting'
|
||||
}, undefined, [legend].concat(select, opacity));
|
||||
};
|
||||
|
||||
/**
|
||||
* Create window color element for the component
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
TextTrackSettings.prototype.createElWinColor_ = function createElWinColor_() {
|
||||
var legend = (0, _dom.createEl)('legend', {
|
||||
textContent: this.localize('Window')
|
||||
});
|
||||
|
||||
var select = this.createElSelect_('windowColor');
|
||||
|
||||
var opacity = (0, _dom.createEl)('span', {
|
||||
className: 'vjs-window-opacity vjs-opacity'
|
||||
}, undefined, this.createElSelect_('windowOpacity'));
|
||||
|
||||
return (0, _dom.createEl)('fieldset', {
|
||||
className: 'vjs-window-color vjs-tracksetting'
|
||||
}, undefined, [legend].concat(select, opacity));
|
||||
};
|
||||
|
||||
/**
|
||||
* Create color elements for the component
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
TextTrackSettings.prototype.createElColors_ = function createElColors_() {
|
||||
return (0, _dom.createEl)('div', {
|
||||
className: 'vjs-tracksettings-colors'
|
||||
}, undefined, [this.createElFgColor_(), this.createElBgColor_(), this.createElWinColor_()]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create font elements for the component
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
TextTrackSettings.prototype.createElFont_ = function createElFont_() {
|
||||
var fontPercent = (0, _dom.createEl)('div', {
|
||||
className: 'vjs-font-percent vjs-tracksetting'
|
||||
}, undefined, this.createElSelect_('fontPercent'));
|
||||
|
||||
var edgeStyle = (0, _dom.createEl)('div', {
|
||||
className: 'vjs-edge-style vjs-tracksetting'
|
||||
}, undefined, this.createElSelect_('edgeStyle'));
|
||||
|
||||
var fontFamily = (0, _dom.createEl)('div', {
|
||||
className: 'vjs-font-family vjs-tracksetting'
|
||||
}, undefined, this.createElSelect_('fontFamily'));
|
||||
|
||||
return (0, _dom.createEl)('div', {
|
||||
className: 'vjs-tracksettings-font'
|
||||
}, undefined, [fontPercent, edgeStyle, fontFamily]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create controls for the component
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
TextTrackSettings.prototype.createElControls_ = function createElControls_() {
|
||||
var defaultsButton = (0, _dom.createEl)('button', {
|
||||
className: 'vjs-default-button',
|
||||
textContent: this.localize('Defaults')
|
||||
});
|
||||
|
||||
var doneButton = (0, _dom.createEl)('button', {
|
||||
className: 'vjs-done-button',
|
||||
textContent: 'Done'
|
||||
});
|
||||
|
||||
return (0, _dom.createEl)('div', {
|
||||
className: 'vjs-tracksettings-controls'
|
||||
}, undefined, [defaultsButton, doneButton]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the component's DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
|
||||
|
||||
TextTrackSettings.prototype.createEl = function createEl() {
|
||||
var settings = (0, _dom.createEl)('div', {
|
||||
className: 'vjs-tracksettings'
|
||||
}, undefined, [this.createElColors_(), this.createElFont_(), this.createElControls_()]);
|
||||
|
||||
var heading = (0, _dom.createEl)('div', {
|
||||
className: 'vjs-control-text',
|
||||
id: 'TTsettingsDialogLabel-' + this.id_,
|
||||
textContent: 'Caption Settings Dialog'
|
||||
}, {
|
||||
'aria-level': '1',
|
||||
'role': 'heading'
|
||||
});
|
||||
|
||||
var description = (0, _dom.createEl)('div', {
|
||||
className: 'vjs-control-text',
|
||||
id: 'TTsettingsDialogDescription-' + this.id_,
|
||||
textContent: 'Beginning of dialog window. Escape will cancel and close the window.'
|
||||
});
|
||||
|
||||
var doc = (0, _dom.createEl)('div', undefined, {
|
||||
role: 'document'
|
||||
}, [heading, description, settings]);
|
||||
|
||||
return (0, _dom.createEl)('div', {
|
||||
className: 'vjs-caption-settings vjs-modal-overlay',
|
||||
tabIndex: -1
|
||||
}, {
|
||||
'role': 'dialog',
|
||||
'aria-labelledby': heading.id,
|
||||
'aria-describedby': description.id
|
||||
}, doc);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets an object of text track settings (or null).
|
||||
*
|
||||
* @return {Object}
|
||||
* An object with config values parsed from the DOM or localStorage.
|
||||
*/
|
||||
|
||||
|
||||
TextTrackSettings.prototype.getValues = function getValues() {
|
||||
var _this3 = this;
|
||||
|
||||
return Obj.reduce(selectConfigs, function (accum, config, key) {
|
||||
var value = getSelectedOptionValue(_this3.$(config.selector), config.parser);
|
||||
|
||||
if (value !== undefined) {
|
||||
accum[key] = value;
|
||||
}
|
||||
|
||||
return accum;
|
||||
}, {});
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets text track settings from an object of values.
|
||||
*
|
||||
* @param {Object} values
|
||||
* An object with config values parsed from the DOM or localStorage.
|
||||
*/
|
||||
|
||||
|
||||
TextTrackSettings.prototype.setValues = function setValues(values) {
|
||||
var _this4 = this;
|
||||
|
||||
Obj.each(selectConfigs, function (config, key) {
|
||||
setSelectedOption(_this4.$(config.selector), values[key], config.parser);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets all <select> elements to their default values.
|
||||
*/
|
||||
|
||||
|
||||
TextTrackSettings.prototype.setDefaults = function setDefaults() {
|
||||
var _this5 = this;
|
||||
|
||||
Obj.each(selectConfigs, function (config) {
|
||||
var index = config.hasOwnProperty('default') ? config['default'] : 0;
|
||||
|
||||
_this5.$(config.selector).selectedIndex = index;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Restore texttrack settings from localStorage
|
||||
*/
|
||||
|
||||
|
||||
TextTrackSettings.prototype.restoreSettings = function restoreSettings() {
|
||||
var values = void 0;
|
||||
|
||||
try {
|
||||
values = JSON.parse(_window2['default'].localStorage.getItem(LOCAL_STORAGE_KEY));
|
||||
} catch (err) {
|
||||
_log2['default'].warn(err);
|
||||
}
|
||||
|
||||
if (values) {
|
||||
this.setValues(values);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Save text track settings to localStorage
|
||||
*/
|
||||
|
||||
|
||||
TextTrackSettings.prototype.saveSettings = function saveSettings() {
|
||||
if (!this.options_.persistTextTrackSettings) {
|
||||
return;
|
||||
}
|
||||
|
||||
var values = this.getValues();
|
||||
|
||||
try {
|
||||
if (Object.keys(values).length) {
|
||||
_window2['default'].localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(values));
|
||||
} else {
|
||||
_window2['default'].localStorage.removeItem(LOCAL_STORAGE_KEY);
|
||||
}
|
||||
} catch (err) {
|
||||
_log2['default'].warn(err);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update display of text track settings
|
||||
*/
|
||||
|
||||
|
||||
TextTrackSettings.prototype.updateDisplay = function updateDisplay() {
|
||||
var ttDisplay = this.player_.getChild('textTrackDisplay');
|
||||
|
||||
if (ttDisplay) {
|
||||
ttDisplay.updateDisplay();
|
||||
}
|
||||
};
|
||||
|
||||
return TextTrackSettings;
|
||||
}(_component2['default']);
|
||||
|
||||
_component2['default'].registerComponent('TextTrackSettings', TextTrackSettings);
|
||||
|
||||
exports['default'] = TextTrackSettings;
|
||||
@@ -0,0 +1,432 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _textTrackCueList = require('./text-track-cue-list');
|
||||
|
||||
var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList);
|
||||
|
||||
var _fn = require('../utils/fn.js');
|
||||
|
||||
var Fn = _interopRequireWildcard(_fn);
|
||||
|
||||
var _trackEnums = require('./track-enums');
|
||||
|
||||
var _log = require('../utils/log.js');
|
||||
|
||||
var _log2 = _interopRequireDefault(_log);
|
||||
|
||||
var _window = require('global/window');
|
||||
|
||||
var _window2 = _interopRequireDefault(_window);
|
||||
|
||||
var _track = require('./track.js');
|
||||
|
||||
var _track2 = _interopRequireDefault(_track);
|
||||
|
||||
var _url = require('../utils/url.js');
|
||||
|
||||
var _xhr = require('xhr');
|
||||
|
||||
var _xhr2 = _interopRequireDefault(_xhr);
|
||||
|
||||
var _mergeOptions = require('../utils/merge-options');
|
||||
|
||||
var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
|
||||
|
||||
var _browser = require('../utils/browser.js');
|
||||
|
||||
var browser = _interopRequireWildcard(_browser);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file text-track.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Takes a webvtt file contents and parses it into cues
|
||||
*
|
||||
* @param {string} srcContent
|
||||
* webVTT file contents
|
||||
*
|
||||
* @param {TextTrack} track
|
||||
* TextTrack to add cues to. Cues come from the srcContent.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var parseCues = function parseCues(srcContent, track) {
|
||||
var parser = new _window2['default'].WebVTT.Parser(_window2['default'], _window2['default'].vttjs, _window2['default'].WebVTT.StringDecoder());
|
||||
var errors = [];
|
||||
|
||||
parser.oncue = function (cue) {
|
||||
track.addCue(cue);
|
||||
};
|
||||
|
||||
parser.onparsingerror = function (error) {
|
||||
errors.push(error);
|
||||
};
|
||||
|
||||
parser.onflush = function () {
|
||||
track.trigger({
|
||||
type: 'loadeddata',
|
||||
target: track
|
||||
});
|
||||
};
|
||||
|
||||
parser.parse(srcContent);
|
||||
if (errors.length > 0) {
|
||||
if (_window2['default'].console && _window2['default'].console.groupCollapsed) {
|
||||
_window2['default'].console.groupCollapsed('Text Track parsing errors for ' + track.src);
|
||||
}
|
||||
errors.forEach(function (error) {
|
||||
return _log2['default'].error(error);
|
||||
});
|
||||
if (_window2['default'].console && _window2['default'].console.groupEnd) {
|
||||
_window2['default'].console.groupEnd();
|
||||
}
|
||||
}
|
||||
|
||||
parser.flush();
|
||||
};
|
||||
|
||||
/**
|
||||
* Load a `TextTrack` from a specifed url.
|
||||
*
|
||||
* @param {string} src
|
||||
* Url to load track from.
|
||||
*
|
||||
* @param {TextTrack} track
|
||||
* Track to add cues to. Comes from the content at the end of `url`.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var loadTrack = function loadTrack(src, track) {
|
||||
var opts = {
|
||||
uri: src
|
||||
};
|
||||
var crossOrigin = (0, _url.isCrossOrigin)(src);
|
||||
|
||||
if (crossOrigin) {
|
||||
opts.cors = crossOrigin;
|
||||
}
|
||||
|
||||
(0, _xhr2['default'])(opts, Fn.bind(this, function (err, response, responseBody) {
|
||||
if (err) {
|
||||
return _log2['default'].error(err, response);
|
||||
}
|
||||
|
||||
track.loaded_ = true;
|
||||
|
||||
// Make sure that vttjs has loaded, otherwise, wait till it finished loading
|
||||
// NOTE: this is only used for the alt/video.novtt.js build
|
||||
if (typeof _window2['default'].WebVTT !== 'function') {
|
||||
if (track.tech_) {
|
||||
(function () {
|
||||
var loadHandler = function loadHandler() {
|
||||
return parseCues(responseBody, track);
|
||||
};
|
||||
|
||||
track.tech_.on('vttjsloaded', loadHandler);
|
||||
track.tech_.on('vttjserror', function () {
|
||||
_log2['default'].error('vttjs failed to load, stopping trying to process ' + track.src);
|
||||
track.tech_.off('vttjsloaded', loadHandler);
|
||||
});
|
||||
})();
|
||||
}
|
||||
} else {
|
||||
parseCues(responseBody, track);
|
||||
}
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* A representation of a single `TextTrack`.
|
||||
*
|
||||
* @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack}
|
||||
* @extends Track
|
||||
*/
|
||||
|
||||
var TextTrack = function (_Track) {
|
||||
_inherits(TextTrack, _Track);
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*
|
||||
* @param {Object} options={}
|
||||
* Object of option names and values
|
||||
*
|
||||
* @param {Tech} options.tech
|
||||
* A reference to the tech that owns this TextTrack.
|
||||
*
|
||||
* @param {TextTrack~Kind} [options.kind='subtitles']
|
||||
* A valid text track kind.
|
||||
*
|
||||
* @param {TextTrack~Mode} [options.mode='disabled']
|
||||
* A valid text track mode.
|
||||
*
|
||||
* @param {string} [options.id='vjs_track_' + Guid.newGUID()]
|
||||
* A unique id for this TextTrack.
|
||||
*
|
||||
* @param {string} [options.label='']
|
||||
* The menu label for this track.
|
||||
*
|
||||
* @param {string} [options.language='']
|
||||
* A valid two character language code.
|
||||
*
|
||||
* @param {string} [options.srclang='']
|
||||
* A valid two character language code. An alternative, but deprioritized
|
||||
* vesion of `options.language`
|
||||
*
|
||||
* @param {string} [options.src]
|
||||
* A url to TextTrack cues.
|
||||
*
|
||||
* @param {boolean} [options.default]
|
||||
* If this track should default to on or off.
|
||||
*/
|
||||
function TextTrack() {
|
||||
var _this, _ret2;
|
||||
|
||||
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
||||
|
||||
_classCallCheck(this, TextTrack);
|
||||
|
||||
if (!options.tech) {
|
||||
throw new Error('A tech was not provided.');
|
||||
}
|
||||
|
||||
var settings = (0, _mergeOptions2['default'])(options, {
|
||||
kind: _trackEnums.TextTrackKind[options.kind] || 'subtitles',
|
||||
language: options.language || options.srclang || ''
|
||||
});
|
||||
var mode = _trackEnums.TextTrackMode[settings.mode] || 'disabled';
|
||||
var default_ = settings['default'];
|
||||
|
||||
if (settings.kind === 'metadata' || settings.kind === 'chapters') {
|
||||
mode = 'hidden';
|
||||
}
|
||||
// on IE8 this will be a document element
|
||||
// for every other browser this will be a normal object
|
||||
var tt = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
|
||||
|
||||
tt.tech_ = settings.tech;
|
||||
|
||||
if (browser.IS_IE8) {
|
||||
for (var prop in TextTrack.prototype) {
|
||||
if (prop !== 'constructor') {
|
||||
tt[prop] = TextTrack.prototype[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tt.cues_ = [];
|
||||
tt.activeCues_ = [];
|
||||
|
||||
var cues = new _textTrackCueList2['default'](tt.cues_);
|
||||
var activeCues = new _textTrackCueList2['default'](tt.activeCues_);
|
||||
var changed = false;
|
||||
var timeupdateHandler = Fn.bind(tt, function () {
|
||||
|
||||
// Accessing this.activeCues for the side-effects of updating itself
|
||||
// due to it's nature as a getter function. Do not remove or cues will
|
||||
// stop updating!
|
||||
/* eslint-disable no-unused-expressions */
|
||||
this.activeCues;
|
||||
/* eslint-enable no-unused-expressions */
|
||||
if (changed) {
|
||||
this.trigger('cuechange');
|
||||
changed = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (mode !== 'disabled') {
|
||||
tt.tech_.on('timeupdate', timeupdateHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @member {boolean} default
|
||||
* If this track was set to be on or off by default. Cannot be changed after
|
||||
* creation.
|
||||
*
|
||||
* @readonly
|
||||
*/
|
||||
Object.defineProperty(tt, 'default', {
|
||||
get: function get() {
|
||||
return default_;
|
||||
},
|
||||
set: function set() {}
|
||||
});
|
||||
|
||||
/**
|
||||
* @member {string} mode
|
||||
* Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will
|
||||
* not be set if setting to an invalid mode.
|
||||
*
|
||||
* @fires TextTrack#modechange
|
||||
*/
|
||||
Object.defineProperty(tt, 'mode', {
|
||||
get: function get() {
|
||||
return mode;
|
||||
},
|
||||
set: function set(newMode) {
|
||||
if (!_trackEnums.TextTrackMode[newMode]) {
|
||||
return;
|
||||
}
|
||||
mode = newMode;
|
||||
if (mode === 'showing') {
|
||||
this.tech_.on('timeupdate', timeupdateHandler);
|
||||
}
|
||||
/**
|
||||
* An event that fires when mode changes on this track. This allows
|
||||
* the TextTrackList that holds this track to act accordingly.
|
||||
*
|
||||
* > Note: This is not part of the spec!
|
||||
*
|
||||
* @event TextTrack#modechange
|
||||
* @type {EventTarget~Event}
|
||||
*/
|
||||
this.trigger('modechange');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @member {TextTrackCueList} cues
|
||||
* The text track cue list for this TextTrack.
|
||||
*/
|
||||
Object.defineProperty(tt, 'cues', {
|
||||
get: function get() {
|
||||
if (!this.loaded_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return cues;
|
||||
},
|
||||
set: function set() {}
|
||||
});
|
||||
|
||||
/**
|
||||
* @member {TextTrackCueList} activeCues
|
||||
* The list text track cues that are currently active for this TextTrack.
|
||||
*/
|
||||
Object.defineProperty(tt, 'activeCues', {
|
||||
get: function get() {
|
||||
if (!this.loaded_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// nothing to do
|
||||
if (this.cues.length === 0) {
|
||||
return activeCues;
|
||||
}
|
||||
|
||||
var ct = this.tech_.currentTime();
|
||||
var active = [];
|
||||
|
||||
for (var i = 0, l = this.cues.length; i < l; i++) {
|
||||
var cue = this.cues[i];
|
||||
|
||||
if (cue.startTime <= ct && cue.endTime >= ct) {
|
||||
active.push(cue);
|
||||
} else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) {
|
||||
active.push(cue);
|
||||
}
|
||||
}
|
||||
|
||||
changed = false;
|
||||
|
||||
if (active.length !== this.activeCues_.length) {
|
||||
changed = true;
|
||||
} else {
|
||||
for (var _i = 0; _i < active.length; _i++) {
|
||||
if (this.activeCues_.indexOf(active[_i]) === -1) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.activeCues_ = active;
|
||||
activeCues.setCues_(this.activeCues_);
|
||||
|
||||
return activeCues;
|
||||
},
|
||||
set: function set() {}
|
||||
});
|
||||
|
||||
if (settings.src) {
|
||||
tt.src = settings.src;
|
||||
loadTrack(settings.src, tt);
|
||||
} else {
|
||||
tt.loaded_ = true;
|
||||
}
|
||||
|
||||
return _ret2 = tt, _possibleConstructorReturn(_this, _ret2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a cue to the internal list of cues.
|
||||
*
|
||||
* @param {TextTrack~Cue} cue
|
||||
* The cue to add to our internal list
|
||||
*/
|
||||
|
||||
|
||||
TextTrack.prototype.addCue = function addCue(cue) {
|
||||
var tracks = this.tech_.textTracks();
|
||||
|
||||
if (tracks) {
|
||||
for (var i = 0; i < tracks.length; i++) {
|
||||
if (tracks[i] !== this) {
|
||||
tracks[i].removeCue(cue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.cues_.push(cue);
|
||||
this.cues.setCues_(this.cues_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a cue from our internal list
|
||||
*
|
||||
* @param {TextTrack~Cue} removeCue
|
||||
* The cue to remove from our internal list
|
||||
*/
|
||||
|
||||
|
||||
TextTrack.prototype.removeCue = function removeCue(_removeCue) {
|
||||
var removed = false;
|
||||
|
||||
for (var i = 0, l = this.cues_.length; i < l; i++) {
|
||||
var cue = this.cues_[i];
|
||||
|
||||
if (cue === _removeCue) {
|
||||
this.cues_.splice(i, 1);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (removed) {
|
||||
this.cues.setCues_(this.cues_);
|
||||
}
|
||||
};
|
||||
|
||||
return TextTrack;
|
||||
}(_track2['default']);
|
||||
|
||||
/**
|
||||
* cuechange - One or more cues in the track have become active or stopped being active.
|
||||
*/
|
||||
|
||||
|
||||
TextTrack.prototype.allowedEvents_ = {
|
||||
cuechange: 'cuechange'
|
||||
};
|
||||
|
||||
exports['default'] = TextTrack;
|
||||
@@ -0,0 +1,66 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
/**
|
||||
* @file track-kinds.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* All possible `VideoTrackKind`s
|
||||
*
|
||||
* @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind
|
||||
* @typedef VideoTrack~Kind
|
||||
* @enum
|
||||
*/
|
||||
var VideoTrackKind = exports.VideoTrackKind = {
|
||||
alternative: 'alternative',
|
||||
captions: 'captions',
|
||||
main: 'main',
|
||||
sign: 'sign',
|
||||
subtitles: 'subtitles',
|
||||
commentary: 'commentary'
|
||||
};
|
||||
|
||||
/**
|
||||
* All possible `AudioTrackKind`s
|
||||
*
|
||||
* @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind
|
||||
* @typedef AudioTrack~Kind
|
||||
* @enum
|
||||
*/
|
||||
var AudioTrackKind = exports.AudioTrackKind = {
|
||||
'alternative': 'alternative',
|
||||
'descriptions': 'descriptions',
|
||||
'main': 'main',
|
||||
'main-desc': 'main-desc',
|
||||
'translation': 'translation',
|
||||
'commentary': 'commentary'
|
||||
};
|
||||
|
||||
/**
|
||||
* All possible `TextTrackKind`s
|
||||
*
|
||||
* @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-texttrack-kind
|
||||
* @typedef TextTrack~Kind
|
||||
* @enum
|
||||
*/
|
||||
var TextTrackKind = exports.TextTrackKind = {
|
||||
subtitles: 'subtitles',
|
||||
captions: 'captions',
|
||||
descriptions: 'descriptions',
|
||||
chapters: 'chapters',
|
||||
metadata: 'metadata'
|
||||
};
|
||||
|
||||
/**
|
||||
* All possible `TextTrackMode`s
|
||||
*
|
||||
* @see https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode
|
||||
* @typedef TextTrack~Mode
|
||||
* @enum
|
||||
*/
|
||||
var TextTrackMode = exports.TextTrackMode = {
|
||||
disabled: 'disabled',
|
||||
hidden: 'hidden',
|
||||
showing: 'showing'
|
||||
};
|
||||
@@ -0,0 +1,233 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _eventTarget = require('../event-target');
|
||||
|
||||
var _eventTarget2 = _interopRequireDefault(_eventTarget);
|
||||
|
||||
var _browser = require('../utils/browser.js');
|
||||
|
||||
var browser = _interopRequireWildcard(_browser);
|
||||
|
||||
var _document = require('global/document');
|
||||
|
||||
var _document2 = _interopRequireDefault(_document);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file track-list.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and
|
||||
* {@link VideoTrackList}
|
||||
*
|
||||
* @extends EventTarget
|
||||
*/
|
||||
var TrackList = function (_EventTarget) {
|
||||
_inherits(TrackList, _EventTarget);
|
||||
|
||||
/**
|
||||
* Create an instance of this class
|
||||
*
|
||||
* @param {Track[]} tracks
|
||||
* A list of tracks to initialize the list with.
|
||||
*
|
||||
* @param {Object} [list]
|
||||
* The child object with inheritance done manually for ie8.
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
function TrackList() {
|
||||
var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
||||
|
||||
var _ret;
|
||||
|
||||
var list = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
||||
|
||||
_classCallCheck(this, TrackList);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
|
||||
|
||||
if (!list) {
|
||||
list = _this; // eslint-disable-line
|
||||
if (browser.IS_IE8) {
|
||||
list = _document2['default'].createElement('custom');
|
||||
for (var prop in TrackList.prototype) {
|
||||
if (prop !== 'constructor') {
|
||||
list[prop] = TrackList.prototype[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list.tracks_ = [];
|
||||
|
||||
/**
|
||||
* @member {number} length
|
||||
* The current number of `Track`s in the this Trackist.
|
||||
*/
|
||||
Object.defineProperty(list, 'length', {
|
||||
get: function get() {
|
||||
return this.tracks_.length;
|
||||
}
|
||||
});
|
||||
|
||||
for (var i = 0; i < tracks.length; i++) {
|
||||
list.addTrack_(tracks[i]);
|
||||
}
|
||||
|
||||
// must return the object, as for ie8 it will not be this
|
||||
// but a reference to a document object
|
||||
return _ret = list, _possibleConstructorReturn(_this, _ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link Track} to the `TrackList`
|
||||
*
|
||||
* @param {Track} track
|
||||
* The audio, video, or text track to add to the list.
|
||||
*
|
||||
* @fires TrackList#addtrack
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
TrackList.prototype.addTrack_ = function addTrack_(track) {
|
||||
var index = this.tracks_.length;
|
||||
|
||||
if (!('' + index in this)) {
|
||||
Object.defineProperty(this, index, {
|
||||
get: function get() {
|
||||
return this.tracks_[index];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Do not add duplicate tracks
|
||||
if (this.tracks_.indexOf(track) === -1) {
|
||||
this.tracks_.push(track);
|
||||
/**
|
||||
* Triggered when a track is added to a track list.
|
||||
*
|
||||
* @event TrackList#addtrack
|
||||
* @type {EventTarget~Event}
|
||||
* @property {Track} track
|
||||
* A reference to track that was added.
|
||||
*/
|
||||
this.trigger({
|
||||
track: track,
|
||||
type: 'addtrack'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a {@link Track} from the `TrackList`
|
||||
*
|
||||
* @param {Track} track
|
||||
* The audio, video, or text track to remove from the list.
|
||||
*
|
||||
* @fires TrackList#removetrack
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
TrackList.prototype.removeTrack_ = function removeTrack_(rtrack) {
|
||||
var track = void 0;
|
||||
|
||||
for (var i = 0, l = this.length; i < l; i++) {
|
||||
if (this[i] === rtrack) {
|
||||
track = this[i];
|
||||
if (track.off) {
|
||||
track.off();
|
||||
}
|
||||
|
||||
this.tracks_.splice(i, 1);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!track) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when a track is removed from track list.
|
||||
*
|
||||
* @event TrackList#removetrack
|
||||
* @type {EventTarget~Event}
|
||||
* @property {Track} track
|
||||
* A reference to track that was removed.
|
||||
*/
|
||||
this.trigger({
|
||||
track: track,
|
||||
type: 'removetrack'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a Track from the TrackList by a tracks id
|
||||
*
|
||||
* @param {String} id - the id of the track to get
|
||||
* @method getTrackById
|
||||
* @return {Track}
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
TrackList.prototype.getTrackById = function getTrackById(id) {
|
||||
var result = null;
|
||||
|
||||
for (var i = 0, l = this.length; i < l; i++) {
|
||||
var track = this[i];
|
||||
|
||||
if (track.id === id) {
|
||||
result = track;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
return TrackList;
|
||||
}(_eventTarget2['default']);
|
||||
|
||||
/**
|
||||
* Triggered when a different track is selected/enabled.
|
||||
*
|
||||
* @event TrackList#change
|
||||
* @type {EventTarget~Event}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Events that can be called with on + eventName. See {@link EventHandler}.
|
||||
*
|
||||
* @property {Object} TrackList#allowedEvents_
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
TrackList.prototype.allowedEvents_ = {
|
||||
change: 'change',
|
||||
addtrack: 'addtrack',
|
||||
removetrack: 'removetrack'
|
||||
};
|
||||
|
||||
// emulate attribute EventHandler support to allow for feature detection
|
||||
for (var event in TrackList.prototype.allowedEvents_) {
|
||||
TrackList.prototype['on' + event] = null;
|
||||
}
|
||||
|
||||
exports['default'] = TrackList;
|
||||
@@ -0,0 +1,142 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _browser = require('../utils/browser.js');
|
||||
|
||||
var browser = _interopRequireWildcard(_browser);
|
||||
|
||||
var _document = require('global/document');
|
||||
|
||||
var _document2 = _interopRequireDefault(_document);
|
||||
|
||||
var _guid = require('../utils/guid.js');
|
||||
|
||||
var Guid = _interopRequireWildcard(_guid);
|
||||
|
||||
var _eventTarget = require('../event-target');
|
||||
|
||||
var _eventTarget2 = _interopRequireDefault(_eventTarget);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
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; } }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file track.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* A Track class that contains all of the common functionality for {@link AudioTrack},
|
||||
* {@link VideoTrack}, and {@link TextTrack}.
|
||||
*
|
||||
* > Note: This class should not be used directly
|
||||
*
|
||||
* @see {@link https://html.spec.whatwg.org/multipage/embedded-content.html}
|
||||
* @extends EventTarget
|
||||
* @abstract
|
||||
*/
|
||||
var Track = function (_EventTarget) {
|
||||
_inherits(Track, _EventTarget);
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*
|
||||
* @param {Object} [options={}]
|
||||
* Object of option names and values
|
||||
*
|
||||
* @param {string} [options.kind='']
|
||||
* A valid kind for the track type you are creating.
|
||||
*
|
||||
* @param {string} [options.id='vjs_track_' + Guid.newGUID()]
|
||||
* A unique id for this AudioTrack.
|
||||
*
|
||||
* @param {string} [options.label='']
|
||||
* The menu label for this track.
|
||||
*
|
||||
* @param {string} [options.language='']
|
||||
* A valid two character language code.
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
function Track() {
|
||||
var _ret;
|
||||
|
||||
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
||||
|
||||
_classCallCheck(this, Track);
|
||||
|
||||
var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
|
||||
|
||||
var track = _this; // eslint-disable-line
|
||||
|
||||
if (browser.IS_IE8) {
|
||||
track = _document2['default'].createElement('custom');
|
||||
for (var prop in Track.prototype) {
|
||||
if (prop !== 'constructor') {
|
||||
track[prop] = Track.prototype[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var trackProps = {
|
||||
id: options.id || 'vjs_track_' + Guid.newGUID(),
|
||||
kind: options.kind || '',
|
||||
label: options.label || '',
|
||||
language: options.language || ''
|
||||
};
|
||||
|
||||
/**
|
||||
* @member {string} id
|
||||
* The id of this track. Cannot be changed after creation.
|
||||
*
|
||||
* @readonly
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member {string} kind
|
||||
* The kind of track that this is. Cannot be changed after creation.
|
||||
*
|
||||
* @readonly
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member {string} label
|
||||
* The label of this track. Cannot be changed after creation.
|
||||
*
|
||||
* @readonly
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member {string} language
|
||||
* The two letter language code for this track. Cannot be changed after
|
||||
* creation.
|
||||
*
|
||||
* @readonly
|
||||
*/
|
||||
|
||||
var _loop = function _loop(key) {
|
||||
Object.defineProperty(track, key, {
|
||||
get: function get() {
|
||||
return trackProps[key];
|
||||
},
|
||||
set: function set() {}
|
||||
});
|
||||
};
|
||||
|
||||
for (var key in trackProps) {
|
||||
_loop(key);
|
||||
}
|
||||
|
||||
return _ret = track, _possibleConstructorReturn(_this, _ret);
|
||||
}
|
||||
|
||||
return Track;
|
||||
}(_eventTarget2['default']);
|
||||
|
||||
exports['default'] = Track;
|
||||
@@ -0,0 +1,193 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _trackList = require('./track-list');
|
||||
|
||||
var _trackList2 = _interopRequireDefault(_trackList);
|
||||
|
||||
var _browser = require('../utils/browser.js');
|
||||
|
||||
var browser = _interopRequireWildcard(_browser);
|
||||
|
||||
var _document = require('global/document');
|
||||
|
||||
var _document2 = _interopRequireDefault(_document);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; } /**
|
||||
* @file video-track-list.js
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Un-select all other {@link VideoTrack}s that are selected.
|
||||
*
|
||||
* @param {VideoTrackList} list
|
||||
* list to work on
|
||||
*
|
||||
* @param {VideoTrack} track
|
||||
* The track to skip
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
var disableOthers = function disableOthers(list, track) {
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (track.id === list[i].id) {
|
||||
continue;
|
||||
}
|
||||
// another video track is enabled, disable it
|
||||
list[i].selected = false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The current list of {@link VideoTrack} for a video.
|
||||
*
|
||||
* @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist}
|
||||
* @extends TrackList
|
||||
*/
|
||||
|
||||
var VideoTrackList = function (_TrackList) {
|
||||
_inherits(VideoTrackList, _TrackList);
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*
|
||||
* @param {VideoTrack[]} [tracks=[]]
|
||||
* A list of `VideoTrack` to instantiate the list with.
|
||||
*/
|
||||
function VideoTrackList() {
|
||||
var _this, _ret;
|
||||
|
||||
var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
||||
|
||||
_classCallCheck(this, VideoTrackList);
|
||||
|
||||
var list = void 0;
|
||||
|
||||
// make sure only 1 track is enabled
|
||||
// sorted from last index to first index
|
||||
for (var i = tracks.length - 1; i >= 0; i--) {
|
||||
if (tracks[i].selected) {
|
||||
disableOthers(tracks, tracks[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// IE8 forces us to implement inheritance ourselves
|
||||
// as it does not support Object.defineProperty properly
|
||||
if (browser.IS_IE8) {
|
||||
list = _document2['default'].createElement('custom');
|
||||
for (var prop in _trackList2['default'].prototype) {
|
||||
if (prop !== 'constructor') {
|
||||
list[prop] = _trackList2['default'].prototype[prop];
|
||||
}
|
||||
}
|
||||
for (var _prop in VideoTrackList.prototype) {
|
||||
if (_prop !== 'constructor') {
|
||||
list[_prop] = VideoTrackList.prototype[_prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
|
||||
list.changing_ = false;
|
||||
|
||||
/**
|
||||
* @member {number} VideoTrackList#selectedIndex
|
||||
* The current index of the selected {@link VideoTrack`}.
|
||||
*/
|
||||
Object.defineProperty(list, 'selectedIndex', {
|
||||
get: function get() {
|
||||
for (var _i = 0; _i < this.length; _i++) {
|
||||
if (this[_i].selected) {
|
||||
return _i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
set: function set() {}
|
||||
});
|
||||
|
||||
return _ret = list, _possibleConstructorReturn(_this, _ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link VideoTrack} to the `VideoTrackList`.
|
||||
*
|
||||
* @param {VideoTrack} track
|
||||
* The VideoTrack to add to the list
|
||||
*
|
||||
* @fires TrackList#addtrack
|
||||
* @private
|
||||
*/
|
||||
|
||||
|
||||
VideoTrackList.prototype.addTrack_ = function addTrack_(track) {
|
||||
var _this2 = this;
|
||||
|
||||
if (track.selected) {
|
||||
disableOthers(this, track);
|
||||
}
|
||||
|
||||
_TrackList.prototype.addTrack_.call(this, track);
|
||||
// native tracks don't have this
|
||||
if (!track.addEventListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @listens VideoTrack#selectedchange
|
||||
* @fires TrackList#change
|
||||
*/
|
||||
track.addEventListener('selectedchange', function () {
|
||||
if (_this2.changing_) {
|
||||
return;
|
||||
}
|
||||
_this2.changing_ = true;
|
||||
disableOthers(_this2, track);
|
||||
_this2.changing_ = false;
|
||||
_this2.trigger('change');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a {@link VideoTrack} to the `VideoTrackList`.
|
||||
*
|
||||
* @param {VideoTrack} track
|
||||
* The VideoTrack to add to the list
|
||||
*
|
||||
* @fires TrackList#addtrack
|
||||
*/
|
||||
|
||||
|
||||
VideoTrackList.prototype.addTrack = function addTrack(track) {
|
||||
this.addTrack_(track);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a {@link VideoTrack} to the `VideoTrackList`.
|
||||
*
|
||||
* @param {VideoTrack} track
|
||||
* The VideoTrack to remove from the list.
|
||||
*
|
||||
* @fires TrackList#removetrack
|
||||
*/
|
||||
|
||||
|
||||
VideoTrackList.prototype.removeTrack = function removeTrack(track) {
|
||||
_TrackList.prototype.removeTrack_.call(this, track);
|
||||
};
|
||||
|
||||
return VideoTrackList;
|
||||
}(_trackList2['default']);
|
||||
|
||||
exports['default'] = VideoTrackList;
|
||||
@@ -0,0 +1,128 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
|
||||
var _trackEnums = require('./track-enums');
|
||||
|
||||
var _track = require('./track');
|
||||
|
||||
var _track2 = _interopRequireDefault(_track);
|
||||
|
||||
var _mergeOptions = require('../utils/merge-options');
|
||||
|
||||
var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
|
||||
|
||||
var _browser = require('../utils/browser.js');
|
||||
|
||||
var browser = _interopRequireWildcard(_browser);
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
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; }
|
||||
|
||||
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; }
|
||||
|
||||
/**
|
||||
* A representation of a single `VideoTrack`.
|
||||
*
|
||||
* @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack}
|
||||
* @extends Track
|
||||
*/
|
||||
var VideoTrack = function (_Track) {
|
||||
_inherits(VideoTrack, _Track);
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*
|
||||
* @param {Object} [options={}]
|
||||
* Object of option names and values
|
||||
*
|
||||
* @param {string} [options.kind='']
|
||||
* A valid {@link VideoTrack~Kind}
|
||||
*
|
||||
* @param {string} [options.id='vjs_track_' + Guid.newGUID()]
|
||||
* A unique id for this AudioTrack.
|
||||
*
|
||||
* @param {string} [options.label='']
|
||||
* The menu label for this track.
|
||||
*
|
||||
* @param {string} [options.language='']
|
||||
* A valid two character language code.
|
||||
*
|
||||
* @param {boolean} [options.selected]
|
||||
* If this track is the one that is currently playing.
|
||||
*/
|
||||
function VideoTrack() {
|
||||
var _this, _ret;
|
||||
|
||||
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
||||
|
||||
_classCallCheck(this, VideoTrack);
|
||||
|
||||
var settings = (0, _mergeOptions2['default'])(options, {
|
||||
kind: _trackEnums.VideoTrackKind[options.kind] || ''
|
||||
});
|
||||
|
||||
// on IE8 this will be a document element
|
||||
// for every other browser this will be a normal object
|
||||
var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
|
||||
var selected = false;
|
||||
|
||||
if (browser.IS_IE8) {
|
||||
for (var prop in VideoTrack.prototype) {
|
||||
if (prop !== 'constructor') {
|
||||
track[prop] = VideoTrack.prototype[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @member {boolean} selected
|
||||
* If this `VideoTrack` is selected or not. When setting this will
|
||||
* fire {@link VideoTrack#selectedchange} if the state of selected changed.
|
||||
*
|
||||
* @fires VideoTrack#selectedchange
|
||||
*/
|
||||
Object.defineProperty(track, 'selected', {
|
||||
get: function get() {
|
||||
return selected;
|
||||
},
|
||||
set: function set(newSelected) {
|
||||
// an invalid or unchanged value
|
||||
if (typeof newSelected !== 'boolean' || newSelected === selected) {
|
||||
return;
|
||||
}
|
||||
selected = newSelected;
|
||||
|
||||
/**
|
||||
* An event that fires when selected changes on this track. This allows
|
||||
* the VideoTrackList that holds this track to act accordingly.
|
||||
*
|
||||
* > Note: This is not part of the spec! Native tracks will do
|
||||
* this internally without an event.
|
||||
*
|
||||
* @event VideoTrack#selectedchange
|
||||
* @type {EventTarget~Event}
|
||||
*/
|
||||
this.trigger('selectedchange');
|
||||
}
|
||||
});
|
||||
|
||||
// if the user sets this track to selected then
|
||||
// set selected to that true value otherwise
|
||||
// we keep it false
|
||||
if (settings.selected) {
|
||||
track.selected = settings.selected;
|
||||
}
|
||||
|
||||
return _ret = track, _possibleConstructorReturn(_this, _ret);
|
||||
}
|
||||
|
||||
return VideoTrack;
|
||||
}(_track2['default']);
|
||||
|
||||
exports['default'] = VideoTrack;
|
||||
@@ -0,0 +1,89 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
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;
|
||||
|
||||
var _dom = require('./dom');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
var _window = require('global/window');
|
||||
|
||||
var _window2 = _interopRequireDefault(_window);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
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; } }
|
||||
|
||||
/**
|
||||
* @file browser.js
|
||||
* @module browser
|
||||
*/
|
||||
var USER_AGENT = _window2['default'].navigator && _window2['default'].navigator.userAgent || '';
|
||||
var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT);
|
||||
var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null;
|
||||
|
||||
/*
|
||||
* Device is an iPhone
|
||||
*
|
||||
* @type {Boolean}
|
||||
* @constant
|
||||
* @private
|
||||
*/
|
||||
var IS_IPAD = exports.IS_IPAD = /iPad/i.test(USER_AGENT);
|
||||
|
||||
// The Facebook app's UIWebView identifies as both an iPhone and iPad, so
|
||||
// to identify iPhones, we need to exclude iPads.
|
||||
// http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/
|
||||
var IS_IPHONE = exports.IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD;
|
||||
var IS_IPOD = exports.IS_IPOD = /iPod/i.test(USER_AGENT);
|
||||
var IS_IOS = exports.IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;
|
||||
|
||||
var IOS_VERSION = exports.IOS_VERSION = function () {
|
||||
var match = USER_AGENT.match(/OS (\d+)_/i);
|
||||
|
||||
if (match && match[1]) {
|
||||
return match[1];
|
||||
}
|
||||
return null;
|
||||
}();
|
||||
|
||||
var IS_ANDROID = exports.IS_ANDROID = /Android/i.test(USER_AGENT);
|
||||
var ANDROID_VERSION = exports.ANDROID_VERSION = function () {
|
||||
// This matches Android Major.Minor.Patch versions
|
||||
// ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
|
||||
var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);
|
||||
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var major = match[1] && parseFloat(match[1]);
|
||||
var minor = match[2] && parseFloat(match[2]);
|
||||
|
||||
if (major && minor) {
|
||||
return parseFloat(match[1] + '.' + match[2]);
|
||||
} else if (major) {
|
||||
return major;
|
||||
}
|
||||
return null;
|
||||
}();
|
||||
|
||||
// Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser
|
||||
var IS_OLD_ANDROID = exports.IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3;
|
||||
var IS_NATIVE_ANDROID = exports.IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537;
|
||||
|
||||
var IS_FIREFOX = exports.IS_FIREFOX = /Firefox/i.test(USER_AGENT);
|
||||
var IS_EDGE = exports.IS_EDGE = /Edge/i.test(USER_AGENT);
|
||||
var IS_CHROME = exports.IS_CHROME = !IS_EDGE && /Chrome/i.test(USER_AGENT);
|
||||
var IS_IE8 = exports.IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT);
|
||||
var IE_VERSION = exports.IE_VERSION = function (result) {
|
||||
return result && parseFloat(result[1]);
|
||||
}(/MSIE\s(\d+)\.\d/.exec(USER_AGENT));
|
||||
|
||||
var IS_SAFARI = exports.IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE;
|
||||
var IS_ANY_SAFARI = exports.IS_ANY_SAFARI = IS_SAFARI || IS_IOS;
|
||||
|
||||
var TOUCH_ENABLED = exports.TOUCH_ENABLED = Dom.isReal() && ('ontouchstart' in _window2['default'] || _window2['default'].DocumentTouch && _window2['default'].document instanceof _window2['default'].DocumentTouch);
|
||||
|
||||
var BACKGROUND_SIZE_SUPPORTED = exports.BACKGROUND_SIZE_SUPPORTED = Dom.isReal() && 'backgroundSize' in _window2['default'].document.createElement('video').style;
|
||||
@@ -0,0 +1,49 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
exports.bufferedPercent = bufferedPercent;
|
||||
|
||||
var _timeRanges = require('./time-ranges.js');
|
||||
|
||||
/**
|
||||
* Compute the percentage of the media that has been buffered.
|
||||
*
|
||||
* @param {TimeRange} buffered
|
||||
* The current `TimeRange` object representing buffered time ranges
|
||||
*
|
||||
* @param {number} duration
|
||||
* Total duration of the media
|
||||
*
|
||||
* @return {number}
|
||||
* Percent buffered of the total duration in decimal form.
|
||||
*/
|
||||
function bufferedPercent(buffered, duration) {
|
||||
var bufferedDuration = 0;
|
||||
var start = void 0;
|
||||
var end = void 0;
|
||||
|
||||
if (!duration) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!buffered || !buffered.length) {
|
||||
buffered = (0, _timeRanges.createTimeRange)(0, 0);
|
||||
}
|
||||
|
||||
for (var i = 0; i < buffered.length; i++) {
|
||||
start = buffered.start(i);
|
||||
end = buffered.end(i);
|
||||
|
||||
// buffered end can be bigger than duration by a very small fraction
|
||||
if (end > duration) {
|
||||
end = duration;
|
||||
}
|
||||
|
||||
bufferedDuration += end - start;
|
||||
}
|
||||
|
||||
return bufferedDuration / duration;
|
||||
} /**
|
||||
* @file buffer.js
|
||||
* @module buffer
|
||||
*/
|
||||
@@ -0,0 +1,42 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
exports['default'] = computedStyle;
|
||||
|
||||
var _window = require('global/window');
|
||||
|
||||
var _window2 = _interopRequireDefault(_window);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
/**
|
||||
* A safe getComputedStyle with an IE8 fallback.
|
||||
*
|
||||
* This is needed because in Firefox, if the player is loaded in an iframe with
|
||||
* `display:none`, then `getComputedStyle` returns `null`, so, we do a null-check to
|
||||
* make sure that the player doesn't break in these cases.
|
||||
*
|
||||
* @param {Element} el
|
||||
* The element you want the computed style of
|
||||
*
|
||||
* @param {string} prop
|
||||
* The property name you want
|
||||
*
|
||||
* @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397
|
||||
*/
|
||||
function computedStyle(el, prop) {
|
||||
if (!el || !prop) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (typeof _window2['default'].getComputedStyle === 'function') {
|
||||
var cs = _window2['default'].getComputedStyle(el);
|
||||
|
||||
return cs ? cs[prop] : '';
|
||||
}
|
||||
|
||||
return el.currentStyle[prop] || '';
|
||||
} /**
|
||||
* @file computed-style.js
|
||||
* @module computed-style
|
||||
*/
|
||||
@@ -0,0 +1,897 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
exports.$$ = exports.$ = undefined;
|
||||
|
||||
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 ', '.']);
|
||||
|
||||
exports.isReal = isReal;
|
||||
exports.isEl = isEl;
|
||||
exports.getEl = getEl;
|
||||
exports.createEl = createEl;
|
||||
exports.textContent = textContent;
|
||||
exports.insertElFirst = insertElFirst;
|
||||
exports.getElData = getElData;
|
||||
exports.hasElData = hasElData;
|
||||
exports.removeElData = removeElData;
|
||||
exports.hasElClass = hasElClass;
|
||||
exports.addElClass = addElClass;
|
||||
exports.removeElClass = removeElClass;
|
||||
exports.toggleElClass = toggleElClass;
|
||||
exports.setElAttributes = setElAttributes;
|
||||
exports.getElAttributes = getElAttributes;
|
||||
exports.getAttribute = getAttribute;
|
||||
exports.setAttribute = setAttribute;
|
||||
exports.removeAttribute = removeAttribute;
|
||||
exports.blockTextSelection = blockTextSelection;
|
||||
exports.unblockTextSelection = unblockTextSelection;
|
||||
exports.findElPosition = findElPosition;
|
||||
exports.getPointerPosition = getPointerPosition;
|
||||
exports.isTextNode = isTextNode;
|
||||
exports.emptyEl = emptyEl;
|
||||
exports.normalizeContent = normalizeContent;
|
||||
exports.appendContent = appendContent;
|
||||
exports.insertContent = insertContent;
|
||||
|
||||
var _document = require('global/document');
|
||||
|
||||
var _document2 = _interopRequireDefault(_document);
|
||||
|
||||
var _window = require('global/window');
|
||||
|
||||
var _window2 = _interopRequireDefault(_window);
|
||||
|
||||
var _guid = require('./guid.js');
|
||||
|
||||
var Guid = _interopRequireWildcard(_guid);
|
||||
|
||||
var _log = require('./log.js');
|
||||
|
||||
var _log2 = _interopRequireDefault(_log);
|
||||
|
||||
var _tsml = require('tsml');
|
||||
|
||||
var _tsml2 = _interopRequireDefault(_tsml);
|
||||
|
||||
var _obj = require('./obj');
|
||||
|
||||
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; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } /**
|
||||
* @file dom.js
|
||||
* @module dom
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Detect if a value is a string with any non-whitespace characters.
|
||||
*
|
||||
* @param {string} str
|
||||
* The string to check
|
||||
*
|
||||
* @return {boolean}
|
||||
* - True if the string is non-blank
|
||||
* - False otherwise
|
||||
*
|
||||
*/
|
||||
function isNonBlankString(str) {
|
||||
return typeof str === 'string' && /\S/.test(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an error if the passed string has whitespace. This is used by
|
||||
* class methods to be relatively consistent with the classList API.
|
||||
*
|
||||
* @param {string} str
|
||||
* The string to check for whitespace.
|
||||
*
|
||||
* @throws {Error}
|
||||
* Throws an error if there is whitespace in the string.
|
||||
*
|
||||
*/
|
||||
function throwIfWhitespace(str) {
|
||||
if (/\s/.test(str)) {
|
||||
throw new Error('class has illegal whitespace characters');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce a regular expression for matching a className within an elements className.
|
||||
*
|
||||
* @param {string} className
|
||||
* The className to generate the RegExp for.
|
||||
*
|
||||
* @return {RegExp}
|
||||
* The RegExp that will check for a specific `className` in an elements
|
||||
* className.
|
||||
*/
|
||||
function classRegExp(className) {
|
||||
return new RegExp('(^|\\s)' + className + '($|\\s)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the current DOM interface appears to be real.
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function isReal() {
|
||||
return (
|
||||
|
||||
// Both document and window will never be undefined thanks to `global`.
|
||||
_document2['default'] === _window2['default'].document &&
|
||||
|
||||
// In IE < 9, DOM methods return "object" as their type, so all we can
|
||||
// confidently check is that it exists.
|
||||
typeof _document2['default'].createElement !== 'undefined'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines, via duck typing, whether or not a value is a DOM element.
|
||||
*
|
||||
* @param {Mixed} value
|
||||
* The thing to check
|
||||
*
|
||||
* @return {boolean}
|
||||
* - True if it is a DOM element
|
||||
* - False otherwise
|
||||
*/
|
||||
function isEl(value) {
|
||||
return (0, _obj.isObject)(value) && value.nodeType === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates functions to query the DOM using a given method.
|
||||
*
|
||||
* @param {string} method
|
||||
* The method to create the query with.
|
||||
*
|
||||
* @return {Function}
|
||||
* The query method
|
||||
*/
|
||||
function createQuerier(method) {
|
||||
return function (selector, context) {
|
||||
if (!isNonBlankString(selector)) {
|
||||
return _document2['default'][method](null);
|
||||
}
|
||||
if (isNonBlankString(context)) {
|
||||
context = _document2['default'].querySelector(context);
|
||||
}
|
||||
|
||||
var ctx = isEl(context) ? context : _document2['default'];
|
||||
|
||||
return ctx[method] && ctx[method](selector);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand for document.getElementById()
|
||||
* Also allows for CSS (jQuery) ID syntax. But nothing other than IDs.
|
||||
*
|
||||
* @param {string} id
|
||||
* The id of the element to get
|
||||
*
|
||||
* @return {Element|null}
|
||||
* Element with supplied ID or null if there wasn't one.
|
||||
*/
|
||||
function getEl(id) {
|
||||
if (id.indexOf('#') === 0) {
|
||||
id = id.slice(1);
|
||||
}
|
||||
|
||||
return _document2['default'].getElementById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an element and applies properties.
|
||||
*
|
||||
* @param {string} [tagName='div']
|
||||
* Name of tag to be created.
|
||||
*
|
||||
* @param {Object} [properties={}]
|
||||
* Element properties to be applied.
|
||||
*
|
||||
* @param {Object} [attributes={}]
|
||||
* Element attributes to be applied.
|
||||
*
|
||||
* @param {String|Element|TextNode|Array|Function} [content]
|
||||
* Contents for the element (see: {@link dom:normalizeContent})
|
||||
*
|
||||
* @return {Element}
|
||||
* The element that was created.
|
||||
*/
|
||||
function createEl() {
|
||||
var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
|
||||
var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
||||
var content = arguments[3];
|
||||
|
||||
var el = _document2['default'].createElement(tagName);
|
||||
|
||||
Object.getOwnPropertyNames(properties).forEach(function (propName) {
|
||||
var val = properties[propName];
|
||||
|
||||
// See #2176
|
||||
// We originally were accepting both properties and attributes in the
|
||||
// same object, but that doesn't work so well.
|
||||
if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') {
|
||||
_log2['default'].warn((0, _tsml2['default'])(_templateObject, propName, val));
|
||||
el.setAttribute(propName, val);
|
||||
|
||||
// Handle textContent since it's not supported everywhere and we have a
|
||||
// method for it.
|
||||
} else if (propName === 'textContent') {
|
||||
textContent(el, val);
|
||||
} else {
|
||||
el[propName] = val;
|
||||
}
|
||||
});
|
||||
|
||||
Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
|
||||
el.setAttribute(attrName, attributes[attrName]);
|
||||
});
|
||||
|
||||
if (content) {
|
||||
appendContent(el, content);
|
||||
}
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects text into an element, replacing any existing contents entirely.
|
||||
*
|
||||
* @param {Element} el
|
||||
* The element to add text content into
|
||||
*
|
||||
* @param {string} text
|
||||
* The text content to add.
|
||||
*
|
||||
* @return {Element}
|
||||
* The element with added text content.
|
||||
*/
|
||||
function textContent(el, text) {
|
||||
if (typeof el.textContent === 'undefined') {
|
||||
el.innerText = text;
|
||||
} else {
|
||||
el.textContent = text;
|
||||
}
|
||||
return el;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert an element as the first child node of another
|
||||
*
|
||||
* @param {Element} child
|
||||
* Element to insert
|
||||
*
|
||||
* @param {Element} parent
|
||||
* Element to insert child into
|
||||
*
|
||||
*/
|
||||
function insertElFirst(child, parent) {
|
||||
if (parent.firstChild) {
|
||||
parent.insertBefore(child, parent.firstChild);
|
||||
} else {
|
||||
parent.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Element Data Store. Allows for binding data to an element without putting it directly on the element.
|
||||
* Ex. Event listeners are stored here.
|
||||
* (also from jsninja.com, slightly modified and updated for closure compiler)
|
||||
*
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
var elData = {};
|
||||
|
||||
/*
|
||||
* Unique attribute name to store an element's guid in
|
||||
*
|
||||
* @type {string}
|
||||
* @constant
|
||||
* @private
|
||||
*/
|
||||
var elIdAttr = 'vdata' + new Date().getTime();
|
||||
|
||||
/**
|
||||
* Returns the cache object where data for an element is stored
|
||||
*
|
||||
* @param {Element} el
|
||||
* Element to store data for.
|
||||
*
|
||||
* @return {Object}
|
||||
* The cache object for that el that was passed in.
|
||||
*/
|
||||
function getElData(el) {
|
||||
var id = el[elIdAttr];
|
||||
|
||||
if (!id) {
|
||||
id = el[elIdAttr] = Guid.newGUID();
|
||||
}
|
||||
|
||||
if (!elData[id]) {
|
||||
elData[id] = {};
|
||||
}
|
||||
|
||||
return elData[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not an element has cached data
|
||||
*
|
||||
* @param {Element} el
|
||||
* Check if this element has cached data.
|
||||
*
|
||||
* @return {boolean}
|
||||
* - True if the DOM element has cached data.
|
||||
* - False otherwise.
|
||||
*/
|
||||
function hasElData(el) {
|
||||
var id = el[elIdAttr];
|
||||
|
||||
if (!id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!Object.getOwnPropertyNames(elData[id]).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete data for the element from the cache and the guid attr from getElementById
|
||||
*
|
||||
* @param {Element} el
|
||||
* Remove cached data for this element.
|
||||
*/
|
||||
function removeElData(el) {
|
||||
var id = el[elIdAttr];
|
||||
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove all stored data
|
||||
delete elData[id];
|
||||
|
||||
// Remove the elIdAttr property from the DOM node
|
||||
try {
|
||||
delete el[elIdAttr];
|
||||
} catch (e) {
|
||||
if (el.removeAttribute) {
|
||||
el.removeAttribute(elIdAttr);
|
||||
} else {
|
||||
// IE doesn't appear to support removeAttribute on the document element
|
||||
el[elIdAttr] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an element has a CSS class
|
||||
*
|
||||
* @param {Element} element
|
||||
* Element to check
|
||||
*
|
||||
* @param {string} classToCheck
|
||||
* Class name to check for
|
||||
*
|
||||
* @return {boolean}
|
||||
* - True if the element had the class
|
||||
* - False otherwise.
|
||||
*
|
||||
* @throws {Error}
|
||||
* Throws an error if `classToCheck` has white space.
|
||||
*/
|
||||
function hasElClass(element, classToCheck) {
|
||||
throwIfWhitespace(classToCheck);
|
||||
if (element.classList) {
|
||||
return element.classList.contains(classToCheck);
|
||||
}
|
||||
return classRegExp(classToCheck).test(element.className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a CSS class name to an element
|
||||
*
|
||||
* @param {Element} element
|
||||
* Element to add class name to.
|
||||
*
|
||||
* @param {string} classToAdd
|
||||
* Class name to add.
|
||||
*
|
||||
* @return {Element}
|
||||
* The dom element with the added class name.
|
||||
*/
|
||||
function addElClass(element, classToAdd) {
|
||||
if (element.classList) {
|
||||
element.classList.add(classToAdd);
|
||||
|
||||
// Don't need to `throwIfWhitespace` here because `hasElClass` will do it
|
||||
// in the case of classList not being supported.
|
||||
} else if (!hasElClass(element, classToAdd)) {
|
||||
element.className = (element.className + ' ' + classToAdd).trim();
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a CSS class name from an element
|
||||
*
|
||||
* @param {Element} element
|
||||
* Element to remove a class name from.
|
||||
*
|
||||
* @param {string} classToRemove
|
||||
* Class name to remove
|
||||
*
|
||||
* @return {Element}
|
||||
* The dom element with class name removed.
|
||||
*/
|
||||
function removeElClass(element, classToRemove) {
|
||||
if (element.classList) {
|
||||
element.classList.remove(classToRemove);
|
||||
} else {
|
||||
throwIfWhitespace(classToRemove);
|
||||
element.className = element.className.split(/\s+/).filter(function (c) {
|
||||
return c !== classToRemove;
|
||||
}).join(' ');
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* The callback definition for toggleElClass.
|
||||
*
|
||||
* @callback Dom~PredicateCallback
|
||||
* @param {Element} element
|
||||
* The DOM element of the Component.
|
||||
*
|
||||
* @param {string} classToToggle
|
||||
* The `className` that wants to be toggled
|
||||
*
|
||||
* @return {boolean|undefined}
|
||||
* - If true the `classToToggle` will get added to `element`.
|
||||
* - If false the `classToToggle` will get removed from `element`.
|
||||
* - If undefined this callback will be ignored
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds or removes a CSS class name on an element depending on an optional
|
||||
* condition or the presence/absence of the class name.
|
||||
*
|
||||
* @param {Element} element
|
||||
* The element to toggle a class name on.
|
||||
*
|
||||
* @param {string} classToToggle
|
||||
* The class that should be toggled
|
||||
*
|
||||
* @param {boolean|PredicateCallback} [predicate]
|
||||
* See the return value for {@link Dom~PredicateCallback}
|
||||
*
|
||||
* @return {Element}
|
||||
* The element with a class that has been toggled.
|
||||
*/
|
||||
function toggleElClass(element, classToToggle, predicate) {
|
||||
|
||||
// This CANNOT use `classList` internally because IE does not support the
|
||||
// second parameter to the `classList.toggle()` method! Which is fine because
|
||||
// `classList` will be used by the add/remove functions.
|
||||
var has = hasElClass(element, classToToggle);
|
||||
|
||||
if (typeof predicate === 'function') {
|
||||
predicate = predicate(element, classToToggle);
|
||||
}
|
||||
|
||||
if (typeof predicate !== 'boolean') {
|
||||
predicate = !has;
|
||||
}
|
||||
|
||||
// If the necessary class operation matches the current state of the
|
||||
// element, no action is required.
|
||||
if (predicate === has) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (predicate) {
|
||||
addElClass(element, classToToggle);
|
||||
} else {
|
||||
removeElClass(element, classToToggle);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply attributes to an HTML element.
|
||||
*
|
||||
* @param {Element} el
|
||||
* Element to add attributes to.
|
||||
*
|
||||
* @param {Object} [attributes]
|
||||
* Attributes to be applied.
|
||||
*/
|
||||
function setElAttributes(el, attributes) {
|
||||
Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
|
||||
var attrValue = attributes[attrName];
|
||||
|
||||
if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
|
||||
el.removeAttribute(attrName);
|
||||
} else {
|
||||
el.setAttribute(attrName, attrValue === true ? '' : attrValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an element's attribute values, as defined on the HTML tag
|
||||
* Attributes are not the same as properties. They're defined on the tag
|
||||
* or with setAttribute (which shouldn't be used with HTML)
|
||||
* This will return true or false for boolean attributes.
|
||||
*
|
||||
* @param {Element} tag
|
||||
* Element from which to get tag attributes.
|
||||
*
|
||||
* @return {Object}
|
||||
* All attributes of the element.
|
||||
*/
|
||||
function getElAttributes(tag) {
|
||||
var obj = {};
|
||||
|
||||
// known boolean attributes
|
||||
// we can check for matching boolean properties, but older browsers
|
||||
// won't know about HTML5 boolean attributes that we still read from
|
||||
var knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ',';
|
||||
|
||||
if (tag && tag.attributes && tag.attributes.length > 0) {
|
||||
var attrs = tag.attributes;
|
||||
|
||||
for (var i = attrs.length - 1; i >= 0; i--) {
|
||||
var attrName = attrs[i].name;
|
||||
var attrVal = attrs[i].value;
|
||||
|
||||
// check for known booleans
|
||||
// the matching element property will return a value for typeof
|
||||
if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {
|
||||
// the value of an included boolean attribute is typically an empty
|
||||
// string ('') which would equal false if we just check for a false value.
|
||||
// we also don't want support bad code like autoplay='false'
|
||||
attrVal = attrVal !== null ? true : false;
|
||||
}
|
||||
|
||||
obj[attrName] = attrVal;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of an element's attribute
|
||||
*
|
||||
* @param {Element} el
|
||||
* A DOM element
|
||||
*
|
||||
* @param {string} attribute
|
||||
* Attribute to get the value of
|
||||
*
|
||||
* @return {string}
|
||||
* value of the attribute
|
||||
*/
|
||||
function getAttribute(el, attribute) {
|
||||
return el.getAttribute(attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of an element's attribute
|
||||
*
|
||||
* @param {Element} el
|
||||
* A DOM element
|
||||
*
|
||||
* @param {string} attribute
|
||||
* Attribute to set
|
||||
*
|
||||
* @param {string} value
|
||||
* Value to set the attribute to
|
||||
*/
|
||||
function setAttribute(el, attribute, value) {
|
||||
el.setAttribute(attribute, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an element's attribute
|
||||
*
|
||||
* @param {Element} el
|
||||
* A DOM element
|
||||
*
|
||||
* @param {string} attribute
|
||||
* Attribute to remove
|
||||
*/
|
||||
function removeAttribute(el, attribute) {
|
||||
el.removeAttribute(attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to block the ability to select text while dragging controls
|
||||
*/
|
||||
function blockTextSelection() {
|
||||
_document2['default'].body.focus();
|
||||
_document2['default'].onselectstart = function () {
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn off text selection blocking
|
||||
*/
|
||||
function unblockTextSelection() {
|
||||
_document2['default'].onselectstart = function () {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The postion of a DOM element on the page.
|
||||
*
|
||||
* @typedef {Object} Dom~Position
|
||||
*
|
||||
* @property {number} left
|
||||
* Pixels to the left
|
||||
*
|
||||
* @property {number} top
|
||||
* Pixels on top
|
||||
*/
|
||||
|
||||
/**
|
||||
* Offset Left.
|
||||
* getBoundingClientRect technique from
|
||||
* John Resig
|
||||
*
|
||||
* @see http://ejohn.org/blog/getboundingclientrect-is-awesome/
|
||||
*
|
||||
* @param {Element} el
|
||||
* Element from which to get offset
|
||||
*
|
||||
* @return {Dom~Position}
|
||||
* The position of the element that was passed in.
|
||||
*/
|
||||
function findElPosition(el) {
|
||||
var box = void 0;
|
||||
|
||||
if (el.getBoundingClientRect && el.parentNode) {
|
||||
box = el.getBoundingClientRect();
|
||||
}
|
||||
|
||||
if (!box) {
|
||||
return {
|
||||
left: 0,
|
||||
top: 0
|
||||
};
|
||||
}
|
||||
|
||||
var docEl = _document2['default'].documentElement;
|
||||
var body = _document2['default'].body;
|
||||
|
||||
var clientLeft = docEl.clientLeft || body.clientLeft || 0;
|
||||
var scrollLeft = _window2['default'].pageXOffset || body.scrollLeft;
|
||||
var left = box.left + scrollLeft - clientLeft;
|
||||
|
||||
var clientTop = docEl.clientTop || body.clientTop || 0;
|
||||
var scrollTop = _window2['default'].pageYOffset || body.scrollTop;
|
||||
var top = box.top + scrollTop - clientTop;
|
||||
|
||||
// Android sometimes returns slightly off decimal values, so need to round
|
||||
return {
|
||||
left: Math.round(left),
|
||||
top: Math.round(top)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* x and y coordinates for a dom element or mouse pointer
|
||||
*
|
||||
* @typedef {Object} Dom~Coordinates
|
||||
*
|
||||
* @property {number} x
|
||||
* x coordinate in pixels
|
||||
*
|
||||
* @property {number} y
|
||||
* y coordinate in pixels
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get pointer position in element
|
||||
* Returns an object with x and y coordinates.
|
||||
* The base on the coordinates are the bottom left of the element.
|
||||
*
|
||||
* @param {Element} el
|
||||
* Element on which to get the pointer position on
|
||||
*
|
||||
* @param {EventTarget~Event} event
|
||||
* Event object
|
||||
*
|
||||
* @return {Dom~Coordinates}
|
||||
* A Coordinates object corresponding to the mouse position.
|
||||
*
|
||||
*/
|
||||
function getPointerPosition(el, event) {
|
||||
var position = {};
|
||||
var box = findElPosition(el);
|
||||
var boxW = el.offsetWidth;
|
||||
var boxH = el.offsetHeight;
|
||||
|
||||
var boxY = box.top;
|
||||
var boxX = box.left;
|
||||
var pageY = event.pageY;
|
||||
var pageX = event.pageX;
|
||||
|
||||
if (event.changedTouches) {
|
||||
pageX = event.changedTouches[0].pageX;
|
||||
pageY = event.changedTouches[0].pageY;
|
||||
}
|
||||
|
||||
position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH));
|
||||
position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines, via duck typing, whether or not a value is a text node.
|
||||
*
|
||||
* @param {Mixed} value
|
||||
* Check if this value is a text node.
|
||||
*
|
||||
* @return {boolean}
|
||||
* - True if it is a text node
|
||||
* - False otherwise
|
||||
*/
|
||||
function isTextNode(value) {
|
||||
return (0, _obj.isObject)(value) && value.nodeType === 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties the contents of an element.
|
||||
*
|
||||
* @param {Element} el
|
||||
* The element to empty children from
|
||||
*
|
||||
* @return {Element}
|
||||
* The element with no children
|
||||
*/
|
||||
function emptyEl(el) {
|
||||
while (el.firstChild) {
|
||||
el.removeChild(el.firstChild);
|
||||
}
|
||||
return el;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes content for eventual insertion into the DOM.
|
||||
*
|
||||
* This allows a wide range of content definition methods, but protects
|
||||
* from falling into the trap of simply writing to `innerHTML`, which is
|
||||
* an XSS concern.
|
||||
*
|
||||
* The content for an element can be passed in multiple types and
|
||||
* combinations, whose behavior is as follows:
|
||||
*
|
||||
* @param {String|Element|TextNode|Array|Function} content
|
||||
* - String: Normalized into a text node.
|
||||
* - Element/TextNode: Passed through.
|
||||
* - Array: A one-dimensional array of strings, elements, nodes, or functions
|
||||
* (which return single strings, elements, or nodes).
|
||||
* - Function: If the sole argument, is expected to produce a string, element,
|
||||
* node, or array as defined above.
|
||||
*
|
||||
* @return {Array}
|
||||
* All of the content that was passed in normalized.
|
||||
*/
|
||||
function normalizeContent(content) {
|
||||
|
||||
// First, invoke content if it is a function. If it produces an array,
|
||||
// that needs to happen before normalization.
|
||||
if (typeof content === 'function') {
|
||||
content = content();
|
||||
}
|
||||
|
||||
// Next up, normalize to an array, so one or many items can be normalized,
|
||||
// filtered, and returned.
|
||||
return (Array.isArray(content) ? content : [content]).map(function (value) {
|
||||
|
||||
// First, invoke value if it is a function to produce a new value,
|
||||
// which will be subsequently normalized to a Node of some kind.
|
||||
if (typeof value === 'function') {
|
||||
value = value();
|
||||
}
|
||||
|
||||
if (isEl(value) || isTextNode(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (typeof value === 'string' && /\S/.test(value)) {
|
||||
return _document2['default'].createTextNode(value);
|
||||
}
|
||||
}).filter(function (value) {
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes and appends content to an element.
|
||||
*
|
||||
* @param {Element} el
|
||||
* Element to append normalized content to.
|
||||
*
|
||||
*
|
||||
* @param {String|Element|TextNode|Array|Function} content
|
||||
* See the `content` argument of {@link dom:normalizeContent}
|
||||
*
|
||||
* @return {Element}
|
||||
* The element with appended normalized content.
|
||||
*/
|
||||
function appendContent(el, content) {
|
||||
normalizeContent(content).forEach(function (node) {
|
||||
return el.appendChild(node);
|
||||
});
|
||||
return el;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes and inserts content into an element; this is identical to
|
||||
* `appendContent()`, except it empties the element first.
|
||||
*
|
||||
* @param {Element} el
|
||||
* Element to insert normalized content into.
|
||||
*
|
||||
* @param {String|Element|TextNode|Array|Function} content
|
||||
* See the `content` argument of {@link dom:normalizeContent}
|
||||
*
|
||||
* @return {Element}
|
||||
* The element with inserted normalized content.
|
||||
*
|
||||
*/
|
||||
function insertContent(el, content) {
|
||||
return appendContent(emptyEl(el), content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a single DOM element matching `selector` within the optional
|
||||
* `context` of another DOM element (defaulting to `document`).
|
||||
*
|
||||
* @param {string} selector
|
||||
* A valid CSS selector, which will be passed to `querySelector`.
|
||||
*
|
||||
* @param {Element|String} [context=document]
|
||||
* A DOM element within which to query. Can also be a selector
|
||||
* string in which case the first matching element will be used
|
||||
* as context. If missing (or no element matches selector), falls
|
||||
* back to `document`.
|
||||
*
|
||||
* @return {Element|null}
|
||||
* The element that was found or null.
|
||||
*/
|
||||
var $ = exports.$ = createQuerier('querySelector');
|
||||
|
||||
/**
|
||||
* Finds a all DOM elements matching `selector` within the optional
|
||||
* `context` of another DOM element (defaulting to `document`).
|
||||
*
|
||||
* @param {string} selector
|
||||
* A valid CSS selector, which will be passed to `querySelectorAll`.
|
||||
*
|
||||
* @param {Element|String} [context=document]
|
||||
* A DOM element within which to query. Can also be a selector
|
||||
* string in which case the first matching element will be used
|
||||
* as context. If missing (or no element matches selector), falls
|
||||
* back to `document`.
|
||||
*
|
||||
* @return {NodeList}
|
||||
* A element list of elements that were found. Will be empty if none were found.
|
||||
*
|
||||
*/
|
||||
var $$ = exports.$$ = createQuerier('querySelectorAll');
|
||||
@@ -0,0 +1,459 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
exports.fixEvent = fixEvent;
|
||||
exports.on = on;
|
||||
exports.off = off;
|
||||
exports.trigger = trigger;
|
||||
exports.one = one;
|
||||
|
||||
var _dom = require('./dom.js');
|
||||
|
||||
var Dom = _interopRequireWildcard(_dom);
|
||||
|
||||
var _guid = require('./guid.js');
|
||||
|
||||
var Guid = _interopRequireWildcard(_guid);
|
||||
|
||||
var _log = require('./log.js');
|
||||
|
||||
var _log2 = _interopRequireDefault(_log);
|
||||
|
||||
var _window = require('global/window');
|
||||
|
||||
var _window2 = _interopRequireDefault(_window);
|
||||
|
||||
var _document = require('global/document');
|
||||
|
||||
var _document2 = _interopRequireDefault(_document);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
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; } }
|
||||
|
||||
/**
|
||||
* Clean up the listener cache and dispatchers
|
||||
*
|
||||
* @param {Element|Object} elem
|
||||
* Element to clean up
|
||||
*
|
||||
* @param {string} type
|
||||
* Type of event to clean up
|
||||
*/
|
||||
function _cleanUpEvents(elem, type) {
|
||||
var data = Dom.getElData(elem);
|
||||
|
||||
// Remove the events of a particular type if there are none left
|
||||
if (data.handlers[type].length === 0) {
|
||||
delete data.handlers[type];
|
||||
// data.handlers[type] = null;
|
||||
// Setting to null was causing an error with data.handlers
|
||||
|
||||
// Remove the meta-handler from the element
|
||||
if (elem.removeEventListener) {
|
||||
elem.removeEventListener(type, data.dispatcher, false);
|
||||
} else if (elem.detachEvent) {
|
||||
elem.detachEvent('on' + type, data.dispatcher);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the events object if there are no types left
|
||||
if (Object.getOwnPropertyNames(data.handlers).length <= 0) {
|
||||
delete data.handlers;
|
||||
delete data.dispatcher;
|
||||
delete data.disabled;
|
||||
}
|
||||
|
||||
// Finally remove the element data if there is no data left
|
||||
if (Object.getOwnPropertyNames(data).length === 0) {
|
||||
Dom.removeElData(elem);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops through an array of event types and calls the requested method for each type.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* The event method we want to use.
|
||||
*
|
||||
* @param {Element|Object} elem
|
||||
* Element or object to bind listeners to
|
||||
*
|
||||
* @param {string} type
|
||||
* Type of event to bind to.
|
||||
*
|
||||
* @param {EventTarget~EventListener} callback
|
||||
* Event listener.
|
||||
*/
|
||||
/**
|
||||
* @file events.js. An Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/)
|
||||
* (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible)
|
||||
* This should work very similarly to jQuery's events, however it's based off the book version which isn't as
|
||||
* robust as jquery's, so there's probably some differences.
|
||||
*
|
||||
* @module events
|
||||
*/
|
||||
|
||||
function _handleMultipleEvents(fn, elem, types, callback) {
|
||||
types.forEach(function (type) {
|
||||
// Call the event method for each one of the types
|
||||
fn(elem, type, callback);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix a native event to have standard property values
|
||||
*
|
||||
* @param {Object} event
|
||||
* Event object to fix.
|
||||
*
|
||||
* @return {Object}
|
||||
* Fixed event object.
|
||||
*/
|
||||
function fixEvent(event) {
|
||||
|
||||
function returnTrue() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function returnFalse() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test if fixing up is needed
|
||||
// Used to check if !event.stopPropagation instead of isPropagationStopped
|
||||
// But native events return true for stopPropagation, but don't have
|
||||
// other expected methods like isPropagationStopped. Seems to be a problem
|
||||
// with the Javascript Ninja code. So we're just overriding all events now.
|
||||
if (!event || !event.isPropagationStopped) {
|
||||
(function () {
|
||||
var old = event || _window2['default'].event;
|
||||
|
||||
event = {};
|
||||
// Clone the old object so that we can modify the values event = {};
|
||||
// IE8 Doesn't like when you mess with native event properties
|
||||
// Firefox returns false for event.hasOwnProperty('type') and other props
|
||||
// which makes copying more difficult.
|
||||
// TODO: Probably best to create a whitelist of event props
|
||||
for (var key in old) {
|
||||
// Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
|
||||
// Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation
|
||||
// and webkitMovementX/Y
|
||||
if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') {
|
||||
// Chrome 32+ warns if you try to copy deprecated returnValue, but
|
||||
// we still want to if preventDefault isn't supported (IE8).
|
||||
if (!(key === 'returnValue' && old.preventDefault)) {
|
||||
event[key] = old[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The event occurred on this element
|
||||
if (!event.target) {
|
||||
event.target = event.srcElement || _document2['default'];
|
||||
}
|
||||
|
||||
// Handle which other element the event is related to
|
||||
if (!event.relatedTarget) {
|
||||
event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
|
||||
}
|
||||
|
||||
// Stop the default browser action
|
||||
event.preventDefault = function () {
|
||||
if (old.preventDefault) {
|
||||
old.preventDefault();
|
||||
}
|
||||
event.returnValue = false;
|
||||
old.returnValue = false;
|
||||
event.defaultPrevented = true;
|
||||
};
|
||||
|
||||
event.defaultPrevented = false;
|
||||
|
||||
// Stop the event from bubbling
|
||||
event.stopPropagation = function () {
|
||||
if (old.stopPropagation) {
|
||||
old.stopPropagation();
|
||||
}
|
||||
event.cancelBubble = true;
|
||||
old.cancelBubble = true;
|
||||
event.isPropagationStopped = returnTrue;
|
||||
};
|
||||
|
||||
event.isPropagationStopped = returnFalse;
|
||||
|
||||
// Stop the event from bubbling and executing other handlers
|
||||
event.stopImmediatePropagation = function () {
|
||||
if (old.stopImmediatePropagation) {
|
||||
old.stopImmediatePropagation();
|
||||
}
|
||||
event.isImmediatePropagationStopped = returnTrue;
|
||||
event.stopPropagation();
|
||||
};
|
||||
|
||||
event.isImmediatePropagationStopped = returnFalse;
|
||||
|
||||
// Handle mouse position
|
||||
if (event.clientX !== null && event.clientX !== undefined) {
|
||||
var doc = _document2['default'].documentElement;
|
||||
var body = _document2['default'].body;
|
||||
|
||||
event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
|
||||
event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
|
||||
}
|
||||
|
||||
// Handle key presses
|
||||
event.which = event.charCode || event.keyCode;
|
||||
|
||||
// Fix button for mouse clicks:
|
||||
// 0 == left; 1 == middle; 2 == right
|
||||
if (event.button !== null && event.button !== undefined) {
|
||||
|
||||
// The following is disabled because it does not pass videojs-standard
|
||||
// and... yikes.
|
||||
/* eslint-disable */
|
||||
event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0;
|
||||
/* eslint-enable */
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
// Returns fixed-up instance
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an event listener to element
|
||||
* It stores the handler function in a separate cache object
|
||||
* and adds a generic handler to the element's event,
|
||||
* along with a unique id (guid) to the element.
|
||||
*
|
||||
* @param {Element|Object} elem
|
||||
* Element or object to bind listeners to
|
||||
*
|
||||
* @param {string|string[]} type
|
||||
* Type of event to bind to.
|
||||
*
|
||||
* @param {EventTarget~EventListener} fn
|
||||
* Event listener.
|
||||
*/
|
||||
function on(elem, type, fn) {
|
||||
if (Array.isArray(type)) {
|
||||
return _handleMultipleEvents(on, elem, type, fn);
|
||||
}
|
||||
|
||||
var data = Dom.getElData(elem);
|
||||
|
||||
// We need a place to store all our handler data
|
||||
if (!data.handlers) {
|
||||
data.handlers = {};
|
||||
}
|
||||
|
||||
if (!data.handlers[type]) {
|
||||
data.handlers[type] = [];
|
||||
}
|
||||
|
||||
if (!fn.guid) {
|
||||
fn.guid = Guid.newGUID();
|
||||
}
|
||||
|
||||
data.handlers[type].push(fn);
|
||||
|
||||
if (!data.dispatcher) {
|
||||
data.disabled = false;
|
||||
|
||||
data.dispatcher = function (event, hash) {
|
||||
|
||||
if (data.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
event = fixEvent(event);
|
||||
|
||||
var handlers = data.handlers[event.type];
|
||||
|
||||
if (handlers) {
|
||||
// Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.
|
||||
var handlersCopy = handlers.slice(0);
|
||||
|
||||
for (var m = 0, n = handlersCopy.length; m < n; m++) {
|
||||
if (event.isImmediatePropagationStopped()) {
|
||||
break;
|
||||
} else {
|
||||
try {
|
||||
handlersCopy[m].call(elem, event, hash);
|
||||
} catch (e) {
|
||||
_log2['default'].error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (data.handlers[type].length === 1) {
|
||||
if (elem.addEventListener) {
|
||||
elem.addEventListener(type, data.dispatcher, false);
|
||||
} else if (elem.attachEvent) {
|
||||
elem.attachEvent('on' + type, data.dispatcher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes event listeners from an element
|
||||
*
|
||||
* @param {Element|Object} elem
|
||||
* Object to remove listeners from.
|
||||
*
|
||||
* @param {string|string[]} [type]
|
||||
* Type of listener to remove. Don't include to remove all events from element.
|
||||
*
|
||||
* @param {EventTarget~EventListener} [fn]
|
||||
* Specific listener to remove. Don't include to remove listeners for an event
|
||||
* type.
|
||||
*/
|
||||
function off(elem, type, fn) {
|
||||
// Don't want to add a cache object through getElData if not needed
|
||||
if (!Dom.hasElData(elem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var data = Dom.getElData(elem);
|
||||
|
||||
// If no events exist, nothing to unbind
|
||||
if (!data.handlers) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(type)) {
|
||||
return _handleMultipleEvents(off, elem, type, fn);
|
||||
}
|
||||
|
||||
// Utility function
|
||||
var removeType = function removeType(t) {
|
||||
data.handlers[t] = [];
|
||||
_cleanUpEvents(elem, t);
|
||||
};
|
||||
|
||||
// Are we removing all bound events?
|
||||
if (!type) {
|
||||
for (var t in data.handlers) {
|
||||
removeType(t);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var handlers = data.handlers[type];
|
||||
|
||||
// If no handlers exist, nothing to unbind
|
||||
if (!handlers) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If no listener was provided, remove all listeners for type
|
||||
if (!fn) {
|
||||
removeType(type);
|
||||
return;
|
||||
}
|
||||
|
||||
// We're only removing a single handler
|
||||
if (fn.guid) {
|
||||
for (var n = 0; n < handlers.length; n++) {
|
||||
if (handlers[n].guid === fn.guid) {
|
||||
handlers.splice(n--, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_cleanUpEvents(elem, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger an event for an element
|
||||
*
|
||||
* @param {Element|Object} elem
|
||||
* Element to trigger an event on
|
||||
*
|
||||
* @param {EventTarget~Event|string} event
|
||||
* A string (the type) or an event object with a type attribute
|
||||
*
|
||||
* @param {Object} [hash]
|
||||
* data hash to pass along with the event
|
||||
*
|
||||
* @return {boolean|undefined}
|
||||
* - Returns the opposite of `defaultPrevented` if default was prevented
|
||||
* - Otherwise returns undefined
|
||||
*/
|
||||
function trigger(elem, event, hash) {
|
||||
// Fetches element data and a reference to the parent (for bubbling).
|
||||
// Don't want to add a data object to cache for every parent,
|
||||
// so checking hasElData first.
|
||||
var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {};
|
||||
var parent = elem.parentNode || elem.ownerDocument;
|
||||
// type = event.type || event,
|
||||
// handler;
|
||||
|
||||
// If an event name was passed as a string, creates an event out of it
|
||||
if (typeof event === 'string') {
|
||||
event = { type: event, target: elem };
|
||||
}
|
||||
// Normalizes the event properties.
|
||||
event = fixEvent(event);
|
||||
|
||||
// If the passed element has a dispatcher, executes the established handlers.
|
||||
if (elemData.dispatcher) {
|
||||
elemData.dispatcher.call(elem, event, hash);
|
||||
}
|
||||
|
||||
// Unless explicitly stopped or the event does not bubble (e.g. media events)
|
||||
// recursively calls this function to bubble the event up the DOM.
|
||||
if (parent && !event.isPropagationStopped() && event.bubbles === true) {
|
||||
trigger.call(null, parent, event, hash);
|
||||
|
||||
// If at the top of the DOM, triggers the default action unless disabled.
|
||||
} else if (!parent && !event.defaultPrevented) {
|
||||
var targetData = Dom.getElData(event.target);
|
||||
|
||||
// Checks if the target has a default action for this event.
|
||||
if (event.target[event.type]) {
|
||||
// Temporarily disables event dispatching on the target as we have already executed the handler.
|
||||
targetData.disabled = true;
|
||||
// Executes the default action.
|
||||
if (typeof event.target[event.type] === 'function') {
|
||||
event.target[event.type]();
|
||||
}
|
||||
// Re-enables event dispatching.
|
||||
targetData.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Inform the triggerer if the default was prevented by returning false
|
||||
return !event.defaultPrevented;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a listener only once for an event
|
||||
*
|
||||
* @param {Element|Object} elem
|
||||
* Element or object to bind to.
|
||||
*
|
||||
* @param {string|string[]} type
|
||||
* Name/type of event
|
||||
*
|
||||
* @param {Event~EventListener} fn
|
||||
* Event Listener function
|
||||
*/
|
||||
function one(elem, type, fn) {
|
||||
if (Array.isArray(type)) {
|
||||
return _handleMultipleEvents(one, elem, type, fn);
|
||||
}
|
||||
var func = function func() {
|
||||
off(elem, type, func);
|
||||
fn.apply(this, arguments);
|
||||
};
|
||||
|
||||
// copy the guid to the new function so it can removed using the original function's ID
|
||||
func.guid = fn.guid = fn.guid || Guid.newGUID();
|
||||
on(elem, type, func);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
exports.throttle = exports.bind = undefined;
|
||||
|
||||
var _guid = require('./guid.js');
|
||||
|
||||
/**
|
||||
* Bind (a.k.a proxy or Context). A simple method for changing the context of a function
|
||||
* It also stores a unique id on the function so it can be easily removed from events.
|
||||
*
|
||||
* @param {Mixed} context
|
||||
* The object to bind as scope.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* The function to be bound to a scope.
|
||||
*
|
||||
* @param {number} [uid]
|
||||
* An optional unique ID for the function to be set
|
||||
*
|
||||
* @return {Function}
|
||||
* The new function that will be bound into the context given
|
||||
*/
|
||||
var bind = exports.bind = function bind(context, fn, uid) {
|
||||
// Make sure the function has a unique ID
|
||||
if (!fn.guid) {
|
||||
fn.guid = (0, _guid.newGUID)();
|
||||
}
|
||||
|
||||
// Create the new function that changes the context
|
||||
var bound = function bound() {
|
||||
return fn.apply(context, arguments);
|
||||
};
|
||||
|
||||
// Allow for the ability to individualize this function
|
||||
// Needed in the case where multiple objects might share the same prototype
|
||||
// IF both items add an event listener with the same function, then you try to remove just one
|
||||
// it will remove both because they both have the same guid.
|
||||
// when using this, you need to use the bind method when you remove the listener as well.
|
||||
// currently used in text tracks
|
||||
bound.guid = uid ? uid + '_' + fn.guid : fn.guid;
|
||||
|
||||
return bound;
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps the given function, `fn`, with a new function that only invokes `fn`
|
||||
* at most once per every `wait` milliseconds.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* The function to be throttled.
|
||||
*
|
||||
* @param {Number} wait
|
||||
* The number of milliseconds by which to throttle.
|
||||
*
|
||||
* @return {Function}
|
||||
*/
|
||||
/**
|
||||
* @file fn.js
|
||||
* @module fn
|
||||
*/
|
||||
var throttle = exports.throttle = function throttle(fn, wait) {
|
||||
var last = Date.now();
|
||||
|
||||
var throttled = function throttled() {
|
||||
var now = Date.now();
|
||||
|
||||
if (now - last >= wait) {
|
||||
fn.apply(undefined, arguments);
|
||||
last = now;
|
||||
}
|
||||
};
|
||||
|
||||
return throttled;
|
||||
};
|
||||
@@ -0,0 +1,52 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
/**
|
||||
* @file format-time.js
|
||||
* @module Format-time
|
||||
*/
|
||||
|
||||
/**
|
||||
* Format seconds as a time string, H:MM:SS or M:SS. Supplying a guide (in seconds)
|
||||
* will force a number of leading zeros to cover the length of the guide.
|
||||
*
|
||||
* @param {number} seconds
|
||||
* Number of seconds to be turned into a string
|
||||
*
|
||||
* @param {number} guide
|
||||
* Number (in seconds) to model the string after
|
||||
*
|
||||
* @return {string}
|
||||
* Time formatted as H:MM:SS or M:SS
|
||||
*/
|
||||
function formatTime(seconds) {
|
||||
var guide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : seconds;
|
||||
|
||||
seconds = seconds < 0 ? 0 : seconds;
|
||||
var s = Math.floor(seconds % 60);
|
||||
var m = Math.floor(seconds / 60 % 60);
|
||||
var h = Math.floor(seconds / 3600);
|
||||
var gm = Math.floor(guide / 60 % 60);
|
||||
var gh = Math.floor(guide / 3600);
|
||||
|
||||
// handle invalid times
|
||||
if (isNaN(seconds) || seconds === Infinity) {
|
||||
// '-' is false for all relational operators (e.g. <, >=) so this setting
|
||||
// will add the minimum number of fields specified by the guide
|
||||
h = m = s = '-';
|
||||
}
|
||||
|
||||
// Check if we need to show hours
|
||||
h = h > 0 || gh > 0 ? h + ':' : '';
|
||||
|
||||
// If hours are showing, we may need to add a leading zero.
|
||||
// Always show at least one digit of minutes.
|
||||
m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':';
|
||||
|
||||
// Check if leading zero is need for seconds
|
||||
s = s < 10 ? '0' + s : s;
|
||||
|
||||
return h + m + s;
|
||||
}
|
||||
|
||||
exports['default'] = formatTime;
|
||||
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
|
||||
exports.__esModule = true;
|
||||
exports.newGUID = newGUID;
|
||||
/**
|
||||
* @file guid.js
|
||||
* @module guid
|
||||
*/
|
||||
|
||||
/**
|
||||
* Unique ID for an element or function
|
||||
* @type {Number}
|
||||
*/
|
||||
var _guid = 1;
|
||||
|
||||
/**
|
||||
* Get a unique auto-incrementing ID by number that has not been returned before.
|
||||
*
|
||||
* @return {number}
|
||||
* A new unique ID.
|
||||
*/
|
||||
function newGUID() {
|
||||
return _guid++;
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
exports.logByType = undefined;
|
||||
|
||||
var _window = require('global/window');
|
||||
|
||||
var _window2 = _interopRequireDefault(_window);
|
||||
|
||||
var _browser = require('./browser');
|
||||
|
||||
var _obj = require('./obj');
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||
|
||||
var log = void 0;
|
||||
|
||||
/**
|
||||
* Log messages to the console and history based on the type of message
|
||||
*
|
||||
* @param {string} type
|
||||
* The name of the console method to use.
|
||||
*
|
||||
* @param {Array} args
|
||||
* The arguments to be passed to the matching console method.
|
||||
*
|
||||
* @param {boolean} [stringify]
|
||||
* By default, only old IEs should get console argument stringification,
|
||||
* but this is exposed as a parameter to facilitate testing.
|
||||
*/
|
||||
/**
|
||||
* @file log.js
|
||||
* @module log
|
||||
*/
|
||||
var logByType = exports.logByType = function logByType(type, args) {
|
||||
var stringify = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : !!_browser.IE_VERSION && _browser.IE_VERSION < 11;
|
||||
|
||||
|
||||
if (type !== 'log') {
|
||||
|
||||
// add the type to the front of the message when it's not "log"
|
||||
args.unshift(type.toUpperCase() + ':');
|
||||
}
|
||||
|
||||
// add to history
|
||||
log.history.push(args);
|
||||
|
||||
// add console prefix after adding to history
|
||||
args.unshift('VIDEOJS:');
|
||||
|
||||
// If there's no console then don't try to output messages, but they will
|
||||
// still be stored in `log.history`.
|
||||
//
|
||||
// Was setting these once outside of this function, but containing them
|
||||
// in the function makes it easier to test cases where console doesn't exist
|
||||
// when the module is executed.
|
||||
var fn = _window2['default'].console && _window2['default'].console[type];
|
||||
|
||||
// Bail out if there's no console.
|
||||
if (!fn) {
|
||||
return;
|
||||
}
|
||||
|
||||
// IEs previous to 11 log objects uselessly as "[object Object]"; so, JSONify
|
||||
// objects and arrays for those less-capable browsers.
|
||||
if (stringify) {
|
||||
args = args.map(function (a) {
|
||||
if ((0, _obj.isObject)(a) || Array.isArray(a)) {
|
||||
try {
|
||||
return JSON.stringify(a);
|
||||
} catch (x) {
|
||||
return String(a);
|
||||
}
|
||||
}
|
||||
|
||||
// Cast to string before joining, so we get null and undefined explicitly
|
||||
// included in output (as we would in a modern console).
|
||||
return String(a);
|
||||
}).join(' ');
|
||||
}
|
||||
|
||||
// Old IE versions do not allow .apply() for console methods (they are
|
||||
// reported as objects rather than functions).
|
||||
if (!fn.apply) {
|
||||
fn(args);
|
||||
} else {
|
||||
fn[Array.isArray(args) ? 'apply' : 'call'](_window2['default'].console, args);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Log plain debug messages
|
||||
*
|
||||
* @param {Mixed[]} args
|
||||
* One or more messages or objects that should be logged.
|
||||
*/
|
||||
log = function log() {
|
||||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
||||
args[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
logByType('log', args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Keep a history of log messages
|
||||
*
|
||||
* @type {Array}
|
||||
*/
|
||||
log.history = [];
|
||||
|
||||
/**
|
||||
* Log error messages
|
||||
*
|
||||
* @param {Mixed[]} args
|
||||
* One or more messages or objects that should be logged as an error
|
||||
*/
|
||||
log.error = function () {
|
||||
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
||||
args[_key2] = arguments[_key2];
|
||||
}
|
||||
|
||||
return logByType('error', args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Log warning messages
|
||||
*
|
||||
* @param {Mixed[]} args
|
||||
* One or more messages or objects that should be logged as a warning.
|
||||
*/
|
||||
log.warn = function () {
|
||||
for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
||||
args[_key3] = arguments[_key3];
|
||||
}
|
||||
|
||||
return logByType('warn', args);
|
||||
};
|
||||
|
||||
exports['default'] = log;
|
||||
@@ -0,0 +1,48 @@
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
exports['default'] = mergeOptions;
|
||||
|
||||
var _obj = require('./obj');
|
||||
|
||||
/**
|
||||
* Deep-merge one or more options objects, recursively merging **only** plain
|
||||
* object properties.
|
||||
*
|
||||
* @param {Object[]} sources
|
||||
* One or more objects to merge into a new object.
|
||||
*
|
||||
* @returns {Object}
|
||||
* A new object that is the merged result of all sources.
|
||||
*/
|
||||
function mergeOptions() {
|
||||
var result = {};
|
||||
|
||||
for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {
|
||||
sources[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
sources.forEach(function (source) {
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
(0, _obj.each)(source, function (value, key) {
|
||||
if (!(0, _obj.isPlain)(value)) {
|
||||
result[key] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(0, _obj.isPlain)(result[key])) {
|
||||
result[key] = {};
|
||||
}
|
||||
|
||||
result[key] = mergeOptions(result[key], value);
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
} /**
|
||||
* @file merge-options.js
|
||||
* @module merge-options
|
||||
*/
|
||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário