1
0
mirror of https://github.com/videojs/video.js.git synced 2025-03-17 21:18:27 +02:00

Merge branch 'master' into review-eXon-feature/watchify

Conflicts:
	Gruntfile.js
This commit is contained in:
heff 2015-04-30 11:44:57 -07:00
commit 476b8a4cf8
114 changed files with 2014 additions and 1977 deletions

4
.gitignore vendored
View File

@ -1,5 +1,4 @@
.DS_Store
dist/*
build/files/*
build/temp/*
docs/api/*
@ -26,3 +25,6 @@ sandbox/*
test/coverage/*
.coveralls.yml
.sass-cache
dist/*

View File

@ -1,6 +1,6 @@
language: node_js
node_js:
- 0.10
- "iojs"
before_script:
- if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then curl https://gist.githubusercontent.com/santiycr/5139565/raw/sauce_connect_setup.sh | bash; fi
before_install:

View File

@ -10,6 +10,17 @@ CHANGELOG
* @dn5 Added new translations (Bosnian, Serbian, Croatian) ([view](https://github.com/videojs/video.js/pull/1897))
* @mmcc (and others) converted the whole project to use ES6, Babel and Browserify ([view](https://github.com/videojs/video.js/pull/1976))
* @heff converted all classes to use ES6 classes ([view](https://github.com/videojs/video.js/pull/1993))
* @mmcc added ES6 default args and template strings ([view](https://github.com/videojs/video.js/pull/2015))
* @dconnolly replaced JSON.parse with a safe non-eval JSON parse ([view](https://github.com/videojs/video.js/pull/2077))
* @mmcc added a new default skin, switched to SASS, modified the html ([view](https://github.com/videojs/video.js/pull/1999))
* @gkatsev removed event.isDefaultPrevented in favor of event.defaultPrevented ([view](https://github.com/videojs/video.js/pull/2081))
* @heff added and `extends` function for external subclassing ([view](https://github.com/videojs/video.js/pull/2078))
* @forbesjo added the `scrubbing` property ([view](https://github.com/videojs/video.js/pull/2080))
* @heff switched to border-box sizing for all player elements ([view](https://github.com/videojs/video.js/pull/2082))
* @forbesjo added a vjs-button class to button controls ([view](https://github.com/videojs/video.js/pull/2084))
* @bc-bbay Load plugins before controls ([view](https://github.com/videojs/video.js/pull/2094))
* @bc-bbay rename onEvent methods to handleEvent ([view](https://github.com/videojs/video.js/pull/2093))
* @dmlap added an error message if techOrder is not in options ([view](https://github.com/videojs/video.js/pull/2097))
--------------------

View File

@ -53,15 +53,27 @@ module.exports = function(grunt) {
},
dist: {},
watch: {
files: [ 'src/**/*', 'test/unit/**/*.js', 'Gruntfile.js' ],
tasks: 'dev'
default: {
files: [ 'src/**/*', 'test/unit/**/*.js', 'Gruntfile.js' ],
tasks: 'dev'
},
skin: {
files: ['src/css/**/*'],
tasks: 'sass'
}
},
connect: {
dev: {
preview: {
options: {
port: 9999,
keepalive: true
}
},
dev: {
options: {
port: 9999,
livereload: true
}
}
},
copy: {
@ -143,10 +155,10 @@ module.exports = function(grunt) {
ext: '.min.css'
}
},
less: {
dev: {
sass: {
dist: {
files: {
'build/temp/video-js.css': 'src/css/video-js.less'
'build/temp/video-js.css': 'src/css/video-js.scss'
}
}
},
@ -226,6 +238,12 @@ module.exports = function(grunt) {
},
src: ['package.json', 'bower.json', 'component.json']
},
prerelease: {
options: {
release: 'prerelease'
},
src: ['package.json', 'bower.json', 'component.json']
},
css: {
options: {
prefix: '@version\\s*'
@ -251,6 +269,21 @@ module.exports = function(grunt) {
}
},
browserify: {
options: {
transform: [
require('babelify').configure({
sourceMapRelative: './src/js'
}),
['browserify-versionify', {
placeholder: '__VERSION__',
version: pkg.version
}],
['browserify-versionify', {
placeholder: '__VERSION_NO_PATCH__',
version: version.majorMinor
}]
]
},
build: {
files: {
'build/temp/video.js': ['src/js/video.js']
@ -261,18 +294,17 @@ module.exports = function(grunt) {
standalone: 'videojs'
},
banner: license,
transform: [
require('babelify').configure({
sourceMapRelative: './src/js'
}),
['browserify-versionify', {
placeholder: '__VERSION__',
version: pkg.version
}],
['browserify-versionify', {
placeholder: '__VERSION_NO_PATCH__',
version: version.majorMinor
}]
plugin: [
[ 'browserify-derequire' ]
]
}
},
test: {
files: {
'build/temp/tests.js': [
'test/globals-shim.js',
'test/unit/**/*.js',
'test/api/**.js'
]
}
},
@ -288,18 +320,8 @@ module.exports = function(grunt) {
standalone: 'videojs'
},
banner: license,
transform: [
require('babelify').configure({
sourceMapRelative: './src/js'
}),
['browserify-versionify', {
placeholder: '__VERSION__',
version: pkg.version
}],
['browserify-versionify', {
placeholder: '__VERSION_NO_PATCH__',
version: version.majorMinor
}]
plugin: [
[ 'browserify-derequire' ]
]
}
}
@ -313,6 +335,9 @@ module.exports = function(grunt) {
}
},
coveralls: {
options: {
force: true
},
all: {
src: 'test/coverage/lcov.info'
}
@ -335,7 +360,7 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-karma');
grunt.loadNpmTasks('videojs-doc-generator');
grunt.loadNpmTasks('grunt-zip');
@ -360,7 +385,7 @@ module.exports = function(grunt) {
'concat:vtt',
'exorcise',
'uglify',
'less',
'sass',
'version:css',
'cssmin',
'copy:fonts',
@ -386,10 +411,13 @@ module.exports = function(grunt) {
grunt.registerTask('newtest', ['build', 'karma:chrome']);
// Default task.
grunt.registerTask('default', ['build', 'test']);
grunt.registerTask('default', ['build', 'test-local']);
// Development watch task. Doing the minimum required.
grunt.registerTask('dev', ['jshint', 'less', 'browserify:build', 'karma:chrome']);
grunt.registerTask('dev', ['connect:dev', 'jshint', 'sass', 'browserify:build', 'karma:chrome']);
// Skin development watch task.
grunt.registerTask('skin-dev', ['connect:dev', 'watch:skin']);
// Tests.
// We want to run things a little differently if it's coming from Travis vs local

View File

@ -61,4 +61,4 @@ To build your own custom version read the section on [contributing code](CONTRIB
Video.js is licensed under the Apache License, Version 2.0. [View the license file](LICENSE)
Copyright 2014 Brightcove, Inc.
Copyright 2014-2015 Brightcove, Inc.

View File

@ -1,7 +1,7 @@
{
"name": "video.js",
"description": "An HTML5 and Flash video player with a common API and skin for both.",
"version": "4.12.5",
"version": "5.0.0-1",
"main": [
"dist/video-js/video.js",
"dist/video-js/video-js.css",

View File

@ -0,0 +1,11 @@
module.exports = function(grunt) {
grunt.registerTask('addStyleInjection', 'Adding base style injection', function() {
var minifiedCss = grunt.file.read('build/files/video-js.min.css');
// We need to escape any strings
minifiedCss = minifiedCss.replace(/'/g, '\\\'');
var combinedJs = grunt.file.read('build/files/combined.video.js');
combinedJs = combinedJs.replace(/\{{GENERATED_STYLES}}/g, minifiedCss);
grunt.file.write('build/files/combined.video.js', combinedJs);
});
};

View File

@ -1,7 +1,7 @@
{
"name": "video.js",
"description": "An HTML5 and Flash video player with a common API and skin for both.",
"version": "4.12.5",
"version": "5.0.0-1",
"keywords": [
"videojs",
"html5",

View File

@ -4,13 +4,13 @@
<title>Video.js | HTML5 Video Player</title>
<!-- Chang URLs to wherever Video.js files will be hosted -->
<link href="../../video-js.css" rel="stylesheet" type="text/css">
<link href="../../../build/temp/video-js.min.css" rel="stylesheet" type="text/css">
<!-- video.js must be in the <head> for older IEs to work. -->
<script src="../../video.js"></script>
<script src="../../../build/temp/video.min.js"></script>
<!-- Unless using the CDN hosted version, update the URL to the Flash SWF -->
<script>
videojs.options.flash.swf = "../../video-js.swf";
videojs.options.flash.swf = "../../../build/temp/video-js.swf";
</script>
</head>

View File

@ -20,8 +20,8 @@ You can download the Video.js source and host it on your own servers, or use the
### CDN Version ###
```html
<link href="//vjs.zencdn.net/4.12/video-js.css" rel="stylesheet">
<script src="//vjs.zencdn.net/4.12/video.js"></script>
<link href="//vjs.zencdn.net/4.12/video-js.min.css" rel="stylesheet">
<script src="//vjs.zencdn.net/4.12/video.min.js"></script>
```
@ -43,8 +43,8 @@ To entirely self-host, you'll need to pull in the font files and let Video.js kn
should Just Work™, but the paths can easily be changed by editing the LESS file and re-building, or by modifying the generated CSS file.
```html
<link href="//example.com/path/to/video-js.css" rel="stylesheet">
<script src="//example.com/path/to/video.js"></script>
<link href="//example.com/path/to/video-js.min.css" rel="stylesheet">
<script src="//example.com/path/to/video.min.js"></script>
<script>
videojs.options.flash.swf = "http://example.com/path/to/video-js.swf"
</script>

View File

@ -1,28 +1,29 @@
Skins
=====
The default Video.js skin is made using HTML and CSS, so there's no need to learn a complicated skinning language to update colors or even create an entirely new skin.
The base Video.js skin is made using HTML and CSS (although we use the [Sass preprocessor](http://sass-lang.com)), and by default these styles are added to the dom for you! That means you can build a custom skin by simply taking advantage of the cascading aspect of CSS and overriding
the styles you'd like to change.
If you don't want Video.js to inject the base styles for you, you can disable it by setting `window.VIDEOJS_NO_BASE_THEME = false` before Video.js is loaded. Keep in mind that without these base styles
enabled, you'll need to manually include them.
## Icons
New in version 4.0 is the use of font icons. All of the icons (play, pause, etc.) use the new custom font, which allows the icons to be scaled and colored just like any other text font.
All of the icons are available as variables in the [LESS](https://github.com/videojs/video.js/blob/master/src/css/video-js.less#L87-L99) source, making it easy to replace icons (such as the loading spinner). The easiest way to try this out is by using the [player skin designer](http://designer.videojs.com/).
![available icons](https://i.cloudup.com/wb51GGDDnJ.png)
You can view all of the icons available in the base theme by renaming and viewing [`icons.html.example`](../../sandbox/icons.html.example) in the sandbox directory.
## Customization
When you create a new skin, you can either override styles in the default skin:
When you create a new skin, the easiest way to get started is to simply override the base Video.js theme. You should include a new class matching the
name of your theme, then just start overriding!
```css
.vjs-default-skin .vjs-play-progress { background: #900; }
.vjs-skin-hotdog-stand { color: #FF0000; }
.vjs-skin-hotdog-stand .vjs-control-bar { background: #FFFF00; }
.vjs-skin-hotdog-stand .vjs-play-progress { background: #FF0000; }
```
Or remove the 'vjs-default-skin' class from the video tag and create a new skin from scratch.
```html
<video class="video-js my-custom-skin" ...>
```
This would take care of the major areas of the skin (play progress, the control bar background, and icon colors), but you can skin any other aspect.
Our suggestion is to use a browser such as Firefox and Chrome, and use the developer tools to inspect the different elements and see what you'd like to change and what classes
to target when you do so.
More custom skins will be available for download soon. If you have one you like you can share it by forking [this example on CodePen.io](http://codepen.io/heff/pen/EarCt), and adding a link on the [Skins wiki page](https://github.com/videojs/video.js/wiki/Skins).

View File

@ -1,7 +1,7 @@
{
"name": "video.js",
"description": "An HTML5 and Flash video player with a common API and skin for both.",
"version": "4.12.5",
"version": "5.0.0-1",
"copyright": "Copyright Brightcove, Inc. <https://www.brightcove.com/>",
"license": "Apache-2.0",
"keywords": [
@ -20,20 +20,25 @@
"type": "git",
"url": "https://github.com/videojs/video.js.git"
},
"main": "src/js/video.js",
"main": "./dist/video.js",
"style": "./dist/video-js.css",
"dependencies": {
"global": "^4.3.0",
"safe-json-parse": "^4.0.0",
"inherits": "^2.0.1",
"videojs-swf": "4.5.4",
"vtt.js": "git+https://github.com/gkatsev/vtt.js.git#shim-build",
"global": "^4.3.0"
"vtt.js": "git+https://github.com/gkatsev/vtt.js.git#shim-build"
},
"devDependencies": {
"babelify": "^6.0.1",
"blanket": "^1.1.6",
"browserify-derequire": "^0.9.4",
"browserify-istanbul": "^0.2.1",
"browserify-versionify": "^1.0.4",
"chg": "~0.2.0",
"grunt": "^0.4.4",
"grunt-aws-s3": "^0.12.1",
"grunt-banner": "^0.3.1",
"grunt-browserify": "^3.5.0",
"grunt-cli": "~0.1.0",
"grunt-contrib-clean": "~0.4.0a",
@ -50,6 +55,7 @@
"grunt-fastly": "^0.1.3",
"grunt-github-releaser": "^0.1.17",
"grunt-karma": "^0.8.3",
"grunt-sass": "^0.18.1",
"grunt-version": "~0.3.0",
"grunt-videojs-languages": "0.0.4",
"grunt-zip": "0.10.2",

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Video.js Icons Sandbox</title>
<link href="../build/temp/video-js.css" rel="stylesheet" type="text/css">
<style>
.icon-list li span { font-size: 150% }
</style>
</head>
<body>
<h1>Video.js Icons</h1>
<p>This is a list of all of the icons available in the Video.js base stylesheet. The appropriate class is to the right of each icon.</p>
<ul class="icon-list">
<li><span class="vjs-icon-play"></span> <code>.vjs-icon-play</code></li>
<li><span class="vjs-icon-pause"></span> <code>.vjs-icon-pause</code></li>
<li><span class="vjs-icon-volume-mute"></span> <code>.vjs-icon-volume-mute</code></li>
<li><span class="vjs-icon-volume-low"></span> <code>.vjs-icon-volume-low</code></li>
<li><span class="vjs-icon-volume-mid"></span> <code>.vjs-icon-volume-mid</code></li>
<li><span class="vjs-icon-volume-high"></span> <code>.vjs-icon-volume-high</code></li>
<li><span class="vjs-icon-fullscreen-enter"></span> <code>.vjs-icon-fullscreen-enter</code></li>
<li><span class="vjs-icon-fullscreen-exit"></span> <code>.vjs-icon-fullscreen-exit</code></li>
<li><span class="vjs-icon-square"></span> <code>.vjs-icon-square</code></li>
<li><span class="vjs-icon-spinner"></span> <code>.vjs-icon-spinner</code></li>
<li><span class="vjs-icon-subtitles"></span> <code>.vjs-icon-subtitles</code></li>
<li><span class="vjs-icon-captions"></span> <code>.vjs-icon-captions</code></li>
<li><span class="vjs-icon-chapters"></span> <code>.vjs-icon-chapters</code></li>
<li><span class="vjs-icon-share"></span> <code>.vjs-icon-share</code></li>
<li><span class="vjs-icon-cog"></span> <code>.vjs-icon-cog</code></li>
<li><span class="vjs-icon-circle"></span> <code>.vjs-icon-circle</code></li>
<li><span class="vjs-icon-circle-outline"></span> <code>.vjs-icon-circle-outline</code></li>
<li><span class="vjs-icon-circle-inner-circle"></span> <code>.vjs-icon-circle-inner-circle</code></li>
</ul>
</body>
</html>

View File

@ -6,12 +6,11 @@
<link href="../build/temp/video-js.css" rel="stylesheet" type="text/css">
<!-- LOAD VIDEO.JS SOURCE FILES IN ORDER -->
<script src="../build/temp/video.js"></script>
<!-- Set the location of the flash SWF -->
<script>
vjs.options.flash.swf = '../build/temp/video-js.swf'
videojs.options.flash.swf = '../build/temp/video-js.swf';
</script>
</head>

95
src/css/_utilities.scss Normal file
View File

@ -0,0 +1,95 @@
@mixin background-color-with-alpha($color, $alpha) {
background-color: $color;
background-color: rgba($color, $alpha);
}
@mixin transition($string: $transition--default) {
-webkit-transition: $string;
-moz-transition: $string;
-o-transition: $string;
transition: $string;
}
@mixin hide-visually {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
@mixin border-radius($radius) {
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
border-radius: $radius;
}
@mixin animation($string: spin 1s infinite linear) {
-webkit-animation: $string;
-moz-animation: $string;
-o-animation: $string;
animation: $string;
}
@mixin display-flex($alignment: '', $justification: '') {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
@if $alignment != '' {
-webkit-box-align: $alignment;
-webkit-align-items: $alignment;
-ms-flex-align: $alignment;
align-items: $alignment;
}
@if $justification != '' {
-webkit-box-pack: $justification;
-webkit-justify-content: $justification;
-ms-flex-pack: $justification;
justify-content: $justification;
}
}
@mixin flex($value) {
// @include context('.video-js', '.video-js.vjs-no-flex') {
// display: table-cell;
// vertical-align: middle;
// @if ($value == 'auto') {
// width: auto;
// }
// }
-webkit-box-flex: $value;
-moz-box-flex: $value;
-webkit-flex: $value;
-ms-flex: $value;
flex: $value;
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/user-select
@mixin user-select($string: none) {
-webkit-user-select: $string;
-moz-user-select: $string;
-ms-user-select: $string;
user-select: $string
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow
@mixin box-shadow ($string: 0 0 1em rgba(0, 0, 0, 0.25)) {
-webkit-box-shadow: $string;
-moz-box-shadow: $string;
box-shadow: $string;
}
@mixin order($value) {
-webkit-box-ordinal-group: $value;
-moz-box-ordinal-group: $value;
-ms-flex-order: $value;
-webkit-order: $value;
order: $value;
}

12
src/css/_variables.scss Normal file
View File

@ -0,0 +1,12 @@
$primary-text: #fff;
$secondary-text: #F4A460; // currently just used for visited links in errors and such.
$primary-bg: #000;
$secondary-bg: lighten($primary-bg, 35%);
$icon-font-family: 'VideoJS';
$text-font-family: Arial, sans-serif;
$base-font-size: 10px;
$control-bar-bg: #2B333F;
$control-bar-transparency: 0.5;

View File

@ -0,0 +1,37 @@
// When the player is absurdly tiny, display nothing but:
// - Play button
// - Fullscreen Button
.video-js.vjs-layout-tiny:not(.vjs-fullscreen) {
.vjs-custom-control-spacer { @include flex(auto); }
&.vjs-no-flex .vjs-custom-control-spacer { width: auto; }
.vjs-current-time, .vjs-captions-button, .vjs-time-divider,
.vjs-progress-control, .vjs-duration, .vjs-remaining-time, .vjs-playback-rate,
.vjs-mute-control, .vjs-volume-control, .vjs-chapters-button, .vjs-captions-button,
.vjs-subtitles-button, .vjs-volume-menu-button { display: none; }
}
// When the player is x-small, display nothing but:
// - Play button
// - Progress bar
// - Fullscreen Button
.video-js.vjs-layout-x-small:not(.vjs-fullscreen) {
.vjs-current-time, .vjs-captions-button, .vjs-time-divider,
.vjs-duration, .vjs-remaining-time, .vjs-playback-rate, .vjs-captions-button,
.vjs-mute-control, .vjs-volume-control, .vjs-chapters-button,
.vjs-subtitles-button, .vjs-volume-button, .vjs-fullscreen-control { display: none; }
}
// When the player is small, display nothing but:
// - Play button
// - Progress bar
// - Volume menu button
// - Captions Button
// - Fullscreen button
.video-js.vjs-layout-small:not(.vjs-fullscreen) {
.vjs-current-time, .vjs-captions-button, .vjs-time-divider,
.vjs-duration, .vjs-remaining-time, .vjs-playback-rate,
.vjs-mute-control, .vjs-volume-control, .vjs-chapters-button,
.vjs-subtitles-button { display: none; }
}

View File

@ -0,0 +1,40 @@
.video-js .vjs-big-play-button {
font-size: 3em;
line-height: 1em;
display: block;
z-index: 2;
position: absolute;
top: 10px;
left: 10px;
padding: 0.2em 1em;
cursor: pointer;
opacity: 1;
border: 2px solid $primary-text;
/* Need a slightly gray bg so it can be seen on black backgrounds *///
@include background-color-with-alpha($primary-bg, 0.8);
@include border-radius(0.3em);
@include transition(all 0.4s);
@extend .vjs-icon-play;
}
/* Hide if controls are disabled, the video is playing, or native controls are used. */
.video-js.vjs-controls-disabled .vjs-big-play-button,
.video-js.vjs-has-started .vjs-big-play-button,
.video-js.vjs-using-native-controls .vjs-big-play-button {
display: none;
}
.video-js:hover .vjs-big-play-button,
.video-js .vjs-big-play-button:focus {
outline: 0;
border-color: $primary-text;
@include background-color-with-alpha($secondary-bg, 0.75);
@include transition(all 0s);
}
.vjs-error .vjs-big-play-button {
display: none;
}

View File

@ -0,0 +1,3 @@
.video-js .vjs-captions-button {
@extend .vjs-icon-captions;
}

View File

@ -0,0 +1,12 @@
.video-js .vjs-chapters-button {
@extend .vjs-icon-chapters;
}
.video-js .vjs-chapters-button.vjs-menu-button .vjs-menu {
left: 2em;
}
.video-js .vjs-chapters-button.vjs-menu-button .vjs-menu .vjs-menu-content {
width: 24em;
left: -12em;
}

View File

@ -0,0 +1,57 @@
.video-js .vjs-control-bar {
display: none;
width: 100%;
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 3.0em;
@include background-color-with-alpha($control-bar-bg, $control-bar-transparency);
}
// Video has started playing
.video-js.vjs-has-started .vjs-control-bar {
@include display-flex;
visibility: visible;
opacity: 1;
$trans: visibility 0.1s, opacity 0.1s; // Var needed because of comma
@include transition($trans);
}
// Video has started playing AND user is inactive
.video-js.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
visibility: hidden;
opacity: 0;
$trans: visibility 1.0s, opacity 1.0s;
@include transition($trans);
}
.video-js.vjs-controls-disabled .vjs-control-bar,
.video-js.vjs-using-native-controls .vjs-control-bar,
.video-js.vjs-error .vjs-control-bar {
display: none;
}
// Don't hide the control bar if it's audio
.video-js.vjs-audio.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
opacity: 1;
visibility: visible;
}
/* IE8 is flakey with fonts, and you have to change the actual content to force
fonts to show/hide properly.
- "\9" IE8 hack didn't work for this
- Found in XP IE8 from http://modern.ie. Does not show up in "IE8 mode" in IE9
*/
$ie8screen: "\0screen";
.video-js.vjs-user-inactive.vjs-playing .vjs-control-bar :before {
@media #{$ie8screen} { content: ""; }
}
/* IE 8 + 9 Support */
.video-js.vjs-has-started.vjs-no-flex .vjs-control-bar {
display: table;
}

View File

@ -0,0 +1,39 @@
.video-js .vjs-control {
outline: none;
position: relative;
text-align: center;
margin: 0;
padding: 0;
height: 100%;
width: 4em;
@include flex(none);
}
.video-js .vjs-control:before {
font-size: 1.8em;
line-height: 1.67;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-align: center;
}
/* Replacement for focus outline */
.video-js .vjs-control:focus:before,
.video-js .vjs-control:hover:before,
.video-js .vjs-control:focus {
text-shadow: 0em 0em 1em rgba($primary-text, 1);
}
/* Hide control text visually, but have it available for screenreaders */
.video-js .vjs-control-text {
@include hide-visually;
}
/* IE 8 + 9 Support */
.vjs-no-flex .vjs-control {
display: table-cell;
vertical-align: middle;
}

View File

@ -0,0 +1,47 @@
.vjs-error-display {
display: none;
}
.vjs-error .vjs-error-display {
display: block;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.vjs-error .vjs-error-display:before {
content: 'X';
font-family: $text-font-family;
font-size: 4em;
color: $secondary-bg;
/* In order to center the play icon vertically we need to set the line height
to the same as the button height */
line-height: 1;
text-shadow: 0.05em 0.05em 0.1em $primary-bg;
text-align: center /* Needed for IE8 */;
vertical-align: middle;
position: absolute;
left: 0;
top: 50%;
margin-top: -0.5em;
width: 100%;
}
.vjs-error-display div {
position: absolute;
bottom: 1em;
right: 0;
left: 0;
font-size: 1.4em;
text-align: center;
padding: 3px;
@include background-color-with-alpha($primary-bg, 0.5);
}
.vjs-error-display a, .vjs-error-display a:visited {
color: $secondary-text;
}

View File

@ -0,0 +1,12 @@
.video-js .vjs-fullscreen-control {
width: 3.8em;
cursor: pointer;
@include flex(none);
}
.video-js .vjs-fullscreen-control {
@extend .vjs-icon-fullscreen-enter;
}
/* Switch to the exit icon when the player is in fullscreen */
.video-js.vjs-fullscreen .vjs-fullscreen-control {
@extend .vjs-icon-fullscreen-exit;
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,101 @@
.video-js {
display: block;
box-sizing: border-box;
color: $primary-text;
background-color: $primary-bg;
position: relative;
padding: 0;
/* Start with 10px for base font size so other dimensions can be em based and
easily calculable. */
font-size: $base-font-size;
/* Allow poster to be vertially aligned. */
vertical-align: middle;
/* Provide some basic defaults for fonts */
font-weight: normal;
font-style: normal;
/* Avoiding helvetica: issue #376 */
font-family: $text-font-family;
@include user-select(none);
/* Fix for Firefox 9 fullscreen (only if it is enabled). Not needed when
checking fullScreenEnabled. */
&:-moz-full-screen { position: absolute; }
&:-webkit-full-screen {
width: 100% !important;
height: 100% !important;
}
}
/* All elements inherit border-box sizing */
.video-js *,
.video-js *:before,
.video-js *:after {
box-sizing: inherit;
}
/* Playback technology elements expand to the width/height of the containing div
<video> or <object> */
.video-js .vjs-tech {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* Fullscreen Styles */
body.vjs-full-window {
padding: 0;
margin: 0;
height: 100%;
/* Fix for IE6 full-window. http://www.cssplay.co.uk/layouts/fixed.html */
overflow-y: auto;
}
.video-js.vjs-fullscreen {
position: fixed;
overflow: hidden;
z-index: 1000;
left: 0;
top: 0;
bottom: 0;
right: 0;
width: 100% !important;
height: 100% !important;
}
.video-js.vjs-fullscreen.vjs-user-inactive {
cursor: none;
}
/* Hide disabled or unsupported controls. */
.vjs-hidden { display: none !important; }
.vjs-lock-showing {
display: block !important;
opacity: 1;
visibility: visible;
}
/* In IE8 w/ no JavaScript (no HTML5 shim), the video tag doesn't register.
The .video-js classname on the video tag also isn't considered.
This optional paragraph inside the video tag can provide a message to users
about what's required to play video. */
.vjs-no-js {
padding: 20px;
color: $primary-text;
background-color: $primary-bg;
font-size: 18px;
font-family: $text-font-family;
text-align: center;
width: 300px;
height: 150px;
margin: 0px auto;
}
.vjs-no-js a, .vjs-no-js a:visited {
color: $secondary-text;
}

View File

@ -0,0 +1,11 @@
.video-js.vjs-live .vjs-time-control,
.video-js.vjs-live .vjs-time-divider,
.video-js.vjs-live .vjs-progress-control {
display: none;
}
.video-js .vjs-live-control {
display: none;
font-size: 1em;
line-height: 3em;
}

View File

@ -0,0 +1,64 @@
.vjs-loading-spinner {
display: none;
position: absolute;
top: 50%;
left: 50%;
font-size: 4em;
line-height: 1;
width: 1em;
height: 1em;
margin-left: -0.5em;
margin-top: -0.5em;
opacity: 0.75;
@extend .vjs-icon-spinner;
}
/* Show the spinner when waiting for data and seeking to a new time */
.vjs-waiting .vjs-loading-spinner,
.vjs-seeking .vjs-loading-spinner {
display: block;
/* only animate when showing because it can be processor heavy *///
@include animation(spin 1.5s infinite linear);
}
/* Errors are unrecoverable without user interaction so hide the spinner */
.vjs-error .vjs-loading-spinner {
display: none;
/* ensure animation doesn't continue while hidden *///
@include animation(none);
}
.video-js .vjs-loading-spinner:before {
position: absolute;
top: 0;
left: 0;
width: 1em;
height: 1em;
text-align: center;
text-shadow: 0em 0em 0.1em $primary-bg;
}
@-moz-keyframes spin {
0% { -moz-transform: rotate(0deg); }
100% { -moz-transform: rotate(359deg); }
}
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(359deg); }
}
@-o-keyframes spin {
0% { -o-transform: rotate(0deg); }
100% { -o-transform: rotate(359deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(359deg); }
}

View File

@ -0,0 +1,69 @@
.video-js .vjs-menu-button {
cursor: pointer;
}
.video-js .vjs-menu {
display: none;
position: absolute;
bottom: 0;
left: -3em; /* (Width of vjs-menu - width of button) / 2 */
width: 0em;
height: 0em;
margin-bottom: 1.5em;
border-top-color: rgba(7, 40, 50, $control-bar-transparency); /* Same as ul background */
}
/* Button Pop-up Menu */
.video-js .vjs-menu-content {
@include background-color-with-alpha($primary-bg, 0.7);
}
.video-js .vjs-menu-button .vjs-menu .vjs-menu-content {
display: block;
padding: 0; margin: 0;
position: absolute;
width: 10em;
bottom: 1.5em; /* Same bottom as vjs-menu border-top */
max-height: 15em;
overflow: auto;
}
.video-js .vjs-menu-button:hover .vjs-control-content .vjs-menu,
.video-js .vjs-control-content .vjs-menu.vjs-lock-showing {
display: block;
}
/* prevent menus from opening while scrubbing (FF, IE) */
.video-js.vjs-scrubbing .vjs-menu-button:hover .vjs-control-content .vjs-menu {
display: none;
}
.video-js .vjs-menu-button ul li {
list-style: none;
margin: 0;
padding: 0.2em 0;
line-height: 1.4em;
font-size: 1.2em;
text-align: center;
text-transform: lowercase;
}
.video-js .vjs-menu-button ul li.vjs-selected {
background-color: $primary-bg;
}
.video-js .vjs-menu-button ul li:focus,
.video-js .vjs-menu-button ul li:hover,
.video-js .vjs-menu-button ul li.vjs-selected:focus,
.video-js .vjs-menu-button ul li.vjs-selected:hover {
outline: 0;
color: $primary-bg;
@include background-color-with-alpha($primary-text, 0.75);
}
.video-js .vjs-menu-button ul li.vjs-menu-title {
text-align: center;
text-transform: uppercase;
font-size: 1em;
line-height: 2em;
padding: 0;
margin: 0 0 0.3em 0;
font-weight: bold;
cursor: default;
}

View File

@ -0,0 +1,11 @@
.video-js .vjs-play-control {
width: 5em;
cursor: pointer;
@include flex(none);
}
.video-js .vjs-play-control {
@extend .vjs-icon-play;
}
.video-js.vjs-playing .vjs-play-control {
@extend .vjs-icon-pause;
}

View File

@ -0,0 +1,20 @@
// TODO: I feel like this should be a generic menu. Research later.
.video-js .vjs-playback-rate .vjs-playback-rate-value {
font-size: 1.5em;
line-height: 2;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-align: center;
}
.video-js .vjs-playback-rate .vjs-menu {
left: 0em;
}
.video-js .vjs-playback-rate.vjs-menu-button .vjs-menu .vjs-menu-content {
width: 4em;
left: 0;
list-style: none;
}

View File

@ -0,0 +1,41 @@
.vjs-poster {
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: contain;
cursor: pointer;
margin: 0;
padding: 0;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.vjs-poster img {
display: block;
margin: 0 auto;
max-height: 100%;
padding: 0;
width: 100%;
}
/* Hide the poster after the video has started playing */
.video-js.vjs-has-started .vjs-poster {
display: none;
}
/* Don't hide the poster if we're playing audio */
.video-js.vjs-audio.vjs-has-started .vjs-poster {
display: block;
}
/* Hide the poster when controls are disabled because it's clickable
and the native poster can take over */
.video-js.vjs-controls-disabled .vjs-poster {
display: none;
}
/* Hide the poster when native controls are used otherwise it covers them */
.video-js.vjs-using-native-controls .vjs-poster {
display: none;
}

View File

@ -0,0 +1,50 @@
.video-js .vjs-progress-control {
@include flex(auto);
@include display-flex(center);
}
/* Box containing play and load progresses. Also acts as seek scrubber. */
.video-js .vjs-progress-holder {
@include flex(auto);
height: 0.3em;
}
/* Progress Bars */
.video-js .vjs-progress-holder .vjs-play-progress,
.video-js .vjs-progress-holder .vjs-load-progress,
.video-js .vjs-progress-holder .vjs-load-progress div {
position: absolute;
display: block;
height: 100%;
margin: 0;
padding: 0;
/* updated by javascript during playback */
width: 0;
/* Needed for IE6 *///
left: 0;
top: 0;
}
.video-js .vjs-play-progress {
background-color: $primary-text;
}
.video-js .vjs-load-progress {
background: rgb(100, 100, 100) /* IE8- Fallback */;
background: rgba(255, 255, 255, 0.2);
}
/* there are child elements of the load progress bar that represent the
specific time ranges that have been buffered */
.video-js .vjs-load-progress div {
background: rgba($secondary-bg, 0.1);
}
.video-js .vjs-slider-handle.vjs-seek-handle {
width: 0.95em;
height: 0.95em;
}
.video-js.vjs-no-flex .vjs-progress-control {
width: auto;
}

View File

@ -0,0 +1,39 @@
.video-js .vjs-slider {
outline: 0;
position: relative;
cursor: pointer;
padding: 0;
@include background-color-with-alpha($secondary-bg, 0.9);
}
.video-js .vjs-slider:focus {
text-shadow: 0em 0em 1em rgba($primary-text, 1);
@include box-shadow(0 0 1em $primary-text);
}
.video-js .vjs-slider-handle {
position: absolute;
@extend .vjs-icon-circle;
}
.video-js .vjs-slider-horizontal .vjs-slider-handle {
left: 0;
top: -0.34em;
}
.video-js .vjs-slider-vertical .vjs-slider-handle {
left: -0.3em;
bottom: 0;
}
.video-js .vjs-slider-handle:before {
font-size: 1em;
line-height: 1;
text-align: center;
position: absolute;
top: 0;
left: 0;
}

View File

@ -0,0 +1,3 @@
.video-js .vjs-subtitles-button {
@extend .vjs-icon-subtitles;
}

View File

@ -0,0 +1,26 @@
.video-js .vjs-text-track-display {
text-align: center;
position: absolute;
bottom: 4em;
/* Leave padding on left and right */
left: 1em;
right: 1em;
}
/* Move captions down when controls aren't being shown */
.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display {
bottom: 1em;
}
/* Individual tracks */
.video-js .vjs-text-track {
font-size: 1.4em;
text-align: center;
margin-bottom: 0.1em;
/* Transparent black background, or fallback to all black (oldIE) */
@include background-color-with-alpha($primary-bg, 0.5);
}
.video-js .vjs-subtitles { color: #fff /* Subtitles are white */; }
.video-js .vjs-captions { color: #fc6 /* Captions are yellow */; }
.vjs-tt-cue { display: block; }

View File

@ -0,0 +1,11 @@
.video-js .vjs-time-control {
@include flex(none);
font-size: 1em;
line-height: 3em;
}
/* We need the extra specificity that referencing .vjs-no-flex provides. */
.video-js .vjs-current-time, .video-js.vjs-no-flex .vjs-current-time { display: none; }
.video-js .vjs-duration, .video-js.vjs-no-flex .vjs-duration { display: none; }
.video-js .vjs-remaining-time, .video-js.vjs-no-flex .vjs-remaining-time { display: none; }
.vjs-time-divider { display: none; line-height: 3em; }

View File

@ -0,0 +1,104 @@
.video-js .vjs-mute-control,
.video-js .vjs-volume-menu-button {
cursor: pointer;
@include flex(none);
@extend .vjs-icon-volume-high;
}
.video-js .vjs-mute-control.vjs-vol-0,
.video-js .vjs-volume-menu-button.vjs-vol-0 {
@extend .vjs-icon-volume-mute;
}
.video-js .vjs-mute-control.vjs-vol-1,
.video-js .vjs-volume-menu-button.vjs-vol-1 {
@extend .vjs-icon-volume-low;
}
.video-js .vjs-mute-control.vjs-vol-2,
.video-js .vjs-volume-menu-button.vjs-vol-2 {
@extend .vjs-icon-volume-mid;
}
.video-js .vjs-volume-control {
width: 5em;
@include flex(none);
@include display-flex(center);
}
.video-js .vjs-volume-bar.vjs-slider-horizontal {
width: 5em;
height: 0.3em;
}
.video-js .vjs-volume-bar.vjs-slider-vertical {
width: 0.3em;
height: 5em;
margin: 1.3em;
}
.video-js .vjs-volume-level {
position: absolute;
bottom: 0;
left: 0;
background-color: $primary-text;
}
.video-js .vjs-slider-vertical .vjs-volume-level { width: 0.3em; }
.video-js .vjs-slider-horizontal .vjs-volume-level { height: 0.3em; }
.video-js .vjs-volume-bar .vjs-volume-handle {
width: 0.8em;
height: 0.8em;
}
/* Assumes volume starts at 1.0. If you change the size of the
handle relative to the volume bar, you'll need to update this value
too. */
.video-js .vjs-volume-bar.vjs-slider-vertical .vjs-volume-level { height: 100%; }
.video-js .vjs-volume-bar.vjs-slider-vertical .vjs-volume-handle { bottom: 4.3em; }
.video-js .vjs-volume-bar.vjs-slider-horizontal .vjs-volume-level { width: 100%; }
.video-js .vjs-volume-bar.vjs-slider-horizontal .vjs-volume-handle { left: 4.3em; }
.video-js .vjs-volume-handle:before {
font-size: 0.9em;
}
/* The volume menu button is like menu buttons (captions/subtitles) but works
a little differently. It needs to be possible to tab to the volume slider
without hitting space bar on the menu button. To do this we're not using
display:none to hide the slider menu by default, and instead setting the
width and height to zero. */
.video-js .vjs-volume-menu-button .vjs-menu {
display: block;
width: 0;
height: 0;
left: 0.5em;
border-top-color: transparent;
}
.video-js .vjs-menu-button.vjs-volume-menu-button .vjs-menu .vjs-menu-content {
height: 0;
width: 0;
// Avoids unnecessary scrollbars in the menu content. Primarily noticed in Chrome on Linux.
overflow-x: hidden;
overflow-y: hidden;
}
.video-js .vjs-volume-menu-button:hover .vjs-menu,
.video-js .vjs-volume-menu-button .vjs-menu.vjs-lock-showing {
// border-top-color: rgba(7, 40, 50, 0.5); /* Same as ul background */
}
.video-js .vjs-volume-menu-button:hover .vjs-menu .vjs-menu-content,
.video-js .vjs-volume-menu-button .vjs-menu.vjs-lock-showing .vjs-menu-content {
height: 8em;
width: 2.9em;
}
// By default, all menu items are shown, but we hide .vjs-mute-control and .vjs-volume-control
// so that the volume menu button is the only visible volume control.
.video-js .vjs-mute-control,
.video-js .vjs-volume-control {
display: none;
}

BIN
src/css/font/VideoJS.eot Executable file

Binary file not shown.

40
src/css/font/VideoJS.svg Executable file
View File

@ -0,0 +1,40 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="VideoJS" horiz-adv-x="512">
<font-face units-per-em="512" ascent="480" descent="-32" />
<missing-glyph horiz-adv-x="512" />
<glyph unicode="&#x20;" d="" horiz-adv-x="256" />
<glyph unicode="&#x25b6;" d="M170.667 373.334v-298.666l234.667 149.333z" />
<glyph unicode="&#xe601;" d="M405.334 373.334v-298.666h-298.666v298.666h298.666zM405.334 416h-298.666c-23.573 0-42.666-19.094-42.666-42.666v-298.666c0-23.574 19.093-42.666 42.666-42.666h298.666c23.574 0 42.666 19.094 42.666 42.666v298.666c0 23.574-19.094 42.666-42.666 42.666z" />
<glyph unicode="&#xe603;" d="M256 330.667c-58.88 0-106.666-47.787-106.666-106.667s47.786-106.666 106.666-106.666 106.666 47.786 106.666 106.666-47.786 106.666-106.666 106.666zM256 437.334c-117.867 0-213.333-95.466-213.333-213.334s95.466-213.333 213.333-213.333 213.333 95.466 213.333 213.333-95.466 213.333-213.333 213.333zM256 53.334c-94.293 0-170.667 76.373-170.667 170.667s76.374 170.667 170.667 170.667 170.667-76.374 170.667-170.667-76.374-170.667-170.667-170.667z" />
<glyph unicode="&#xe61a;" d="M384 136.853c-16.214 0-30.827-6.293-41.92-16.426l-152 88.64c1.173 4.8 1.92 9.813 1.92 14.934s-0.746 10.133-1.92 14.934l150.4 87.786c11.413-10.666 26.666-17.28 43.52-17.28 35.307 0 64 28.693 64 64s-28.693 64-64 64-64-28.694-64-64c0-5.12 0.747-10.134 1.92-14.934l-150.4-87.786c-11.413 10.666-26.667 17.28-43.52 17.28-35.306 0-64-28.693-64-64s28.694-64 64-64c16.853 0 32.106 6.613 43.52 17.28l152-88.64c-1.067-4.48-1.707-9.173-1.707-13.974 0-34.346 27.84-62.187 62.187-62.187s62.187 27.84 62.187 62.187-27.84 62.187-62.187 62.187z" />
<glyph unicode="&#xe64b;" d="M149.333 181.334h-42.666v-106.666h106.666v42.666h-64v64zM106.666 266.667h42.666v64h64v42.666h-106.666v-106.666zM362.666 117.334h-64v-42.666h106.666v106.666h-42.666v-64zM298.666 373.334v-42.666h64v-64h42.666v106.666h-106.666z" />
<glyph unicode="&#xe64c;" d="M106.666 138.666h64v-64h42.666v106.666h-106.666v-42.666zM170.667 309.333h-64v-42.666h106.667v106.666h-42.666v-64zM298.666 74.666h42.666v64h64v42.666h-106.666v-106.666zM341.334 309.333v64h-42.666v-106.666h106.666v42.666h-64z" />
<glyph unicode="&#xe650;" d="M376.534 344.534c-30.827 30.933-73.387 50.134-120.534 50.134-94.293 0-170.453-76.374-170.453-170.667s76.16-170.667 170.453-170.667c79.466 0 146.026 54.4 164.906 128h-44.373c-17.6-49.707-64.746-85.334-120.534-85.334-70.72 0-128 57.28-128 128s57.28 128 128 128c35.307 0 66.986-14.72 90.134-37.867l-68.8-68.8h149.334v149.333l-50.134-50.133z" />
<glyph unicode="&#xe692;" d="M469.334 224c0-117.82-95.512-213.333-213.334-213.333s-213.333 95.512-213.333 213.333c0 117.821 95.513 213.333 213.333 213.333s213.333-95.512 213.333-213.333z" />
<glyph unicode="&#xe6e2;" d="M256 437.334c-117.867 0-213.333-95.466-213.333-213.334s95.466-213.333 213.333-213.333 213.333 95.466 213.333 213.333-95.466 213.333-213.333 213.333z" />
<glyph unicode="&#xe6f2;" d="M256 437.334c-117.867 0-213.333-95.466-213.333-213.334s95.466-213.333 213.333-213.333 213.333 95.466 213.333 213.333-95.466 213.333-213.333 213.333zM256 53.334c-94.080 0-170.667 76.587-170.667 170.667s76.587 170.667 170.667 170.667 170.667-76.587 170.667-170.667-76.587-170.667-170.667-170.667z" />
<glyph unicode="&#xe713;" d="M448 416h-384c-23.573 0-42.666-19.094-42.666-42.666v-64h42.666v64h384v-298.666h-149.333v-42.666h149.333c23.574 0 42.666 19.094 42.666 42.666v298.666c0 23.574-19.094 42.666-42.666 42.666zM21.334 96v-64h64c0 35.307-28.694 64-64 64zM21.334 181.334v-42.666c58.88 0 106.666-47.786 106.666-106.666h42.666c0 82.454-66.88 149.334-149.333 149.334zM21.334 266.667v-42.667c106.026 0 192-85.974 192-192h42.666c0 129.6-105.067 234.667-234.667 234.667z" />
<glyph unicode="&#xe80d;" d="M426.666 394.666h-341.334c-23.573 0-42.666-19.094-42.666-42.666v-256c0-23.574 19.093-42.666 42.666-42.666h341.334c23.574 0 42.666 19.094 42.666 42.666v256c0 23.573-19.094 42.666-42.666 42.666zM85.334 224h85.334v-42.666h-85.334v42.666zM298.666 96h-213.333v42.666h213.333v-42.666zM426.666 96h-85.334v42.666h85.334v-42.666zM426.666 181.334h-213.333v42.666h213.333v-42.666z" />
<glyph unicode="&#xe81e;" d="M405.334 394.666h-298.666c-23.573 0-42.666-19.094-42.666-42.666v-256c0-23.574 19.093-42.666 42.666-42.666h298.666c23.574 0 42.666 19.094 42.666 42.666v256c0 23.573-19.094 42.666-42.666 42.666zM234.667 245.333h-32v10.667h-42.667v-64h42.666v10.666h32v-21.334c0-11.733-9.494-21.334-21.334-21.334h-64c-11.84 0-21.334 9.6-21.334 21.334v85.334c0 11.733 9.493 21.334 21.334 21.334h64c11.84 0 21.334-9.6 21.334-21.334v-21.334zM384 245.333h-32v10.667h-42.666v-64h42.666v10.666h32v-21.334c0-11.733-9.493-21.334-21.334-21.334h-64c-11.84 0-21.334 9.6-21.334 21.334v85.334c0 11.733 9.493 21.334 21.334 21.334h64c11.84 0 21.334-9.6 21.334-21.334v-21.334z" />
<glyph unicode="&#xe821;" d="M85.334 96l181.333 128-181.333 128v-256zM277.334 352v-256l181.334 128-181.333 128z" />
<glyph unicode="&#xe822;" d="M234.667 96v256l-181.333-128 181.333-128zM245.333 224l181.333-128v256l-181.333-128z" />
<glyph unicode="&#xe825;" d="M405.334 394.666h-298.666c-23.573 0-42.666-19.094-42.666-42.666v-256c0-23.574 19.093-42.666 42.666-42.666h298.666c23.574 0 42.666 19.094 42.666 42.666v256c0 23.573-19.094 42.666-42.666 42.666zM234.667 160h-32v42.666h-42.667v-42.666h-32v128h32v-53.334h42.666v53.334h32v-128zM384 181.334c0-11.733-9.493-21.334-21.334-21.334h-16v-32h-32v32h-16c-11.84 0-21.334 9.6-21.334 21.334v85.334c0 11.733 9.493 21.334 21.334 21.334h64c11.84 0 21.334-9.6 21.334-21.334v-85.334zM309.334 192h42.666v64h-42.666v-64z" />
<glyph unicode="&#xe830;" d="M128 74.666h85.334v298.666h-85.334v-298.666zM298.666 373.334v-298.666h85.334v298.666h-85.334z" />
<glyph unicode="&#xe831;" d="M256 437.334c-117.867 0-213.333-95.466-213.333-213.334s95.466-213.333 213.333-213.333 213.333 95.466 213.333 213.333-95.466 213.333-213.333 213.333zM234.667 138.666h-42.667v170.666h42.666v-170.666zM320 138.666h-42.666v170.666h42.666v-170.666z" />
<glyph unicode="&#xe832;" d="M192 138.666h42.666v170.666h-42.666v-170.666zM256 437.334c-117.867 0-213.333-95.466-213.333-213.334s95.466-213.333 213.333-213.333 213.333 95.466 213.333 213.333-95.466 213.333-213.333 213.333zM256 53.334c-94.080 0-170.667 76.587-170.667 170.667s76.587 170.667 170.667 170.667 170.667-76.587 170.667-170.667-76.587-170.667-170.667-170.667zM277.334 138.666h42.666v170.666h-42.666v-170.666z" />
<glyph unicode="&#xe834;" d="M256 437.334c-117.867 0-213.333-95.466-213.333-213.334s95.466-213.333 213.333-213.333 213.333 95.466 213.333 213.333-95.466 213.333-213.333 213.333zM213.333 128v192l128-96-128-96z" />
<glyph unicode="&#xe835;" d="M213.333 128l128 96-128 96v-192zM256 437.334c-117.867 0-213.333-95.466-213.333-213.334s95.466-213.333 213.333-213.333 213.333 95.466 213.333 213.333-95.466 213.333-213.333 213.333zM256 53.334c-94.080 0-170.667 76.587-170.667 170.667s76.587 170.667 170.667 170.667 170.667-76.587 170.667-170.667-76.587-170.667-170.667-170.667z" />
<glyph unicode="&#xe840;" d="M128 96l181.333 128-181.333 128v-256zM341.334 352v-256h42.666v256h-42.666z" />
<glyph unicode="&#xe841;" d="M128 352h42.666v-256h-42.666zM202.667 224l181.333-128v256z" />
<glyph unicode="&#xe849;" d="M394.666 224c0 37.654-21.76 70.187-53.334 85.866v-171.84c31.574 15.786 53.334 48.32 53.334 85.974zM106.666 288v-128h85.334l106.666-106.666v341.334l-106.666-106.666h-85.334z" />
<glyph unicode="&#xe84a;" d="M149.333 288v-128h85.333l106.666-106.666v341.334l-106.666-106.666h-85.334z" />
<glyph unicode="&#xe84b;" d="M352 224c0 37.654-21.76 70.187-53.334 85.866v-47.146l52.373-52.374c0.64 4.48 0.96 9.067 0.96 13.654zM405.334 224c0-20.053-4.373-38.933-11.52-56.32l32.32-32.32c13.866 26.56 21.866 56.64 21.866 88.64 0 91.307-63.894 167.68-149.333 187.094v-44.053c61.654-18.347 106.666-75.413 106.666-143.040zM91.2 416l-27.2-27.2 100.8-100.8h-100.8v-128h85.334l106.666-106.666v143.466l90.774-90.774c-14.293-10.986-30.4-19.84-48.106-25.173v-44.053c29.334 6.72 56.106 20.16 78.613 38.613l43.52-43.413 27.2 27.2-356.8 356.8zM256 394.666l-44.587-44.587 44.587-44.587v89.173z" />
<glyph unicode="&#xe84c;" d="M64 288v-128h85.334l106.666-106.666v341.334l-106.666-106.666h-85.334zM352 224c0 37.654-21.76 70.187-53.334 85.866v-171.84c31.574 15.786 53.334 48.32 53.334 85.974zM298.666 411.094v-44.053c61.654-18.347 106.666-75.413 106.666-143.040s-45.014-124.693-106.666-143.040v-44.053c85.44 19.413 149.334 95.68 149.334 187.094s-63.894 167.68-149.333 187.094z" />
<glyph unicode="&#xe866;" d="M256 352v-64l85.334 85.334-85.334 85.334v-64c-94.293 0-170.667-76.374-170.667-170.667 0-33.493 9.814-64.534 26.453-90.88l31.147 31.147c-9.494 17.813-14.933 38.080-14.933 59.733 0 70.72 57.28 128 128 128zM400.214 314.88l-31.147-31.147c9.493-17.814 14.933-38.080 14.933-59.733 0-70.72-57.28-128-128-128v64l-85.334-85.334 85.334-85.334v64c94.293 0 170.667 76.374 170.667 170.667 0 33.493-9.813 64.534-26.454 90.88z" />
<glyph unicode="&#xe891;" d="M64 202.666h42.666v42.666h-42.666v-42.666zM64 117.334h42.666v42.666h-42.666v-42.666zM64 288h42.666v42.666h-42.666v-42.666zM149.333 202.666h298.667v42.666h-298.666v-42.666zM149.333 117.334h298.667v42.666h-298.666v-42.666zM149.333 330.667v-42.667h298.667v42.666h-298.666z" />
<glyph unicode="&#xe8b1;" d="M414.507 203.2c0.853 6.827 1.493 13.76 1.493 20.8s-0.64 13.974-1.493 20.8l45.12 35.306c4.053 3.2 5.226 8.96 2.56 13.654l-42.666 73.92c-2.666 4.587-8.214 6.507-13.014 4.587l-53.12-21.44c-10.986 8.427-23.040 15.573-36.053 21.014l-8 56.533c-0.96 5.014-5.334 8.96-10.666 8.96h-85.334c-5.333 0-9.707-3.947-10.56-8.96l-8-56.533c-13.013-5.44-25.066-12.48-36.053-21.014l-53.12 21.44c-4.8 1.814-10.347 0-13.013-4.587l-42.666-73.92c-2.666-4.587-1.493-10.346 2.56-13.654l45.014-35.306c-0.853-6.827-1.493-13.76-1.493-20.8s0.64-13.974 1.493-20.8l-45.014-35.306c-4.053-3.2-5.227-8.96-2.56-13.654l42.666-73.92c2.666-4.587 8.213-6.507 13.013-4.587l53.12 21.44c10.987-8.426 23.040-15.574 36.053-21.014l8-56.534c0.853-5.014 5.226-8.96 10.56-8.96h85.334c5.334 0 9.707 3.947 10.56 8.96l8 56.534c13.014 5.44 25.067 12.48 36.053 21.014l53.12-21.44c4.8-1.813 10.346 0 13.014 4.587l42.666 73.92c2.666 4.587 1.493 10.346-2.56 13.654l-45.014 35.307zM256 149.334c-41.28 0-74.666 33.387-74.666 74.666s33.387 74.666 74.666 74.666 74.666-33.387 74.666-74.666-33.387-74.666-74.666-74.666z" />
</font></defs></svg>

After

Width:  |  Height:  |  Size: 10 KiB

BIN
src/css/font/VideoJS.ttf Executable file

Binary file not shown.

BIN
src/css/font/VideoJS.woff Executable file

Binary file not shown.

Binary file not shown.

View File

@ -1,28 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="icomoon" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" d="" horiz-adv-x="512" />
<glyph unicode="&#xe000;" d="M1024 960v-416l-160 160-192-192-96 96 192 192-160 160zM448 288l-192-192 160-160h-416v416l160-160 192 192z" />
<glyph unicode="&#xe001;" d="M192 832l640-384-640-384z" />
<glyph unicode="&#xe002;" d="M128 832h320v-768h-320zM576 832h320v-768h-320z" />
<glyph unicode="&#xe003;" d="M401.332 881.332c25.668 25.668 46.668 16.968 46.668-19.332v-828c0-36.3-21-44.998-46.668-19.33l-241.332 241.33h-160v384h160l241.332 241.332z" />
<glyph unicode="&#xe004;" d="M549.020 218.98c-12.286 0-24.568 4.686-33.942 14.058-18.746 18.746-18.746 49.136 0 67.882 81.1 81.1 81.1 213.058 0 294.156-18.746 18.746-18.746 49.138 0 67.882 18.746 18.744 49.136 18.744 67.882 0 118.53-118.53 118.53-311.392 0-429.922-9.372-9.37-21.656-14.056-33.94-14.056zM401.332 881.332c25.668 25.668 46.668 16.968 46.668-19.332v-828c0-36.3-21-44.998-46.668-19.33l-241.332 241.33h-160v384h160l241.332 241.332z" />
<glyph unicode="&#xe005;" d="M719.53 128.47c-12.286 0-24.568 4.686-33.942 14.058-18.744 18.744-18.744 49.136 0 67.882 131.006 131.006 131.006 344.17 0 475.176-18.744 18.746-18.744 49.138 0 67.882 18.744 18.742 49.138 18.744 67.882 0 81.594-81.592 126.53-190.076 126.53-305.468 0-115.39-44.936-223.876-126.53-305.47-9.372-9.374-21.656-14.060-33.94-14.060zM549.020 218.98c-12.286 0-24.568 4.686-33.942 14.058-18.746 18.746-18.746 49.136 0 67.882 81.1 81.1 81.1 213.058 0 294.156-18.746 18.746-18.746 49.138 0 67.882 18.746 18.744 49.136 18.744 67.882 0 118.53-118.53 118.53-311.392 0-429.922-9.372-9.37-21.656-14.056-33.94-14.056zM401.332 881.332c25.668 25.668 46.668 16.968 46.668-19.332v-828c0-36.3-21-44.998-46.668-19.33l-241.332 241.33h-160v384h160l241.332 241.332z" />
<glyph unicode="&#xe006;" d="M890.040 37.96c-12.286 0-24.568 4.686-33.942 14.058-18.744 18.746-18.744 49.136 0 67.882 87.638 87.642 135.904 204.16 135.904 328.1 0 123.938-48.266 240.458-135.904 328.098-18.744 18.746-18.744 49.138 0 67.882 18.744 18.744 49.138 18.744 67.882 0 105.77-105.772 164.022-246.4 164.022-395.98 0-149.582-58.252-290.208-164.022-395.98-9.372-9.374-21.656-14.060-33.94-14.060zM719.53 128.47c-12.286 0-24.568 4.686-33.942 14.058-18.744 18.744-18.744 49.136 0 67.882 131.006 131.006 131.006 344.17 0 475.176-18.744 18.746-18.744 49.138 0 67.882 18.744 18.742 49.138 18.744 67.882 0 81.594-81.592 126.53-190.076 126.53-305.468 0-115.39-44.936-223.876-126.53-305.47-9.372-9.374-21.656-14.060-33.94-14.060zM549.020 218.98c-12.286 0-24.568 4.686-33.942 14.058-18.746 18.746-18.746 49.136 0 67.882 81.1 81.1 81.1 213.058 0 294.156-18.746 18.746-18.746 49.138 0 67.882 18.746 18.744 49.136 18.744 67.882 0 118.53-118.53 118.53-311.392 0-429.922-9.372-9.37-21.656-14.056-33.94-14.056zM401.332 881.332c25.668 25.668 46.668 16.968 46.668-19.332v-828c0-36.3-21-44.998-46.668-19.33l-241.332 241.33h-160v384h160l241.332 241.332z" horiz-adv-x="1088" />
<glyph unicode="&#xe007;" d="M512 960l-320-512 320-512 320 512z" />
<glyph unicode="&#xe008;" d="M0 960h1374.316v-1030.414h-1374.316v1030.414zM1245.462 449.276c-1.706 180.052-8.542 258.568-51.2 314.036-7.68 11.946-22.186 18.772-34.132 27.296-41.814 30.73-238.944 41.814-467.636 41.814-228.702 0-435.21-11.084-476.17-41.814-12.8-8.524-27.316-15.35-35.84-27.296-41.822-55.468-47.786-133.984-50.346-314.036 2.56-180.062 8.524-258.57 50.346-314.036 8.524-12.8 23.040-18.774 35.84-27.306 40.96-31.574 247.468-41.814 476.17-43.52 228.692 1.706 425.822 11.946 467.636 43.52 11.946 8.532 26.452 14.506 34.132 27.306 42.658 55.466 49.494 133.974 51.2 314.036zM662.358 495.904c-11.58 140.898-86.51 223.906-220.556 223.906-122.458 0-218.722-110.432-218.722-287.88 0-178.212 87.73-289.396 232.734-289.396 115.766 0 196.798 85.298 209.588 226.95h-138.302c-5.48-52.548-27.414-92.914-73.72-92.914-73.108 0-86.51 72.354-86.51 149.27 0 105.868 30.46 159.932 81.032 159.932 45.082 0 73.718-32.75 77.976-89.868h136.48zM1140.026 495.904c-11.57 140.898-86.51 223.906-220.546 223.906-122.466 0-218.722-110.432-218.722-287.88 0-178.212 87.73-289.396 232.734-289.396 115.758 0 196.788 85.298 209.58 226.95h-138.304c-5.47-52.548-27.404-92.914-73.71-92.914-73.116 0-86.518 72.354-86.518 149.27 0 105.868 30.468 159.932 81.030 159.932 45.084 0 73.728-32.75 77.986-89.868h136.47z" horiz-adv-x="1374" />
<glyph unicode="&#xe009;" d="M128 832h768v-768h-768z" />
<glyph unicode="&#xe00a;" d="M384 832c0-70.692 57.308-128 128-128s128 57.308 128 128c0 70.692-57.308 128-128 128-70.692 0-128-57.308-128-128zM655.53 719.53c0-70.692 57.308-128 128-128s128 57.308 128 128c0 70.692-57.308 128-128 128-70.692 0-128-57.308-128-128zM832 448c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64zM719.53 176.47c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64zM448.002 64c0 0 0 0 0 0 0-35.346 28.654-64 64-64 35.346 0 64 28.654 64 64 0 0 0 0 0 0 0 0 0 0 0 0 0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64s0 0 0 0zM176.472 176.47c0 0 0 0 0 0 0-35.346 28.654-64 64-64 35.346 0 64 28.654 64 64 0 0 0 0 0 0 0 0 0 0 0 0 0 35.346-28.654 64-64 64-35.346 0-64-28.654-64-64s0 0 0 0zM144.472 719.53c0 0 0 0 0 0 0-53.019 42.981-96 96-96 53.019 0 96 42.981 96 96 0 0 0 0 0 0 0 0 0 0 0 0 0 53.019-42.981 96-96 96-53.019 0-96-42.981-96-96s0 0 0 0zM56 448c0-39.765 32.235-72 72-72s72 32.235 72 72c0 39.765-32.235 72-72 72-39.765 0-72-32.235-72-72z" />
<glyph unicode="&#xe00b;" d="M448 384v-416l-160 160-192-192-96 96 192 192-160 160zM1024 864l-192-192 160-160h-416v416l160-160 192 192z" />
<glyph unicode="&#xe00c;" d="M512 896c282.77 0 512-186.25 512-416 0-229.752-229.23-416-512-416-27.156 0-53.81 1.734-79.824 5.044-109.978-109.978-241.25-129.7-368.176-132.596v26.916c68.536 33.578 128 94.74 128 164.636 0 9.754-0.758 19.33-2.164 28.696-115.796 76.264-189.836 192.754-189.836 323.304 0 229.75 229.23 416 512 416z" />
<glyph unicode="&#xe00d;" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512 704c141.384 0 256-114.616 256-256s-114.616-256-256-256-256 114.616-256 256 114.616 256 256 256zM817.47 142.53c-81.594-81.594-190.080-126.53-305.47-126.53-115.392 0-223.876 44.936-305.47 126.53-81.594 81.594-126.53 190.078-126.53 305.47 0 115.39 44.936 223.876 126.53 305.47l67.882-67.882c0 0 0 0 0 0-131.006-131.006-131.006-344.17 0-475.176 63.462-63.462 147.838-98.412 237.588-98.412 89.748 0 174.124 34.95 237.588 98.412 131.006 131.006 131.006 344.168 0 475.176l67.882 67.882c81.594-81.594 126.53-190.080 126.53-305.47 0-115.392-44.936-223.876-126.53-305.47z" />
<glyph unicode="&#xe00e;" d="M864 256c-45.16 0-85.92-18.738-115.012-48.83l-431.004 215.502c1.314 8.252 2.016 16.706 2.016 25.328s-0.702 17.076-2.016 25.326l431.004 215.502c29.092-30.090 69.852-48.828 115.012-48.828 88.366 0 160 71.634 160 160s-71.634 160-160 160-160-71.634-160-160c0-8.622 0.704-17.076 2.016-25.326l-431.004-215.504c-29.092 30.090-69.852 48.83-115.012 48.83-88.366 0-160-71.636-160-160 0-88.368 71.634-160 160-160 45.16 0 85.92 18.738 115.012 48.828l431.004-215.502c-1.312-8.25-2.016-16.704-2.016-25.326 0-88.368 71.634-160 160-160s160 71.632 160 160c0 88.364-71.634 160-160 160z" />
<glyph unicode="&#xe01e;" d="M1024 448c-1.278 66.862-15.784 133.516-42.576 194.462-26.704 61-65.462 116.258-113.042 161.92-47.552 45.696-103.944 81.82-164.984 105.652-61.004 23.924-126.596 35.352-191.398 33.966-64.81-1.282-129.332-15.374-188.334-41.356-59.048-25.896-112.542-63.47-156.734-109.576-44.224-46.082-79.16-100.708-102.186-159.798-23.114-59.062-34.128-122.52-32.746-185.27 1.286-62.76 14.964-125.148 40.134-182.206 25.088-57.1 61.476-108.828 106.11-151.548 44.61-42.754 97.472-76.504 154.614-98.72 57.118-22.304 118.446-32.902 179.142-31.526 60.708 1.29 120.962 14.554 176.076 38.914 55.15 24.282 105.116 59.48 146.366 102.644 41.282 43.14 73.844 94.236 95.254 149.43 13.034 33.458 21.88 68.4 26.542 103.798 1.246-0.072 2.498-0.12 3.762-0.12 35.346 0 64 28.652 64 64 0 1.796-0.094 3.572-0.238 5.332h0.238zM922.306 278.052c-23.472-53.202-57.484-101.4-99.178-141.18-41.67-39.81-91-71.186-144.244-91.79-53.228-20.678-110.29-30.452-166.884-29.082-56.604 1.298-112.596 13.736-163.82 36.474-51.25 22.666-97.684 55.49-135.994 95.712-38.338 40.198-68.528 87.764-88.322 139.058-19.87 51.284-29.228 106.214-27.864 160.756 1.302 54.552 13.328 108.412 35.254 157.69 21.858 49.3 53.498 93.97 92.246 130.81 38.73 36.868 84.53 65.87 133.874 84.856 49.338 19.060 102.136 28.006 154.626 26.644 52.5-1.306 104.228-12.918 151.562-34.034 47.352-21.050 90.256-51.502 125.624-88.782 35.396-37.258 63.21-81.294 81.39-128.688 18.248-47.392 26.782-98.058 25.424-148.496h0.238c-0.144-1.76-0.238-3.536-0.238-5.332 0-33.012 24.992-60.174 57.086-63.624-6.224-34.822-16.53-68.818-30.78-100.992z" />
<glyph unicode="&#xe01f;" d="M512 960c-278.748 0-505.458-222.762-511.848-499.974 5.92 241.864 189.832 435.974 415.848 435.974 229.75 0 416-200.576 416-448 0-53.020 42.98-96 96-96 53.020 0 96 42.98 96 96 0 282.77-229.23 512-512 512zM512-64c278.748 0 505.458 222.762 511.848 499.974-5.92-241.864-189.832-435.974-415.848-435.974-229.75 0-416 200.576-416 448 0 53.020-42.98 96-96 96-53.020 0-96-42.98-96-96 0-282.77 229.23-512 512-512z" />
<glyph unicode="&#xe600;" d="M1024 351.906v192.188l-146.774 24.462c-5.958 18.132-13.222 35.668-21.694 52.5l86.454 121.034-135.896 135.898-120.826-86.304c-16.91 8.554-34.538 15.888-52.768 21.902l-24.402 146.414h-192.188l-24.402-146.416c-18.23-6.014-35.858-13.348-52.766-21.902l-120.828 86.304-135.898-135.898 86.454-121.036c-8.47-16.83-15.734-34.366-21.692-52.498l-146.774-24.46v-192.188l147.118-24.52c5.96-17.968 13.21-35.348 21.642-52.030l-86.748-121.448 135.898-135.896 121.654 86.894c16.602-8.35 33.89-15.528 51.764-21.434l24.578-147.472h192.188l24.578 147.474c17.874 5.906 35.162 13.084 51.766 21.432l121.652-86.892 135.896 135.896-86.744 121.446c8.432 16.682 15.678 34.062 21.64 52.032l147.118 24.518zM512 320c-70.692 0-128 57.306-128 128 0 70.692 57.308 128 128 128 70.694 0 128-57.308 128-128 0-70.694-57.306-128-128-128z" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

25
src/css/video-js.scss Normal file
View File

@ -0,0 +1,25 @@
@import "variables";
@import "utilities";
@import "components/icons";
@import "components/layout";
@import "components/big-play";
@import "components/control-bar";
@import "components/control";
@import "components/progress";
@import "components/slider";
@import "components/volume";
@import "components/menu";
@import "components/poster";
@import "components/live";
@import "components/time";
@import "components/play-pause";
@import "components/text-track";
@import "components/fullscreen";
@import "components/playback-rate";
@import "components/error";
@import "components/loading";
@import "components/captions";
@import "components/chapters";
@import "components/subtitles";
@import "components/adaptive";

16
src/js/base-styles.js Normal file
View File

@ -0,0 +1,16 @@
/**
* This code injects the required base styles in the head of the document.
*/
import window from 'global/window';
import document from 'global/document';
if (window.VIDEOJS_NO_BASE_THEME) return;
const styles = '{{GENERATED_STYLES}}';
if (styles === '{{GENERATED'+'_STYLES}}');
const styleNode = document.createElement('style');
styleNode.innerHTML = styles;
document.head.insertBefore(styleNode, document.head.firstChild);

View File

@ -5,7 +5,7 @@ import Button from './button';
/**
* Initial play button. Shows before the video has played. The hiding of the
* big play button is done via CSS and player states.
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @class
* @constructor
@ -20,7 +20,7 @@ class BigPlayButton extends Button {
});
}
onClick() {
handleClick() {
this.player_.play();
}

View File

@ -7,7 +7,7 @@ import document from 'global/document';
================================================================================ */
/**
* Base class for all buttons
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @class
* @constructor
@ -19,10 +19,10 @@ class Button extends Component {
this.emitTapEvents();
this.on('tap', this.onClick);
this.on('click', this.onClick);
this.on('focus', this.onFocus);
this.on('blur', this.onBlur);
this.on('tap', this.handleClick);
this.on('click', this.handleClick);
this.on('focus', this.handleFocus);
this.on('blur', this.handleBlur);
}
createEl(type, props) {
@ -55,30 +55,29 @@ class Button extends Component {
}
buildCSSClass() {
// TODO: Change vjs-control to vjs-button?
return 'vjs-control ' + super.buildCSSClass();
return `vjs-control vjs-button ${super.buildCSSClass()}`;
}
// Click - Override with specific functionality for button
onClick() {}
handleClick() {}
// Focus - Add keyboard functionality to element
onFocus() {
Events.on(document, 'keydown', Lib.bind(this, this.onKeyPress));
handleFocus() {
Events.on(document, 'keydown', Lib.bind(this, this.handleKeyPress));
}
// KeyPress (document level) - Trigger click when keys are pressed
onKeyPress(event) {
handleKeyPress(event) {
// Check for space bar (32) or enter (13) keys
if (event.which == 32 || event.which == 13) {
event.preventDefault();
this.onClick();
this.handleClick();
}
}
// Blur - Remove keyboard triggers
onBlur() {
Events.off(document, 'keydown', Lib.bind(this, this.onKeyPress));
handleBlur() {
Events.off(document, 'keydown', Lib.bind(this, this.handleKeyPress));
}
}

View File

@ -35,7 +35,6 @@ import window from 'global/window';
* @param {Object=} options
* @class
* @constructor
* @extends vjs.CoreObject
*/
class Component {
@ -60,7 +59,8 @@ class Component {
// If there was no ID from the options, generate one
if (!this.id_) {
// Don't require the player ID function in the case of mock players
this.id_ = ((player.id && player.id()) || 'no_player') + '_component_' + Lib.guid++;
let id = player.id && player.id() || 'no_player';
this.id_ = `${id}_component_${Lib.guid++}`;
}
this.name_ = options['name'] || null;
@ -131,7 +131,7 @@ class Component {
/**
* Return the component's player
*
* @return {vjs.Player}
* @return {Player}
*/
player() {
return this.player_;
@ -141,7 +141,7 @@ class Component {
* Deep merge of options objects
*
* Whenever a property is an object on both options objects
* the two properties will be merged using vjs.obj.deepMerge.
* the two properties will be merged using Lib.obj.deepMerge.
*
* This is used for merging options for child components. We
* want it to be easy to override individual options on a child
@ -207,11 +207,13 @@ class Component {
}
localize(string){
var lang = this.player_.language(),
languages = this.player_.languages();
let lang = this.player_.language();
let languages = this.player_.languages();
if (languages && languages[lang] && languages[lang][string]) {
return languages[lang][string];
}
return string;
}
@ -261,7 +263,7 @@ class Component {
/**
* Returns a child component with the provided ID
*
* @return {vjs.Component}
* @return {Component}
*/
getChildById(id){
return this.childIndex_[id];
@ -270,7 +272,7 @@ class Component {
/**
* Returns a child component with the provided name
*
* @return {vjs.Component}
* @return {Component}
*/
getChild(name){
return this.childNameIndex_[name];
@ -299,21 +301,27 @@ class Component {
* }
* });
*
* @param {String|vjs.Component} child The class name or instance of a child to add
* @param {String|Component} child The class name or instance of a child to add
* @param {Object=} options Options, including options to be passed to children of the child.
* @return {vjs.Component} The child component (created by this process if a string was used)
* @return {Component} The child component (created by this process if a string was used)
* @suppress {accessControls|checkRegExp|checkTypes|checkVars|const|constantProperty|deprecated|duplicate|es5Strict|fileoverviewTags|globalThis|invalidCasts|missingProperties|nonStandardJsDocs|strictModuleDepCheck|undefinedNames|undefinedVars|unknownDefines|uselessCode|visibility}
*/
addChild(child, options){
addChild(child, options={}){
let component;
let componentName;
// If child is a string, create nt with options
if (typeof child === 'string') {
let componentName = child;
componentName = child;
// Make sure options is at least an empty object to protect against errors
if (!options || options === true) {
// Options can also be specified as a boolean, so convert to an empty object if false.
if (!options) {
options = {};
}
// Same as above, but true is deprecated so show a warning.
if (options === true) {
Lib.log.warn('Initializing a child component with `true` is deprecated. Children should be defined in an array when possible, but if necessary use an object instead of `true`.');
options = {};
}
@ -326,8 +334,6 @@ class Component {
// Create a new object & element for this controls set
// If there's no .player_, this is a player
// Closure Compiler throws an 'incomplete alias' warning if we use the vjs variable directly.
// Every class should be exported, so this should never be a problem here.
let componentClass = Component.getComponent(componentClassName);
component = new componentClass(this.player_ || this, options);
@ -365,7 +371,7 @@ class Component {
* Remove a child component from this component's list of children, and the
* child component's element from this component's element
*
* @param {vjs.Component} component Component to remove
* @param {Component} component Component to remove
*/
removeChild(component){
if (typeof component === 'string') {
@ -443,7 +449,7 @@ class Component {
}
// Allow for disabling default components
// e.g. vjs.options['children']['posterImage'] = false
// e.g. options['children']['posterImage'] = false
if (opts === false) return;
// Create and add the child component.
@ -505,36 +511,34 @@ class Component {
* myComponent.on(otherElement, 'eventName', myFunc);
* myComponent.on(otherComponent, 'eventName', myFunc);
*
* The benefit of using this over `vjs.on(otherElement, 'eventName', myFunc)`
* The benefit of using this over `VjsEvents.on(otherElement, 'eventName', myFunc)`
* and `otherComponent.on('eventName', myFunc)` is that this way the listeners
* will be automatically cleaned up when either component is disposed.
* It will also bind myComponent as the context of myFunc.
*
* **NOTE**: When using this on elements in the page other than window
* and document (both permanent), if you remove the element from the DOM
* you need to call `vjs.trigger(el, 'dispose')` on it to clean up
* you need to call `myComponent.trigger(el, 'dispose')` on it to clean up
* references to it and allow the browser to garbage collect it.
*
* @param {String|vjs.Component} first The event type or other component
* @param {String|Component} first The event type or other component
* @param {Function|String} second The event handler or event type
* @param {Function} third The event handler
* @return {vjs.Component} self
* @return {Component} self
*/
on(first, second, third){
var target, type, fn, removeOnDispose, cleanRemover, thisComponent;
if (typeof first === 'string' || Lib.obj.isArray(first)) {
Events.on(this.el_, first, Lib.bind(this, second));
// Targeting another component or element
} else {
target = first;
type = second;
fn = Lib.bind(this, third);
thisComponent = this;
const target = first;
const type = second;
const fn = Lib.bind(this, third);
const thisComponent = this;
// When this component is disposed, remove the listener from the other component
removeOnDispose = function(){
const removeOnDispose = function(){
thisComponent.off(target, type, fn);
};
// Use the same function ID so we can remove it later it using the ID
@ -545,7 +549,7 @@ class Component {
// If the other component is disposed first we need to clean the reference
// to the other component in this component's removeOnDispose listener
// Otherwise we create a memory leak.
cleanRemover = function(){
const cleanRemover = function(){
thisComponent.off('dispose', removeOnDispose);
};
// Add the same function ID so we can easily remove it later
@ -558,7 +562,7 @@ class Component {
Events.on(target, 'dispose', cleanRemover);
// Should be a component
// Not using `instanceof vjs.Component` because it makes mock players difficult
// Not using `instanceof Component` because it makes mock players difficult
} else if (typeof first.on === 'function') {
// Add the listener to the other component
target.on(type, fn);
@ -584,21 +588,19 @@ class Component {
* myComponent.off(otherElement, 'eventType', myFunc);
* myComponent.off(otherComponent, 'eventType', myFunc);
*
* @param {String=|vjs.Component} first The event type or other component
* @param {String=|Component} first The event type or other component
* @param {Function=|String} second The listener function or event type
* @param {Function=} third The listener for other component
* @return {vjs.Component}
* @return {Component}
*/
off(first, second, third){
var target, otherComponent, type, fn, otherEl;
if (!first || typeof first === 'string' || Lib.obj.isArray(first)) {
Events.off(this.el_, first, second);
} else {
target = first;
type = second;
const target = first;
const type = second;
// Ensure there's at least a guid, even if the function hasn't been used
fn = Lib.bind(this, third);
const fn = Lib.bind(this, third);
// Remove the dispose listener on this component,
// which was given the same guid as the event listener
@ -629,23 +631,21 @@ class Component {
* myComponent.one(otherElement, 'eventName', myFunc);
* myComponent.one(otherComponent, 'eventName', myFunc);
*
* @param {String|vjs.Component} first The event type or other component
* @param {String|Component} first The event type or other component
* @param {Function|String} second The listener function or event type
* @param {Function=} third The listener function for other component
* @return {vjs.Component}
* @return {Component}
*/
one(first, second, third) {
var target, type, fn, thisComponent, newFunc;
if (typeof first === 'string' || Lib.obj.isArray(first)) {
Events.one(this.el_, first, Lib.bind(this, second));
} else {
target = first;
type = second;
fn = Lib.bind(this, third);
thisComponent = this;
const target = first;
const type = second;
const fn = Lib.bind(this, third);
const thisComponent = this;
newFunc = function(){
const newFunc = function(){
thisComponent.off(target, type, newFunc);
fn.apply(this, arguments);
};
@ -665,7 +665,7 @@ class Component {
* myComponent.trigger({'type':'eventName'});
*
* @param {Event|Object|String} event A string (the type) or an event object with a type attribute
* @return {vjs.Component} self
* @return {Component} self
*/
trigger(event){
Events.trigger(this.el_, event);
@ -679,7 +679,7 @@ class Component {
* it will trigger the function immediately.
*
* @param {Function} fn Ready listener
* @return {vjs.Component}
* @return {Component}
*/
ready(fn){
if (fn) {
@ -696,7 +696,7 @@ class Component {
/**
* Trigger the ready listeners
*
* @return {vjs.Component}
* @return {Component}
*/
triggerReady(){
this.isReady_ = true;
@ -721,7 +721,7 @@ class Component {
* Check if a component's element has a CSS class name
*
* @param {String} classToCheck Classname to check
* @return {vjs.Component}
* @return {Component}
*/
hasClass(classToCheck){
return Lib.hasClass(this.el_, classToCheck);
@ -731,7 +731,7 @@ class Component {
* Add a CSS class name to the component's element
*
* @param {String} classToAdd Classname to add
* @return {vjs.Component}
* @return {Component}
*/
addClass(classToAdd){
Lib.addClass(this.el_, classToAdd);
@ -742,7 +742,7 @@ class Component {
* Remove a CSS class name from the component's element
*
* @param {String} classToRemove Classname to remove
* @return {vjs.Component}
* @return {Component}
*/
removeClass(classToRemove){
Lib.removeClass(this.el_, classToRemove);
@ -752,7 +752,7 @@ class Component {
/**
* Show the component element if hidden
*
* @return {vjs.Component}
* @return {Component}
*/
show(){
this.removeClass('vjs-hidden');
@ -762,7 +762,7 @@ class Component {
/**
* Hide the component element if currently showing
*
* @return {vjs.Component}
* @return {Component}
*/
hide(){
this.addClass('vjs-hidden');
@ -773,7 +773,7 @@ class Component {
* Lock an item in its visible state
* To be used with fadeIn/fadeOut.
*
* @return {vjs.Component}
* @return {Component}
* @private
*/
lockShowing(){
@ -785,7 +785,7 @@ class Component {
* Unlock an item to be hidden
* To be used with fadeIn/fadeOut.
*
* @return {vjs.Component}
* @return {Component}
* @private
*/
unlockShowing(){
@ -803,7 +803,7 @@ class Component {
*
* @param {Number|String=} num Optional width number
* @param {Boolean} skipListeners Skip the 'resize' event trigger
* @return {vjs.Component} This component, when setting the width
* @return {Component} This component, when setting the width
* @return {Number|String} The width, when getting
*/
width(num, skipListeners){
@ -820,7 +820,7 @@ class Component {
*
* @param {Number|String=} num New component height
* @param {Boolean=} skipListeners Skip the resize event trigger
* @return {vjs.Component} This component, when setting the height
* @return {Component} This component, when setting the height
* @return {Number|String} The height, when getting
*/
height(num, skipListeners){
@ -832,7 +832,7 @@ class Component {
*
* @param {Number|String} width
* @param {Number|String} height
* @return {vjs.Component} The component
* @return {Component} The component
*/
dimensions(width, height){
// Skip resize listeners on width for optimization
@ -853,7 +853,7 @@ class Component {
* @param {String} widthOrHeight 'width' or 'height'
* @param {Number|String=} num New dimension
* @param {Boolean=} skipListeners Skip resize event trigger
* @return {vjs.Component} The component if a dimension was set
* @return {Component} The component if a dimension was set
* @return {Number|String} The dimension if nothing was set
* @private
*/
@ -902,7 +902,7 @@ class Component {
// Only difference is if the element is hidden it will return
// the percent value (e.g. '100%'')
// instead of zero like offsetWidth returns.
// var val = vjs.getComputedStyleValue(this.el_, widthOrHeight);
// var val = Lib.getComputedStyleValue(this.el_, widthOrHeight);
// var pxIndex = val.indexOf('px');
// if (pxIndex !== -1) {
@ -924,20 +924,18 @@ class Component {
* @private
*/
emitTapEvents(){
var touchStart, firstTouch, touchTime, couldBeTap, noTap,
xdiff, ydiff, touchDistance, tapMovementThreshold, touchTimeThreshold;
// Track the start time so we can determine how long the touch lasted
touchStart = 0;
firstTouch = null;
let touchStart = 0;
let firstTouch = null;
// Maximum movement allowed during a touch event to still be considered a tap
// Other popular libs use anywhere from 2 (hammer.js) to 15, so 10 seems like a nice, round number.
tapMovementThreshold = 10;
const tapMovementThreshold = 10;
// The maximum length a touch can be while still being considered a tap
touchTimeThreshold = 200;
const touchTimeThreshold = 200;
let couldBeTap;
this.on('touchstart', function(event) {
// If more than one finger, don't consider treating this as a click
if (event.touches.length === 1) {
@ -956,16 +954,16 @@ class Component {
} else if (firstTouch) {
// Some devices will throw touchmoves for all but the slightest of taps.
// So, if we moved only a small distance, this could still be a tap
xdiff = event.touches[0].pageX - firstTouch.pageX;
ydiff = event.touches[0].pageY - firstTouch.pageY;
touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
const xdiff = event.touches[0].pageX - firstTouch.pageX;
const ydiff = event.touches[0].pageY - firstTouch.pageY;
const touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
if (touchDistance > tapMovementThreshold) {
couldBeTap = false;
}
}
});
noTap = function(){
const noTap = function(){
couldBeTap = false;
};
// TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s
@ -979,14 +977,14 @@ class Component {
// Proceed only if the touchmove/leave/cancel event didn't happen
if (couldBeTap === true) {
// Measure how long the touch lasted
touchTime = new Date().getTime() - touchStart;
const touchTime = new Date().getTime() - touchStart;
// Make sure the touch was less than the threshold to be considered a tap
if (touchTime < touchTimeThreshold) {
event.preventDefault(); // Don't let browser turn this into a click
this.trigger('tap');
// It may be good to copy the touchend event object and change the
// type to tap, if the other event properties aren't exact after
// vjs.fixEvent runs (e.g. event.target)
// Lib.fixEvent runs (e.g. event.target)
}
}
});
@ -1016,16 +1014,15 @@ class Component {
* want touch events to act differently.
*/
enableTouchActivity() {
var report, touchHolding, touchEnd;
// Don't continue if the root player doesn't support reporting user activity
if (!this.player().reportUserActivity) {
return;
}
// listener for reporting that the user is active
report = Lib.bind(this.player(), this.player().reportUserActivity);
const report = Lib.bind(this.player(), this.player().reportUserActivity);
let touchHolding;
this.on('touchstart', function() {
report();
// For as long as the they are touching the device or have their mouse down,
@ -1036,7 +1033,7 @@ class Component {
touchHolding = this.setInterval(report, 250);
});
touchEnd = function(event) {
const touchEnd = function(event) {
report();
// stop the interval that maintains activity if the touch is holding
this.clearInterval(touchHolding);
@ -1063,7 +1060,7 @@ class Component {
this.clearTimeout(timeoutId);
};
disposeFn.guid = 'vjs-timeout-'+ timeoutId;
disposeFn.guid = `vjs-timeout-${timeoutId}`;
this.on('dispose', disposeFn);
@ -1080,7 +1077,7 @@ class Component {
clearTimeout(timeoutId);
var disposeFn = function(){};
disposeFn.guid = 'vjs-timeout-'+ timeoutId;
disposeFn.guid = `vjs-timeout-${timeoutId}`;
this.off('dispose', disposeFn);
@ -1102,7 +1099,7 @@ class Component {
this.clearInterval(intervalId);
};
disposeFn.guid = 'vjs-interval-'+ intervalId;
disposeFn.guid = `vjs-interval-${intervalId}`;
this.on('dispose', disposeFn);
@ -1118,7 +1115,7 @@ class Component {
clearInterval(intervalId);
var disposeFn = function(){};
disposeFn.guid = 'vjs-interval-'+ intervalId;
disposeFn.guid = `vjs-interval-${intervalId}`;
this.off('dispose', disposeFn);
@ -1140,7 +1137,7 @@ class Component {
}
if (window && window.videojs && window.videojs[name]) {
Lib.log.warn('The '+name+' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)');
Lib.log.warn(`The ${name} component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)`);
return window.videojs[name];
}
}

View File

@ -3,10 +3,10 @@ import * as Lib from '../lib.js';
// Required children
import PlayToggle from './play-toggle.js';
import CurrentTimeDisplay from './current-time-display.js';
import DurationDisplay from './duration-display.js';
import TimeDivider from './time-divider.js';
import RemainingTimeDisplay from './remaining-time-display.js';
import CurrentTimeDisplay from './time-controls/current-time-display.js';
import DurationDisplay from './time-controls/duration-display.js';
import TimeDivider from './time-controls/time-divider.js';
import RemainingTimeDisplay from './time-controls/remaining-time-display.js';
import LiveDisplay from './live-display.js';
import ProgressControl from './progress-control/progress-control.js';
import FullscreenToggle from './fullscreen-toggle.js';
@ -17,14 +17,15 @@ import ChaptersButton from './text-track-controls/chapters-button.js';
import SubtitlesButton from './text-track-controls/subtitles-button.js';
import CaptionsButton from './text-track-controls/captions-button.js';
import PlaybackRateMenuButton from './playback-rate-menu/playback-rate-menu-button.js';
import CustomControlSpacer from './spacer-controls/custom-control-spacer.js';
/**
* Container of main controls
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @class
* @constructor
* @extends vjs.Component
* @extends Component
*/
class ControlBar extends Component {
createEl() {
@ -36,24 +37,25 @@ class ControlBar extends Component {
ControlBar.prototype.options_ = {
loadEvent: 'play',
children: {
'playToggle': {},
'currentTimeDisplay': {},
'timeDivider': {},
'durationDisplay': {},
'remainingTimeDisplay': {},
'liveDisplay': {},
'progressControl': {},
'fullscreenToggle': {},
'volumeControl': {},
'muteToggle': {},
// 'volumeMenuButton': {},
'playbackRateMenuButton': {},
'subtitlesButton': {},
'captionsButton': {},
'chaptersButton': {}
}
children: [
'playToggle',
'currentTimeDisplay',
'timeDivider',
'durationDisplay',
'progressControl',
'liveDisplay',
'remainingTimeDisplay',
'customControlSpacer',
'playbackRateMenuButton',
'muteToggle',
'volumeControl',
'chaptersButton',
'subtitlesButton',
'captionsButton',
'volumeMenuButton',
'fullscreenToggle'
]
};
Component.registerComponent('ControlBar', ControlBar);
export default ControlBar;
export default ControlBar;

View File

@ -2,7 +2,7 @@ import Button from '../button';
/**
* Toggle fullscreen video
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @class
* @extends vjs.Button
@ -10,10 +10,10 @@ import Button from '../button';
class FullscreenToggle extends Button {
buildCSSClass() {
return 'vjs-fullscreen-control ' + super.buildCSSClass();
return `vjs-fullscreen-control ${super.buildCSSClass()}`;
}
onClick() {
handleClick() {
if (!this.player_.isFullscreen()) {
this.player_.requestFullscreen();
this.controlText_.innerHTML = this.localize('Non-Fullscreen');

View File

@ -4,7 +4,7 @@ import * as Lib from '../lib';
/**
* Displays the live indicator
* TODO - Future make it click to snap to live
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -12,12 +12,12 @@ class LiveDisplay extends Component {
createEl() {
var el = super.createEl('div', {
className: 'vjs-live-controls vjs-control'
className: 'vjs-live-control vjs-control'
});
this.contentEl_ = Lib.createEl('div', {
className: 'vjs-live-display',
innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE'),
innerHTML: `<span class="vjs-control-text">${this.localize('Stream Type')}</span>${this.localize('LIVE')}`,
'aria-live': 'off'
});

View File

@ -5,7 +5,7 @@ import * as Lib from '../lib';
/**
* A button component for muting the audio
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -32,12 +32,16 @@ class MuteToggle extends Button {
createEl() {
return super.createEl('div', {
className: 'vjs-mute-control vjs-control',
innerHTML: '<div><span class="vjs-control-text">' + this.localize('Mute') + '</span></div>'
className: this.buildCSSClass(),
innerHTML: `<div><span class="vjs-control-text">${this.localize('Mute')}</span></div>`
});
}
onClick() {
buildCSSClass() {
return `vjs-mute-control ${super.buildCSSClass()}`;
}
handleClick() {
this.player_.muted( this.player_.muted() ? false : true );
}
@ -64,9 +68,9 @@ class MuteToggle extends Button {
/* TODO improve muted icon classes */
for (var i = 0; i < 4; i++) {
Lib.removeClass(this.el_, 'vjs-vol-'+i);
Lib.removeClass(this.el_, `vjs-vol-${i}`);
}
Lib.addClass(this.el_, 'vjs-vol-'+level);
Lib.addClass(this.el_, `vjs-vol-${level}`);
}
}

View File

@ -3,7 +3,7 @@ import * as Lib from '../lib';
/**
* Button to toggle between play and pause
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @class
* @constructor
@ -13,16 +13,16 @@ class PlayToggle extends Button {
constructor(player, options){
super(player, options);
this.on(player, 'play', this.onPlay);
this.on(player, 'pause', this.onPause);
this.on(player, 'play', this.handlePlay);
this.on(player, 'pause', this.handlePause);
}
buildCSSClass() {
return 'vjs-play-control ' + super.buildCSSClass();
return `vjs-play-control ${super.buildCSSClass()}`;
}
// OnClick - Toggle between play and pause
onClick() {
// handleClick - Toggle between play and pause
handleClick() {
if (this.player_.paused()) {
this.player_.play();
} else {
@ -30,15 +30,15 @@ class PlayToggle extends Button {
}
}
// OnPlay - Add the vjs-playing class to the element so it can change appearance
onPlay() {
// handlePlay - Add the vjs-playing class to the element so it can change appearance
handlePlay() {
this.removeClass('vjs-paused');
this.addClass('vjs-playing');
this.el_.children[0].children[0].innerHTML = this.localize('Pause'); // change the button text to "Pause"
}
// OnPause - Add the vjs-paused class to the element so it can change appearance
onPause() {
// handlePause - Add the vjs-paused class to the element so it can change appearance
handlePause() {
this.removeClass('vjs-playing');
this.addClass('vjs-paused');
this.el_.children[0].children[0].innerHTML = this.localize('Play'); // change the button text to "Play"

View File

@ -6,7 +6,7 @@ import * as Lib from '../../lib.js';
/**
* The component for controlling the playback rate
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -56,7 +56,7 @@ class PlaybackRateMenuButton extends MenuButton {
this.el().setAttribute('aria-valuenow', this.player().playbackRate());
}
onClick() {
handleClick() {
// select next rate option
let currentRate = this.player().playbackRate();
let rates = this.player().options()['playbackRates'];

View File

@ -22,8 +22,8 @@ class PlaybackRateMenuItem extends MenuItem {
this.on(player, 'ratechange', this.update);
}
onClick() {
super.onClick();
handleClick() {
super.handleClick();
this.player().playbackRate(this.rate);
}
@ -36,4 +36,4 @@ class PlaybackRateMenuItem extends MenuItem {
PlaybackRateMenuItem.prototype.contentElType = 'button';
MenuItem.registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem);
export default PlaybackRateMenuItem;
export default PlaybackRateMenuItem;

View File

@ -4,7 +4,7 @@ import * as Lib from '../../lib.js';
/**
* Shows load progress
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -18,7 +18,7 @@ class LoadProgressBar extends Component {
createEl() {
return super.createEl('div', {
className: 'vjs-load-progress',
innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>'
innerHTML: `<span class="vjs-control-text"><span>${this.localize('Loaded')}</span>: 0%</span>`
});
}
@ -61,4 +61,4 @@ class LoadProgressBar extends Component {
}
Component.registerComponent('LoadProgressBar', LoadProgressBar);
export default LoadProgressBar;
export default LoadProgressBar;

View File

@ -3,7 +3,7 @@ import Component from '../../component.js';
/**
* Shows play progress
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -12,11 +12,11 @@ class PlayProgressBar extends Component {
createEl() {
return super.createEl('div', {
className: 'vjs-play-progress',
innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
innerHTML: `<span class="vjs-control-text"><span>${this.localize('Progress')}</span>: 0%</span>`
});
}
}
Component.registerComponent('PlayProgressBar', PlayProgressBar);
export default PlayProgressBar;
export default PlayProgressBar;

View File

@ -5,7 +5,7 @@ import SeekBar from './seek-bar.js';
* The Progress Control component contains the seek bar, load progress,
* and play progress
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/

View File

@ -7,7 +7,7 @@ import * as Lib from '../../lib.js';
/**
* Seek Bar and holder for the progress bars
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -28,7 +28,7 @@ class SeekBar extends Slider {
updateARIAAttributes() {
// Allows for smooth scrubbing, when player can't keep up.
let time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime();
let time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
this.el_.setAttribute('aria-valuenow', Lib.round(this.getPercent()*100, 2)); // machine readable value of progress bar (percentage complete)
this.el_.setAttribute('aria-valuetext', Lib.formatTime(time, this.player_.duration())); // human readable value of progress bar (time complete)
}
@ -37,17 +37,16 @@ class SeekBar extends Slider {
return this.player_.currentTime() / this.player_.duration();
}
onMouseDown(event) {
super.onMouseDown(event);
handleMouseDown(event) {
super.handleMouseDown(event);
this.player_.scrubbing = true;
this.player_.addClass('vjs-scrubbing');
this.player_.scrubbing(true);
this.videoWasPlaying = !this.player_.paused();
this.player_.pause();
}
onMouseMove(event) {
handleMouseMove(event) {
let newTime = this.calculateDistance(event) * this.player_.duration();
// Don't let video end while scrubbing.
@ -57,11 +56,10 @@ class SeekBar extends Slider {
this.player_.currentTime(newTime);
}
onMouseUp(event) {
super.onMouseUp(event);
handleMouseUp(event) {
super.handleMouseUp(event);
this.player_.scrubbing = false;
this.player_.removeClass('vjs-scrubbing');
this.player_.scrubbing(false);
if (this.videoWasPlaying) {
this.player_.play();
}

View File

@ -5,7 +5,7 @@ import * as Lib from '../../lib.js';
* The Seek Handle shows the current position of the playhead during playback,
* and can be dragged to adjust the playhead.
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -18,7 +18,7 @@ class SeekHandle extends SliderHandle {
/** @inheritDoc */
createEl() {
return super.createEl.call('div', {
return super.createEl('div', {
className: 'vjs-seek-handle',
'aria-live': 'off'
});
@ -26,7 +26,7 @@ class SeekHandle extends SliderHandle {
updateContent() {
let time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime();
this.el_.innerHTML = '<span class="vjs-control-text">' + Lib.formatTime(time, this.player_.duration()) + '</span>';
this.el_.innerHTML = `<span class="vjs-control-text">${Lib.formatTime(time, this.player_.duration())}</span>`;
}
}
@ -40,4 +40,4 @@ class SeekHandle extends SliderHandle {
SeekHandle.prototype.defaultValue = '00:00';
SliderHandle.registerComponent('SeekHandle', SeekHandle);
export default SeekHandle;
export default SeekHandle;

View File

@ -0,0 +1,23 @@
import Spacer from './spacer.js';
/**
* Spacer specifically meant to be used as an insertion point for new plugins, etc.
*
* @param {Player|Object} player
* @param {Obect=} options
*/
class CustomControlSpacer extends Spacer {
buildCSSClass() {
return `vjs-custom-control-spacer ${super.buildCSSClass()}`;
}
createEl() {
return super.createEl({
className: this.buildCSSClass()
});
}
}
Spacer.registerComponent('CustomControlSpacer', CustomControlSpacer);
export default CustomControlSpacer;

View File

@ -0,0 +1,24 @@
import Component from '../../component.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.
*
* @param {Player|Object} player
* @param {Object=} options
*/
class Spacer extends Component {
buildCSSClass() {
return `vjs-spacer ${super.buildCSSClass()}`;
}
createEl(props) {
return super.createEl('div', {
className: this.buildCSSClass()
});
}
}
Component.registerComponent('Spacer', Spacer);
export default Spacer;

View File

@ -15,11 +15,11 @@ class CaptionSettingsMenuItem extends TextTrackMenuItem {
this.addClass('vjs-texttrack-settings');
}
onClick() {
handleClick() {
this.player().getChild('textTrackSettings').show();
}
}
TextTrackMenuItem.registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem);
export default CaptionSettingsMenuItem;
export default CaptionSettingsMenuItem;

View File

@ -21,8 +21,8 @@ class ChaptersTrackMenuItem extends MenuItem {
track.addEventListener('cuechange', Lib.bind(this, this.update));
}
onClick() {
super.onClick();
handleClick() {
super.handleClick();
this.player_.currentTime(this.cue.startTime);
this.update(this.cue.startTime);
}

View File

@ -58,11 +58,11 @@ class TextTrackMenuItem extends MenuItem {
}
}
onClick(event) {
handleClick(event) {
let kind = this.track['kind'];
let tracks = this.player_.textTracks();
super.onClick(event);
super.handleClick(event);
if (!tracks) return;
@ -88,4 +88,4 @@ class TextTrackMenuItem extends MenuItem {
}
MenuItem.registerComponent('TextTrackMenuItem', TextTrackMenuItem);
export default TextTrackMenuItem;
export default TextTrackMenuItem;

View File

@ -1,9 +1,9 @@
import Component from '../component.js';
import * as Lib from '../lib.js';
import Component from '../../component.js';
import * as Lib from '../../lib.js';
/**
* Displays the current time
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -17,7 +17,7 @@ class CurrentTimeDisplay extends Component {
createEl() {
let el = super.createEl('div', {
className: 'vjs-current-time vjs-time-controls vjs-control'
className: 'vjs-current-time vjs-time-control vjs-control'
});
this.contentEl_ = Lib.createEl('div', {
@ -33,7 +33,9 @@ class CurrentTimeDisplay extends Component {
updateContent() {
// Allows for smooth scrubbing, when player can't keep up.
let time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime();
this.contentEl_.innerHTML = '<span class="vjs-control-text">' + this.localize('Current Time') + '</span> ' + Lib.formatTime(time, this.player_.duration());
let localizedText = this.localize('Current Time');
let formattedTime = Lib.formatTime(time, this.player_.duration());
this.contentEl_.innerHTML = `<span class="vjs-control-text">${localizedText}</span> ${formattedTime}`;
}
}

View File

@ -1,9 +1,9 @@
import Component from '../component.js';
import * as Lib from '../lib.js';
import Component from '../../component.js';
import * as Lib from '../../lib.js';
/**
* Displays the duration
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -22,12 +22,12 @@ class DurationDisplay extends Component {
createEl() {
let el = super.createEl('div', {
className: 'vjs-duration vjs-time-controls vjs-control'
className: 'vjs-duration vjs-time-control vjs-control'
});
this.contentEl_ = Lib.createEl('div', {
className: 'vjs-duration-display',
innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> ' + '0:00', // label the duration time for screen reader users
innerHTML: `<span class="vjs-control-text">${this.localize('Duration Time')}</span> 0:00`, // label the duration time for screen reader users
'aria-live': 'off' // tell screen readers not to automatically read the time as it changes
});
@ -38,7 +38,9 @@ class DurationDisplay extends Component {
updateContent() {
let duration = this.player_.duration();
if (duration) {
this.contentEl_.innerHTML = '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> ' + Lib.formatTime(duration); // label the duration time for screen reader users
let localizedText = this.localize('Duration Time');
let formattedTime = Lib.formatTime(duration);
this.contentEl_.innerHTML = `<span class="vjs-control-text">${localizedText}</span> ${formattedTime}`; // label the duration time for screen reader users
}
}

View File

@ -1,5 +1,5 @@
import Component from '../component.js';
import * as Lib from '../lib';
import Component from '../../component.js';
import * as Lib from '../../lib';
/**
* Displays the time left in the video
@ -17,12 +17,12 @@ class RemainingTimeDisplay extends Component {
createEl() {
let el = super.createEl('div', {
className: 'vjs-remaining-time vjs-time-controls vjs-control'
className: 'vjs-remaining-time vjs-time-control vjs-control'
});
this.contentEl_ = Lib.createEl('div', {
className: 'vjs-remaining-time-display',
innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> ' + '-0:00', // label the remaining time for screen reader users
innerHTML: `<span class="vjs-control-text">${this.localize('Remaining Time')}</span> -0:00`, // label the remaining time for screen reader users
'aria-live': 'off' // tell screen readers not to automatically read the time as it changes
});
@ -32,7 +32,9 @@ class RemainingTimeDisplay extends Component {
updateContent() {
if (this.player_.duration()) {
this.contentEl_.innerHTML = '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> ' + '-'+ Lib.formatTime(this.player_.remainingTime());
const localizedText = this.localize('Remaining Time');
const formattedTime = Lib.formatTime(this.player_.remainingTime());
this.contentEl_.innerHTML = `<span class="vjs-control-text">${localizedText}</span> -${formattedTime}`;
}
// Allows for smooth scrubbing, when player can't keep up.

View File

@ -1,11 +1,11 @@
import Component from '../component.js';
import Component from '../../component.js';
/**
* The separator between the current time and duration
*
* Can be hidden if it's not needed in the design.
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -13,7 +13,7 @@ class TimeDivider extends Component {
createEl() {
return super.createEl('div', {
className: 'vjs-time-divider',
className: 'vjs-time-control vjs-time-divider',
innerHTML: '<div><span>/</span></div>'
});
}
@ -21,4 +21,4 @@ class TimeDivider extends Component {
}
Component.registerComponent('TimeDivider', TimeDivider);
export default TimeDivider;
export default TimeDivider;

View File

@ -8,7 +8,7 @@ import VolumeLevel from './volume-level.js';
/**
* The bar that contains the volume level and can be clicked on to adjust the level
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -27,7 +27,7 @@ class VolumeBar extends Slider {
});
}
onMouseMove(event) {
handleMouseMove(event) {
if (this.player_.muted()) {
this.player_.muted(false);
}

View File

@ -7,7 +7,7 @@ import VolumeBar from './volume-bar.js';
/**
* The component for controlling the volume level
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/

View File

@ -3,7 +3,7 @@ import SliderHandle from '../../slider/slider-handle.js';
/**
* The volume handle can be dragged to adjust the volume level
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -21,4 +21,4 @@ class VolumeHandle extends SliderHandle {
VolumeHandle.prototype.defaultValue = '00:00';
SliderHandle.registerComponent('VolumeHandle', VolumeHandle);
export default VolumeHandle;
export default VolumeHandle;

View File

@ -3,7 +3,7 @@ import Component from '../../component.js';
/**
* Shows volume level
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -19,4 +19,4 @@ class VolumeLevel extends Component {
}
Component.registerComponent('VolumeLevel', VolumeLevel);
export default VolumeLevel;
export default VolumeLevel;

View File

@ -35,7 +35,13 @@ class VolumeMenuButton extends MenuButton {
let menu = new Menu(this.player_, {
contentElType: 'div'
});
let vc = new VolumeBar(this.player_, this.options_['volumeBar']);
// The volumeBar is vertical by default in the base theme when used with a VolumeMenuButton
var options = this.options_['volumeBar'] || {};
options['vertical'] = options['vertical'] || true;
let vc = new VolumeBar(this.player_, options);
vc.on('focus', function() {
menu.lockShowing();
});
@ -46,15 +52,15 @@ class VolumeMenuButton extends MenuButton {
return menu;
}
onClick() {
MuteToggle.prototype.onClick.call(this);
super.onClick();
handleClick() {
MuteToggle.prototype.handleClick.call(this);
super.handleClick();
}
createEl() {
return super.createEl('div', {
className: 'vjs-volume-menu-button vjs-menu-button vjs-control',
innerHTML: '<div><span class="vjs-control-text">' + this.localize('Mute') + '</span></div>'
className: 'vjs-volume-menu-button vjs-menu-button vjs-control vjs-button',
innerHTML: `<div><span class="vjs-control-text">${this.localize('Mute')}</span></div>`
});
}

View File

@ -66,11 +66,10 @@ var CoreObject = function(){};
*
* @param {Object} props Functions and properties to be applied to the
* new object's prototype
* @return {vjs.CoreObject} An object that inherits from CoreObject
* @return {CoreObject} An object that inherits from CoreObject
* @this {*}
*/
CoreObject.extend = function(props){
props = props || {};
CoreObject.extend = function(props={}){
// Set up the constructor using the supplied init method
// or using the init of the parent object
// Make sure to check the unobfuscated version for external libs
@ -114,7 +113,7 @@ CoreObject.extend = function(props){
*
* var myAnimal = Animal.create();
*
* @return {vjs.CoreObject} An instance of a CoreObject subclass
* @return {CoreObject} An instance of a CoreObject subclass
* @this {*}
*/
CoreObject.create = function(){

View File

@ -23,7 +23,7 @@ import document from 'global/document';
* @param {String|Element} id Video element or video element ID
* @param {Object=} options Optional options object for config/settings
* @param {Function=} ready Optional ready callback
* @return {vjs.Player} A player instance
* @return {Player} A player instance
* @namespace
*/
var videojs = function(id, options, ready){
@ -43,7 +43,7 @@ var videojs = function(id, options, ready){
// If options or ready funtion are passed, warn
if (options) {
Lib.log.warn('Player "' + id + '" is already initialised. Options will not be applied.');
Lib.log.warn(`Player "${id}" is already initialised. Options will not be applied.`);
}
if (ready) {
@ -88,14 +88,14 @@ videojs['VERSION'] = '__VERSION__';
// Set CDN Version of swf
// The added (+) blocks the replace from changing this _VERSION_NO_PATCH_ string
if (videojs.CDN_VERSION !== '__VERSION_'+'NO_PATCH__') {
Options['flash']['swf'] = videojs.ACCESS_PROTOCOL + 'vjs.zencdn.net/'+videojs.CDN_VERSION+'/video-js.swf';
Options['flash']['swf'] = `${videojs.ACCESS_PROTOCOL}vjs.zencdn.net/${videojs.CDN_VERSION}/video-js.swf`;
}
/**
* Utility function for adding languages to the default options. Useful for
* amending multiple language support at runtime.
*
* Example: vjs.addLanguage('es', {'Hello':'Hola'});
* Example: videojs.addLanguage('es', {'Hello':'Hola'});
*
* @param {String} code The language code or dictionary property
* @param {Object} data The data values to be translated

View File

@ -3,7 +3,7 @@ import * as Lib from './lib';
/**
* Display that an error has occurred making the video unplayable
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/

View File

@ -6,7 +6,7 @@ var EventEmitter = function() {};
EventEmitter.prototype.allowedEvents_ = {};
EventEmitter.prototype.on = function(type, fn) {
// Remove the addEventListener alias before calling vjs.on
// Remove the addEventListener alias before calling Events.on
// so we don't get into an infinite type loop
let ael = this.addEventListener;
this.addEventListener = Function.prototype;

View File

@ -62,11 +62,9 @@ var fixEvent = function(event) {
old.preventDefault();
}
event.returnValue = false;
event.isDefaultPrevented = returnTrue;
event.defaultPrevented = true;
};
event.isDefaultPrevented = returnFalse;
event.defaultPrevented = false;
// Stop the event from bubbling
@ -325,25 +323,6 @@ var trigger = function(elem, event) {
// Inform the triggerer if the default was prevented by returning false
return !event.defaultPrevented;
/* Original version of js ninja events wasn't complete.
* We've since updated to the latest version, but keeping this around
* for now just in case.
*/
// // Added in addition to book. Book code was broke.
// event = typeof event === 'object' ?
// event[vjs.expando] ?
// event :
// new vjs.Event(type, event) :
// new vjs.Event(type);
// event.type = type;
// if (handler) {
// handler.call(elem, event);
// }
// // Clean up the event in case it is being reused
// event.result = undefined;
// event.target = elem;
};
/**

71
src/js/extends.js Normal file
View File

@ -0,0 +1,71 @@
import * as Lib from './lib';
/**
* 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.
*/
const _inherits = function (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) {
// node
subClass.super_ = superClass;
}
};
/**
* Function for subclassing using the same inheritance that
* videojs uses internally
*
* ```
* var Button = videojs.getComponent('Button');
*
* var MyButton = videojs.extends(Button, {
* constructor: function(player, options) {
* Button.call(this, player, options);
* },
*
* onClick: function() {
* // doSomething
* }
* });
* ```
*/
const extendsFn = function(superClass, subClassMethods={}) {
let subClass = function() {
superClass.apply(this, arguments);
};
let methods = {};
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;
};
export default extendsFn;

View File

@ -5,7 +5,6 @@ import document from 'global/document';
* @type {Object|undefined}
* @private
*/
// vjs.browser.fullscreenAPI;
let FullscreenApi = {};
// browser API methods
@ -71,7 +70,6 @@ for (let i = 0; i < apiMap.length; i++) {
}
// map the browser API names to the spec API names
// or leave vjs.browser.fullscreenAPI undefined
if (browserApi) {
for (let i=0; i<browserApi.length; i++) {
FullscreenApi[specApi[i]] = browserApi[i];

View File

@ -1,75 +0,0 @@
/**
* @fileoverview Add JSON support
* @suppress {undefinedVars}
* (Compiler doesn't like JSON not being declared)
*/
import window from 'global/window';
// Changing 'JSON' throws jshint errors
var json = window.JSON;
/**
* Javascript JSON implementation
* (Parse Method Only)
* https://github.com/douglascrockford/JSON-js/blob/master/json2.js
* Only using for parse method when parsing data-setup attribute JSON.
* @suppress {undefinedVars}
* @namespace
* @private
*/
if (!(typeof json !== 'undefined' && typeof json.parse === 'function')) {
json = {};
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
/**
* parse the json
*
* @memberof vjs.JSON
* @param {String} text The JSON string to parse
* @param {Function=} [reviver] Optional function that can transform the results
* @return {Object|Array} The parsed JSON
*/
json.parse = function (text, reviver) {
var j;
function walk(holder, key) {
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
text = String(text);
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u'+ ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
if (/^[\],:{}\s]*$/
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
j = eval('(' + text + ')');
return typeof reviver === 'function' ? walk({'': j}, '') : j;
}
throw new SyntaxError('JSON.parse(): invalid or malformed JSON data');
};
}
export default json;

View File

@ -11,10 +11,7 @@ let hasOwnProp = Object.prototype.hasOwnProperty;
* @return {Element}
* @private
*/
var createEl = function(tagName, properties){
tagName = tagName || 'div';
properties = properties || {};
var createEl = function(tagName='div', properties={}){
let el = document.createElement(tagName);
obj.each(properties, function(propName, val){
@ -265,7 +262,7 @@ var removeData = function(el){
// Remove all stored data
// Changed to = null
// http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/
// vjs.cache[id] = null;
// cache[id] = null;
delete cache[id];
// Remove the expando property from the DOM node
@ -483,7 +480,8 @@ var getComputedDimension = function(el, strCssRule){
} else if(el.currentStyle){
// IE8 Width/Height support
strValue = el['client'+strCssRule.substr(0,1).toUpperCase() + strCssRule.substr(1)] + 'px';
let upperCasedRule = strCssRule.substr(0,1).toUpperCase() + strCssRule.substr(1);
strValue = el[`client${upperCasedRule}`] + 'px';
}
return strValue;
};
@ -533,14 +531,12 @@ var el = function(id){
* @return {String} Time formatted as H:MM:SS or M:SS
* @private
*/
var formatTime = function(seconds, guide) {
// Default to using seconds as guide
guide = guide || seconds;
var s = Math.floor(seconds % 60),
m = Math.floor(seconds / 60 % 60),
h = Math.floor(seconds / 3600),
gm = Math.floor(guide / 60 % 60),
gh = Math.floor(guide / 3600);
var formatTime = function(seconds, guide=seconds) {
let s = Math.floor(seconds % 60);
let m = Math.floor(seconds / 60 % 60);
let h = Math.floor(seconds / 3600);
const gm = Math.floor(guide / 60 % 60);
const gh = Math.floor(guide / 3600);
// handle invalid times
if (isNaN(seconds) || seconds === Infinity) {
@ -587,8 +583,7 @@ var trim = function(str){
* @return {Number} Rounded number
* @private
*/
var round = function(num, dec) {
if (!dec) { dec = 0; }
var round = function(num, dec=0) {
return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
};
@ -645,7 +640,7 @@ var getAbsoluteURL = function(url){
if (!url.match(/^https?:\/\//)) {
// Convert to absolute URL. Flash hosted off-site needs an absolute URL.
url = createEl('div', {
innerHTML: '<a href="'+url+'">x</a>'
innerHTML: `<a href="${url}">x</a>`
}).firstChild.href;
}
@ -670,7 +665,7 @@ var parseUrl = function(url) {
let div;
if (addToBody) {
div = createEl('div');
div.innerHTML = '<a href="'+url+'"></a>';
div.innerHTML = `<a href="${url}"></a>`;
a = div.firstChild;
// prevent the div from affecting layout
div.setAttribute('style', 'display:none; position:absolute;');
@ -712,7 +707,7 @@ function _logType(type, args){
// convert args to an array to get array functions
let argsArray = Array.prototype.slice.call(args);
// if there's no console then don't try to output messages
// they will still be stored in vjs.log.history
// they will still be stored in Lib.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
let noop = function(){};

View File

@ -4,7 +4,7 @@ import Component from './component';
================================================================================ */
/**
* Loading spinner for waiting events
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @class
* @constructor

View File

@ -4,7 +4,7 @@ import * as Lib from '../lib.js';
/**
* A button class with a popup menu
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -15,7 +15,7 @@ class MenuButton extends Button {
this.update();
this.on('keydown', this.onKeyPress);
this.on('keydown', this.handleKeyPress);
this.el_.setAttribute('aria-haspopup', true);
this.el_.setAttribute('role', 'button');
}
@ -75,19 +75,19 @@ class MenuButton extends Button {
/** @inheritDoc */
buildCSSClass() {
return this.className + ' vjs-menu-button ' + super.buildCSSClass();
return `${this.className} vjs-menu-button ${super.buildCSSClass()}`;
}
// Focus - Add keyboard functionality to element
// This function is not needed anymore. Instead, the keyboard functionality is handled by
// treating the button as triggering a submenu. When the button is pressed, the submenu
// appears. Pressing the button again makes the submenu disappear.
onFocus() {}
handleFocus() {}
// Can't turn off list display that we turned on with focus, because list would go away.
onBlur() {}
handleBlur() {}
onClick() {
handleClick() {
// When you click the button it adds focus, which will show the menu indefinitely.
// So we'll remove focus when the mouse leaves the button.
// Focus is needed for tab navigation.
@ -102,7 +102,7 @@ class MenuButton extends Button {
}
}
onKeyPress(event) {
handleKeyPress(event) {
// Check for space bar (32) or enter (13) keys
if (event.which == 32 || event.which == 13) {
@ -138,4 +138,4 @@ class MenuButton extends Button {
}
Button.registerComponent('MenuButton', MenuButton);
export default MenuButton;
export default MenuButton;

View File

@ -4,7 +4,7 @@ import * as Lib from '../lib.js';
/**
* The component for a menu item. `<li>`
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @class
* @constructor
@ -27,7 +27,7 @@ class MenuItem extends Button {
/**
* Handle a click on the menu item, and set it to selected
*/
onClick() {
handleClick() {
this.selected(true);
}
@ -48,4 +48,4 @@ class MenuItem extends Button {
}
Button.registerComponent('MenuItem', MenuItem);
export default MenuItem;
export default MenuItem;

View File

@ -8,7 +8,7 @@ import * as Events from '../events.js';
* The Menu component is used to build pop up menus, including subtitle and
* captions selection menus.
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @class
* @constructor

View File

@ -3,8 +3,8 @@ import window from 'global/window';
let navigator = window.navigator;
/**
* Global Player instance options, surfaced from vjs.Player.prototype.options_
* vjs.options = vjs.Player.prototype.options_
* Global Player instance options, surfaced from Player.prototype.options_
* options = Player.prototype.options_
* All options should use string keys so they avoid
* renaming by closure compiler
* @type {Object}

View File

@ -4,7 +4,7 @@ import * as Events from './events.js';
import FullscreenApi from './fullscreen-api.js';
import MediaError from './media-error.js';
import Options from './options.js';
import JSON from './json.js';
import safeParseTuple from 'safe-json-parse/tuple';
import window from 'global/window';
import document from 'global/document';
@ -21,7 +21,7 @@ import TextTrackSettings from './tracks/text-track-settings.js';
import Html5 from './tech/html5.js';
/**
* An instance of the `vjs.Player` class is created when any of the Video.js setup methods are used to initialize a video.
* An instance of the `Player` class is created when any of the Video.js setup methods are used to initialize a video.
*
* ```js
* var myPlayer = videojs('example_video_1');
@ -38,7 +38,7 @@ import Html5 from './tech/html5.js';
* After an instance has been created it can be accessed globally using `Video('example_video_1')`.
*
* @class
* @extends vjs.Component
* @extends Component
*/
class Player extends Component {
@ -53,7 +53,7 @@ class Player extends Component {
*/
constructor(tag, options, ready){
// Make sure tag ID exists
tag.id = tag.id || 'vjs_video_' + Lib.guid++;
tag.id = tag.id || `vjs_video_${Lib.guid++}`;
// Set Options
// The options argument overrides options set in the video tag
@ -76,6 +76,17 @@ class Player extends Component {
// Run base component initializing with new options
super(null, options, ready);
// if the global option object was accidentally blown away by
// someone, bail early with an informative error
if (!this.options_ ||
!this.options_.techOrder ||
!this.options_.techOrder.length) {
throw new Error('No techOrder specified. Did you overwrite ' +
'videojs.options instead of just changing the ' +
'properties you want to override?');
}
this.tag = tag; // Store the original tag used to set options
// Store the tag attributes used to restore html5 element
@ -100,7 +111,22 @@ class Player extends Component {
// May be turned back on by HTML5 tech if nativeControlsForTouch is true
tag.controls = false;
/**
* Store the internal state of scrubbing
* @private
* @return {Boolean} True if the user is scrubbing
*/
this.scrubbing_ = false;
this.el_ = this.createEl();
// Load plugins
if (options['plugins']) {
Lib.obj.each(options['plugins'], function(key, val){
this[key](val);
}, this);
}
this.initChildren();
// Set isAudio based on whether or not an audio tag was used
@ -118,21 +144,19 @@ class Player extends Component {
this.addClass('vjs-audio');
}
if (this.flexNotSupported_()) {
this.addClass('vjs-no-flex');
}
// TODO: Make this smarter. Toggle user state between touching/mousing
// using events, since devices can have both touch and mouse events.
// if (vjs.TOUCH_ENABLED) {
// if (Lib.TOUCH_ENABLED) {
// this.addClass('vjs-touch-enabled');
// }
// Make player easily findable by ID
Player.players[this.id_] = this;
if (options['plugins']) {
Lib.obj.each(options['plugins'], function(key, val){
this[key](val);
}, this);
}
// When the player is first initialized, trigger activity so components
// like the control bar show themselves if needed
this.userActive_ = true;
@ -200,7 +224,7 @@ class Player extends Component {
this.width(this.options_['width'], true); // (true) Skip resize listener on load
this.height(this.options_['height'], true);
// vjs.insertFirst seems to cause the networkState to flicker from 3 to 2, so
// Lib.insertFirst seems to cause the networkState to flicker from 3 to 2, so
// keep track of the original for later so we can know if the source originally failed
tag.initNetworkState_ = tag.networkState;
@ -217,18 +241,18 @@ class Player extends Component {
// like component.initEventListeners() that runs between el creation and
// adding children
this.el_ = el;
this.on('loadstart', this.onLoadStart);
this.on('waiting', this.onWaiting);
this.on(['canplay', 'canplaythrough', 'playing', 'ended'], this.onWaitEnd);
this.on('seeking', this.onSeeking);
this.on('seeked', this.onSeeked);
this.on('ended', this.onEnded);
this.on('play', this.onPlay);
this.on('firstplay', this.onFirstPlay);
this.on('pause', this.onPause);
this.on('progress', this.onProgress);
this.on('durationchange', this.onDurationChange);
this.on('fullscreenchange', this.onFullscreenChange);
this.on('loadstart', this.handleLoadStart);
this.on('waiting', this.handleWaiting);
this.on(['canplay', 'canplaythrough', 'playing', 'ended'], this.handleWaitEnd);
this.on('seeking', this.handleSeeking);
this.on('seeked', this.handleSeeked);
this.on('ended', this.handleEnded);
this.on('play', this.handlePlay);
this.on('firstplay', this.handleFirstPlay);
this.on('pause', this.handlePause);
this.on('progress', this.handleProgress);
this.on('durationchange', this.handleDurationChange);
this.on('fullscreenchange', this.handleFullscreenChange);
return el;
}
@ -291,7 +315,7 @@ class Player extends Component {
* Fired when the user agent begins looking for media data
* @event loadstart
*/
onLoadStart() {
handleLoadStart() {
// TODO: Update to use `emptied` event instead. See #1277.
this.removeClass('vjs-ended');
@ -332,7 +356,7 @@ class Player extends Component {
* Fired whenever the media begins or resumes playback
* @event play
*/
onPlay() {
handlePlay() {
this.removeClass('vjs-ended');
this.removeClass('vjs-paused');
this.addClass('vjs-playing');
@ -346,7 +370,7 @@ class Player extends Component {
* Fired whenever the media begins waiting
* @event waiting
*/
onWaiting() {
handleWaiting() {
this.addClass('vjs-waiting');
}
@ -355,7 +379,7 @@ class Player extends Component {
* which is not consistent between browsers. See #1351
* @private
*/
onWaitEnd() {
handleWaitEnd() {
this.removeClass('vjs-waiting');
}
@ -363,7 +387,7 @@ class Player extends Component {
* Fired whenever the player is jumping to a new time
* @event seeking
*/
onSeeking() {
handleSeeking() {
this.addClass('vjs-seeking');
}
@ -371,7 +395,7 @@ class Player extends Component {
* Fired when the player has finished jumping to a new time
* @event seeked
*/
onSeeked() {
handleSeeked() {
this.removeClass('vjs-seeking');
}
@ -384,7 +408,7 @@ class Player extends Component {
*
* @event firstplay
*/
onFirstPlay() {
handleFirstPlay() {
//If the first starttime attribute is specified
//then we will start at the given offset in seconds
if(this.options_['starttime']){
@ -398,7 +422,8 @@ class Player extends Component {
* Fired whenever the media has been paused
* @event pause
*/
onPause() {
handlePause() {
this.removeClass('vjs-playing');
this.addClass('vjs-paused');
}
@ -406,7 +431,7 @@ class Player extends Component {
* Fired while the user agent is downloading media data
* @event progress
*/
onProgress() {
handleProgress() {
// Add custom event for when source is finished downloading.
if (this.bufferedPercent() == 1) {
this.trigger('loadedalldata');
@ -417,7 +442,7 @@ class Player extends Component {
* Fired when the end of the media resource is reached (currentTime == duration)
* @event ended
*/
onEnded() {
handleEnded() {
this.addClass('vjs-ended');
if (this.options_['loop']) {
this.currentTime(0);
@ -431,7 +456,7 @@ class Player extends Component {
* Fired when the duration of the media resource is first known or changed
* @event durationchange
*/
onDurationChange() {
handleDurationChange() {
// Allows for caching value instead of asking player each time.
// We need to get the techGet response and check for a value so we don't
// accidentally cause the stack to blow up.
@ -454,7 +479,7 @@ class Player extends Component {
* Fired when the player switches in or out of fullscreen mode
* @event fullscreenchange
*/
onFullscreenChange() {
handleFullscreenChange() {
if (this.isFullscreen()) {
this.addClass('vjs-fullscreen');
} else {
@ -500,11 +525,11 @@ class Player extends Component {
} catch(e) {
// When building additional tech libs, an expected method may not be defined yet
if (this.tech[method] === undefined) {
Lib.log('Video.js: ' + method + ' method not defined for '+this.techName+' playback technology.', e);
Lib.log(`Video.js: ${method} method not defined for ${this.techName} playback technology.`, e);
} else {
// When a method isn't available on the object it throws a TypeError
if (e.name == 'TypeError') {
Lib.log('Video.js: ' + method + ' unavailable on '+this.techName+' playback technology element.', e);
Lib.log(`Video.js: ${method} unavailable on ${this.techName} playback technology element.`, e);
this.tech.isReady_ = false;
} else {
Lib.log(e);
@ -522,7 +547,7 @@ class Player extends Component {
*
* myPlayer.play();
*
* @return {vjs.Player} self
* @return {Player} self
*/
play() {
this.techCall('play');
@ -534,7 +559,7 @@ class Player extends Component {
*
* myPlayer.pause();
*
* @return {vjs.Player} self
* @return {Player} self
*/
pause() {
this.techCall('pause');
@ -554,6 +579,29 @@ class Player extends Component {
return (this.techGet('paused') === false) ? false : true;
}
/**
* Returns whether or not the user is "scrubbing". Scrubbing is when the user
* has clicked the progress bar handle and is dragging it along the progress bar.
* @param {Boolean} isScrubbing True/false the user is scrubbing
* @return {Boolean} The scrubbing status when getting
* @return {Object} The player when setting
*/
scrubbing(isScrubbing) {
if (isScrubbing !== undefined) {
this.scrubbing_ = !!isScrubbing;
if (isScrubbing) {
this.addClass('vjs-scrubbing');
} else {
this.removeClass('vjs-scrubbing');
}
return this;
}
return this.scrubbing_;
}
/**
* Get or set the current time (in seconds)
*
@ -565,7 +613,7 @@ class Player extends Component {
*
* @param {Number|String=} seconds The time to seek to
* @return {Number} The time in seconds, when not setting
* @return {vjs.Player} self, when the current time is set
* @return {Player} self, when the current time is set
*/
currentTime(seconds) {
if (seconds !== undefined) {
@ -605,7 +653,7 @@ class Player extends Component {
}
if (this.cache_.duration === undefined) {
this.onDurationChange();
this.handleDurationChange();
}
return this.cache_.duration || 0;
@ -723,7 +771,7 @@ class Player extends Component {
*
* @param {Number} percentAsDecimal The new volume as a decimal percent
* @return {Number} The current volume, when getting
* @return {vjs.Player} self, when setting
* @return {Player} self, when setting
*/
volume(percentAsDecimal) {
let vol;
@ -753,7 +801,7 @@ class Player extends Component {
*
* @param {Boolean=} muted True to mute, false to unmute
* @return {Boolean} True if mute is on, false if not, when getting
* @return {vjs.Player} self, when setting mute
* @return {Player} self, when setting mute
*/
muted(muted) {
if (muted !== undefined) {
@ -784,7 +832,7 @@ class Player extends Component {
*
* @param {Boolean=} isFS Update the player's fullscreen state
* @return {Boolean} true if fullscreen, false if not
* @return {vjs.Player} self, when setting
* @return {Player} self, when setting
*/
isFullscreen(isFS) {
if (isFS !== undefined) {
@ -815,7 +863,7 @@ class Player extends Component {
* This includes most mobile devices (iOS, Android) and older versions of
* Safari.
*
* @return {vjs.Player} self
* @return {Player} self
*/
requestFullscreen() {
var fsApi = FullscreenApi;
@ -872,7 +920,7 @@ class Player extends Component {
*
* myPlayer.exitFullscreen();
*
* @return {vjs.Player} self
* @return {Player} self
*/
exitFullscreen() {
var fsApi = FullscreenApi;
@ -952,7 +1000,7 @@ class Player extends Component {
// Check if the current tech is defined before continuing
if (!tech) {
Lib.log.error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
Lib.log.error(`The "${techName}" tech is undefined. Skipped browser support check for that tech.`);
continue;
}
@ -1005,13 +1053,9 @@ class Player extends Component {
* @return {String} The current video source when getting
* @return {String} The player when setting
*/
src(source) {
src(source=this.techGet('src')) {
let currentTech = Component.getComponent(this.techName);
if (source === undefined) {
return this.techGet('src');
}
// case: Array of source objects to choose from and pick the best to play
if (Lib.obj.isArray(source)) {
this.sourceList_(source);
@ -1090,7 +1134,7 @@ class Player extends Component {
/**
* Begin loading the src data.
* @return {vjs.Player} Returns the player
* @return {Player} Returns the player
*/
load() {
this.techCall('load');
@ -1119,7 +1163,7 @@ class Player extends Component {
/**
* Get or set the preload attribute.
* @return {String} The preload attribute value when getting
* @return {vjs.Player} Returns the player when setting
* @return {Player} Returns the player when setting
*/
preload(value) {
if (value !== undefined) {
@ -1133,7 +1177,7 @@ class Player extends Component {
/**
* Get or set the autoplay attribute.
* @return {String} The autoplay attribute value when getting
* @return {vjs.Player} Returns the player when setting
* @return {Player} Returns the player when setting
*/
autoplay(value) {
if (value !== undefined) {
@ -1147,7 +1191,7 @@ class Player extends Component {
/**
* Get or set the loop attribute on the video element.
* @return {String} The loop attribute value when getting
* @return {vjs.Player} Returns the player when setting
* @return {Player} Returns the player when setting
*/
loop(value) {
if (value !== undefined) {
@ -1171,7 +1215,7 @@ class Player extends Component {
*
* @param {String=} [src] Poster image source URL
* @return {String} poster URL when getting
* @return {vjs.Player} self when setting
* @return {Player} self when setting
*/
poster(src) {
if (src === undefined) {
@ -1231,7 +1275,7 @@ class Player extends Component {
* if it can support native controls**
*
* @param {Boolean} bool True signals that native controls are on
* @return {vjs.Player} Returns the player
* @return {Player} Returns the player
* @private
*/
usingNativeControls(bool) {
@ -1247,7 +1291,7 @@ class Player extends Component {
* player is using the native device controls
*
* @event usingnativecontrols
* @memberof vjs.Player
* @memberof Player
* @instance
* @private
*/
@ -1259,7 +1303,7 @@ class Player extends Component {
* player is using the custom HTML controls
*
* @event usingcustomcontrols
* @memberof vjs.Player
* @memberof Player
* @instance
* @private
*/
@ -1274,8 +1318,8 @@ class Player extends Component {
/**
* Set or get the current MediaError
* @param {*} err A MediaError or a String/Number to be turned into a MediaError
* @return {vjs.MediaError|null} when getting
* @return {vjs.Player} when setting
* @return {MediaError|null} when getting
* @return {Player} when setting
*/
error(err) {
if (err === undefined) {
@ -1304,7 +1348,7 @@ class Player extends Component {
// log the name of the error type and any message
// ie8 just logs "[object object]" if you just log the error object
Lib.log.error('(CODE:'+this.error_.code+' '+MediaError.errorTypes[this.error_.code]+')', this.error_.message, this.error_);
Lib.log.error(`(CODE:${this.error_.code} ${MediaError.errorTypes[this.error_.code]})`, this.error_.message, this.error_);
return this;
}
@ -1370,20 +1414,20 @@ class Player extends Component {
listenForUserActivity() {
let mouseInProgress, lastMoveX, lastMoveY;
let onActivity = Lib.bind(this, this.reportUserActivity);
let handleActivity = Lib.bind(this, this.reportUserActivity);
let onMouseMove = function(e) {
let handleMouseMove = function(e) {
// #1068 - Prevent mousemove spamming
// Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970
if(e.screenX != lastMoveX || e.screenY != lastMoveY) {
lastMoveX = e.screenX;
lastMoveY = e.screenY;
onActivity();
handleActivity();
}
};
let onMouseDown = function() {
onActivity();
let handleMouseDown = function() {
handleActivity();
// For as long as the they are touching the device or have their mouse down,
// we consider them active even if they're not moving their finger or mouse.
// So we want to continue to update that they are active
@ -1391,24 +1435,24 @@ class Player extends Component {
// Setting userActivity=true now and setting the interval to the same time
// as the activityCheck interval (250) should ensure we never miss the
// next activityCheck
mouseInProgress = this.setInterval(onActivity, 250);
mouseInProgress = this.setInterval(handleActivity, 250);
};
let onMouseUp = function(event) {
onActivity();
let handleMouseUp = function(event) {
handleActivity();
// Stop the interval that maintains activity if the mouse/touch is down
this.clearInterval(mouseInProgress);
};
// Any mouse movement will be considered user activity
this.on('mousedown', onMouseDown);
this.on('mousemove', onMouseMove);
this.on('mouseup', onMouseUp);
this.on('mousedown', handleMouseDown);
this.on('mousemove', handleMouseMove);
this.on('mouseup', handleMouseUp);
// Listen for keyboard navigation
// Shouldn't need to use inProgress interval because of key repeat
this.on('keydown', onActivity);
this.on('keyup', onActivity);
this.on('keydown', handleActivity);
this.on('keyup', handleActivity);
// Run an interval every 250 milliseconds instead of stuffing everything into
// the mousemove/touchmove function itself, to prevent performance degradation.
@ -1473,7 +1517,7 @@ class Player extends Component {
*
* @param {Boolean} bool True signals that this is an audio player.
* @return {Boolean} Returns true if player is audio, false if not when getting
* @return {vjs.Player} Returns the player if setting
* @return {Player} Returns the player if setting
* @private
*/
isAudio(bool) {
@ -1597,7 +1641,7 @@ class Player extends Component {
* The player's language code
* @param {String} languageCode The locale string
* @return {String} The locale string when getting
* @return {vjs.Player} self, when setting
* @return {Player} self, when setting
*/
language(languageCode) {
if (languageCode === undefined) {
@ -1628,7 +1672,7 @@ class Player extends Component {
if (dataSetup !== null){
// Parse options JSON
// If empty string, make it a parsable json object.
Lib.obj.merge(tagOptions, JSON.parse(dataSetup || '{}'));
Lib.obj.merge(tagOptions, safeParseTuple(dataSetup || '{}')[1]);
}
Lib.obj.merge(baseOptions, tagOptions);
@ -1661,9 +1705,9 @@ class Player extends Component {
Player.players = {};
/**
* Player instance options, surfaced using vjs.options
* vjs.options = vjs.Player.prototype.options_
* Make changes in vjs.options, not here.
* Player instance options, surfaced using options
* options = Player.prototype.options_
* Make changes in options, not here.
* All options should use string keys so they avoid
* renaming by closure compiler
* @type {Object}
@ -1675,31 +1719,31 @@ Player.prototype.options_ = Options;
* Fired when the player has initial duration and dimension information
* @event loadedmetadata
*/
Player.prototype.onLoadedMetaData;
Player.prototype.handleLoadedMetaData;
/**
* Fired when the player has downloaded data at the current playback position
* @event loadeddata
*/
Player.prototype.onLoadedData;
Player.prototype.handleLoadedData;
/**
* Fired when the player has finished downloading the source data
* @event loadedalldata
*/
Player.prototype.onLoadedAllData;
Player.prototype.handleLoadedAllData;
/**
* Fired when the user is active, e.g. moves the mouse over the player
* @event useractive
*/
Player.prototype.onUserActive;
Player.prototype.handleUserActive;
/**
* Fired when the user is inactive, e.g. a short delay after the last mouse move or control interaction
* @event userinactive
*/
Player.prototype.onUserInactive;
Player.prototype.handleUserInactive;
/**
* Fired when the current playback position has changed
@ -1708,19 +1752,28 @@ Player.prototype.onUserInactive;
* playback technology in use.
* @event timeupdate
*/
Player.prototype.onTimeUpdate;
Player.prototype.handleTimeUpdate;
/**
* Fired when the volume changes
* @event volumechange
*/
Player.prototype.onVolumeChange;
Player.prototype.handleVolumeChange;
/**
* Fired when an error occurs
* @event error
*/
Player.prototype.onError;
Player.prototype.handleError;
Player.prototype.flexNotSupported_ = function() {
var elem = document.createElement('i');
return !('flexBasis' in elem.style ||
'webkitFlexBasis' in elem.style ||
'mozFlexBasis' in elem.style ||
'msFlexBasis' in elem.style);
};
Component.registerComponent('Player', Player);
export default Player;

View File

@ -6,7 +6,7 @@ import * as Lib from './lib';
/**
* The component that handles showing the poster image.
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -79,7 +79,7 @@ class PosterImage extends Button {
// Any falsey values should stay as an empty string, otherwise
// this will throw an extra error
if (url) {
backgroundImage = 'url("' + url + '")';
backgroundImage = `url("${url}")`;
}
this.el_.style.backgroundImage = backgroundImage;
@ -89,10 +89,14 @@ class PosterImage extends Button {
/**
* Event handler for clicks on the poster image
*/
onClick() {
handleClick() {
// We don't want a click to trigger playback when controls are disabled
// but CSS should be hiding the poster to prevent that from happening
this.player_.play();
if (this.player_.paused()) {
this.player_.play();
} else {
this.player_.pause();
}
}
}

View File

@ -1,4 +1,3 @@
import JSON from './json';
import * as Events from './events';
import document from 'global/document';
import window from 'global/window';

View File

@ -4,7 +4,7 @@ import * as Lib from '../lib.js';
/**
* SeekBar Behavior includes play progress bar, and seek handle
* Needed so it can determine seek position based on handle position/size
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -16,7 +16,7 @@ class SliderHandle extends Component {
// Add the slider element class to all sub classes
props.className = props.className + ' vjs-slider-handle';
props = Lib.obj.merge({
innerHTML: '<span class="vjs-control-text">'+(this.defaultValue || 0)+'</span>'
innerHTML: `<span class="vjs-control-text">${this.defaultValue || 0}</span>`
}, props);
return super.createEl('div', props);

View File

@ -7,7 +7,7 @@ import document from 'global/document';
/**
* The base functionality for sliders like the volume bar and seek bar
*
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @constructor
*/
@ -23,18 +23,17 @@ class Slider extends Component {
// Set a horizontal or vertical class on the slider depending on the slider type
this.vertical(!!this.options()['vertical']);
this.on('mousedown', this.onMouseDown);
this.on('touchstart', this.onMouseDown);
this.on('focus', this.onFocus);
this.on('blur', this.onBlur);
this.on('click', this.onClick);
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);
}
createEl(type, props) {
props = props || {};
createEl(type, props={}) {
// Add the slider element class to all sub classes
props.className = props.className + ' vjs-slider';
props = Lib.obj.merge({
@ -48,30 +47,30 @@ class Slider extends Component {
return super.createEl(type, props);
}
onMouseDown(event) {
handleMouseDown(event) {
event.preventDefault();
Lib.blockTextSelection();
this.addClass('vjs-sliding');
this.on(document, 'mousemove', this.onMouseMove);
this.on(document, 'mouseup', this.onMouseUp);
this.on(document, 'touchmove', this.onMouseMove);
this.on(document, 'touchend', this.onMouseUp);
this.on(document, 'mousemove', this.handleMouseMove);
this.on(document, 'mouseup', this.handleMouseUp);
this.on(document, 'touchmove', this.handleMouseMove);
this.on(document, 'touchend', this.handleMouseUp);
this.onMouseMove(event);
this.handleMouseMove(event);
}
// To be overridden by a subclass
onMouseMove() {}
handleMouseMove() {}
onMouseUp() {
handleMouseUp() {
Lib.unblockTextSelection();
this.removeClass('vjs-sliding');
this.off(document, 'mousemove', this.onMouseMove);
this.off(document, 'mouseup', this.onMouseUp);
this.off(document, 'touchmove', this.onMouseMove);
this.off(document, 'touchend', this.onMouseUp);
this.off(document, 'mousemove', this.handleMouseMove);
this.off(document, 'mouseup', this.handleMouseUp);
this.off(document, 'touchmove', this.handleMouseMove);
this.off(document, 'touchend', this.handleMouseUp);
this.update();
}
@ -207,11 +206,11 @@ class Slider extends Component {
}
}
onFocus() {
this.on(document, 'keydown', this.onKeyPress);
handleFocus() {
this.on(document, 'keydown', this.handleKeyPress);
}
onKeyPress(event) {
handleKeyPress(event) {
if (event.which == 37 || event.which == 40) { // Left and Down Arrows
event.preventDefault();
this.stepBack();
@ -221,8 +220,8 @@ class Slider extends Component {
}
}
onBlur() {
this.off(document, 'keydown', this.onKeyPress);
handleBlur() {
this.off(document, 'keydown', this.handleKeyPress);
}
/**
@ -230,7 +229,7 @@ class Slider extends Component {
* from bubbling up to parent elements like button menus.
* @param {Object} event Event object
*/
onClick(event) {
handleClick(event) {
event.stopImmediatePropagation();
event.preventDefault();
}

View File

@ -74,7 +74,7 @@ function FlashRtmpDecorator(Flash) {
* Adaptive source handlers will have more complicated workflows before passing
* video data to the video element
* @param {Object} source The source object
* @param {vjs.Flash} tech The instance of the Flash tech
* @param {Flash} tech The instance of the Flash tech
*/
Flash.rtmpSourceHandler.handleSource = function(source, tech){
let srcParts = Flash.streamToParts(source.src);

View File

@ -14,7 +14,7 @@ let navigator = window.navigator;
/**
* Flash Media Controller - Wrapper for fallback SWF API
*
* @param {vjs.Player} player
* @param {Player} player
* @param {Object=} options
* @param {Function=} ready
* @constructor
@ -221,7 +221,7 @@ Tech.withSourceHandlers(Flash);
* The default native source handler.
* This simply passes the source to the video element. Nothing fancy.
* @param {Object} source The source object
* @param {vjs.Flash} tech The instance of the Flash tech
* @param {Flash} tech The instance of the Flash tech
*/
Flash.nativeSourceHandler = {};
@ -236,7 +236,7 @@ Flash.nativeSourceHandler.canHandleSource = function(source){
function guessMimeType(src) {
var ext = Lib.getFileExtension(src);
if (ext) {
return 'video/' + ext;
return `video/${ext}`;
}
return '';
}
@ -260,7 +260,7 @@ Flash.nativeSourceHandler.canHandleSource = function(source){
* Adaptive source handlers will have more complicated workflows before passing
* video data to the video element
* @param {Object} source The source object
* @param {vjs.Flash} tech The instance of the Flash tech
* @param {Flash} tech The instance of the Flash tech
*/
Flash.nativeSourceHandler.handleSource = function(source, tech){
tech.setSrc(source.src);
@ -379,7 +379,7 @@ Flash.getEmbedCode = function(swf, flashVars, params, attributes){
// Convert flash vars to string
if (flashVars) {
Lib.obj.each(flashVars, function(key, val){
flashVarsString += (key + '=' + val + '&amp;');
flashVarsString += `${key}=${val}&amp;`;
});
}
@ -393,7 +393,7 @@ Flash.getEmbedCode = function(swf, flashVars, params, attributes){
// Create param tags string
Lib.obj.each(params, function(key, val){
paramsString += '<param name="'+key+'" value="'+val+'" />';
paramsString += `<param name="${key}" value="${val}" />`;
});
attributes = Lib.obj.merge({
@ -408,10 +408,10 @@ Flash.getEmbedCode = function(swf, flashVars, params, attributes){
// Create Attributes string
Lib.obj.each(attributes, function(key, val){
attrsString += (key + '="' + val + '" ');
attrsString += `${key}="${val}" `;
});
return objTag + attrsString + '>' + paramsString + '</object>';
return `${objTag}${attrsString}>${paramsString}</object>`;
};
// Run Flash through the RTMP decorator

View File

@ -10,7 +10,7 @@ import document from 'global/document';
/**
* HTML5 Media Controller - Wrapper for HTML5 Media API
* @param {vjs.Player|Object} player
* @param {Player|Object} player
* @param {Object=} options
* @param {Function=} ready
* @constructor
@ -362,13 +362,12 @@ class Html5 extends Tech {
return this.el_.addTextTrack(kind, label, language);
}
addRemoteTextTrack(options) {
addRemoteTextTrack(options={}) {
if (!this['featuresNativeTextTracks']) {
return super.addRemoteTextTrack(options);
}
var track = document.createElement('track');
options = options || {};
if (options['kind']) {
track['kind'] = options['kind'];
@ -460,7 +459,7 @@ Tech.withSourceHandlers(Html5);
* The default native source handler.
* This simply passes the source to the video element. Nothing fancy.
* @param {Object} source The source object
* @param {vjs.Html5} tech The instance of the HTML5 tech
* @param {Html5} tech The instance of the HTML5 tech
*/
Html5.nativeSourceHandler = {};
@ -489,7 +488,7 @@ Html5.nativeSourceHandler.canHandleSource = function(source){
// If no type, fall back to checking 'video/[EXTENSION]'
ext = Lib.getFileExtension(source.src);
return canPlayType('video/'+ext);
return canPlayType(`video/${ext}`);
}
return '';
@ -500,7 +499,7 @@ Html5.nativeSourceHandler.canHandleSource = function(source){
* Adaptive source handlers will have more complicated workflows before passing
* video data to the video element
* @param {Object} source The source object
* @param {vjs.Html5} tech The instance of the Html5 tech
* @param {Html5} tech The instance of the Html5 tech
*/
Html5.nativeSourceHandler.handleSource = function(source, tech){
tech.setSrc(source.src);

Some files were not shown because too many files have changed in this diff Show More