Comparar commits
1 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| bef4c96a4b |
@@ -6,81 +6,6 @@ _(none)_
|
||||
|
||||
--------------------
|
||||
|
||||
## 5.6.0 (2016-01-26)
|
||||
* @OwenEdwards added ClickableComponent. Fixed keyboard operation of buttons ([view](https://github.com/videojs/video.js/pull/3032))
|
||||
* @OwenEdwards Fixed menu keyboard access and ARIA labeling for screen readers ([view](https://github.com/videojs/video.js/pull/3033))
|
||||
* @OwenEdwards Fixed volume menu keyboard access ([view](https://github.com/videojs/video.js/pull/3034))
|
||||
* @mister-ben made $primary-foreground-color a !default sass var ([view](https://github.com/videojs/video.js/pull/3003))
|
||||
* @OwenEdwards fixed double-localization of mute toggle control text ([view](https://github.com/videojs/video.js/pull/3017))
|
||||
* @gkatsev checked muted status when updating volume bar level ([view](https://github.com/videojs/video.js/pull/3037))
|
||||
* @vitor-faiante updated the guides ([view](https://github.com/videojs/video.js/pull/2781))
|
||||
* @aril-spetalen added language support for Norwegian (nb and nn) ([view](https://github.com/videojs/video.js/pull/3021))
|
||||
* @CoWinkKeyDinkInc fixed table in Tracks guide. Replaced some single quotes with double quotes ([view](https://github.com/videojs/video.js/pull/2946))
|
||||
* @hubdotcom changed URLs in README to be protocol-relative ([view](https://github.com/videojs/video.js/pull/3040))
|
||||
* @gkatsev updated to latest videojs-ie8 shim ([view](https://github.com/videojs/video.js/pull/3042))
|
||||
|
||||
## 5.5.3 (2016-01-15)
|
||||
* @gkasev updated vjs to correctly return already created player when given an element ([view](https://github.com/videojs/video.js/pull/3006))
|
||||
* @mister-ben updated CDN urls in setup guide ([view](https://github.com/videojs/video.js/pull/2984))
|
||||
* @rcrooks fixed a couple of docs link and a jsdoc comment ([view](https://github.com/videojs/video.js/pull/2987))
|
||||
|
||||
## 5.5.2 (2016-01-14)
|
||||
* make sure that styleEl_ is in DOM before removing on dispose ([view](https://github.com/videojs/video.js/pull/3004))
|
||||
|
||||
## 5.5.1 (2016-01-08)
|
||||
* @gkatsev fixed sass if else for icons ([view](https://github.com/videojs/video.js/pull/2988))
|
||||
|
||||
## 5.5.0 (2016-01-07)
|
||||
* @hartman fixed usage of lighten in progress component. Fixes #2793 ([view](https://github.com/videojs/video.js/pull/2875))
|
||||
* @misteroneill exposed createEl on videojs ([view](https://github.com/videojs/video.js/pull/2926))
|
||||
* @huitsing updated docstrings for autoplay and loop methods ([view](https://github.com/videojs/video.js/pull/2960))
|
||||
* @rcrooks fixed some broken links in guides ([view](https://github.com/videojs/video.js/pull/2965))
|
||||
* @forbesjo fixed errorDisplay erroring on subsequent openings ([view](https://github.com/videojs/video.js/pull/2966))
|
||||
* @incompl updated build command in CONTRIBUTING.md ([view](https://github.com/videojs/video.js/pull/2967))
|
||||
* @forbesjo updated player to not autoplay if there is no source ([view](https://github.com/videojs/video.js/pull/2971))
|
||||
* @gkatsev updated css to have ascii codepoints for fonticons. Expose new scss file ([view](https://github.com/videojs/video.js/pull/2973))
|
||||
|
||||
## 5.4.6 (2015-12-22)
|
||||
* @gkatsev fixed vertical slider alignment in volume menu button ([view](https://github.com/videojs/video.js/pull/2943))
|
||||
|
||||
## 5.4.5 (2015-12-15)
|
||||
* @gkatsev added mouse/touch listeners to volume menu button ([view](https://github.com/videojs/video.js/pull/2638))
|
||||
* @gkatsev updated styles for inline menu and volume bar ([view](https://github.com/videojs/video.js/pull/2913))
|
||||
* @BrandonOCasey updated sandbox to to use newer CDN urls ([view](https://github.com/videojs/video.js/pull/2917))
|
||||
* @hartman updated options guide doc ([view](https://github.com/videojs/video.js/pull/2908))
|
||||
* @rcrooks fixed simple embed example ([view](https://github.com/videojs/video.js/pull/2915))
|
||||
|
||||
## 5.4.4 (2015-12-09)
|
||||
* @gkatsev switched to use custom vtt.js from npm ([view](https://github.com/videojs/video.js/pull/2905))
|
||||
|
||||
## 5.4.3 (2015-12-08)
|
||||
* @gkatsev updated options customizer and github-release options ([view](https://github.com/videojs/video.js/pull/2903))
|
||||
|
||||
## 5.4.2 (2015-12-08)
|
||||
* @gkatsev updated grunt-release config ([view](https://github.com/videojs/video.js/pull/2900))
|
||||
|
||||
## 5.4.1 (2015-12-08)
|
||||
* @misteroneill updated videojs-ie8 to 1.1.1 ([view](https://github.com/videojs/video.js/pull/2869))
|
||||
* @gkatsev added Player#tech. Fixes #2617 ([view](https://github.com/videojs/video.js/pull/2883))
|
||||
* @nick11703 changed multiline comments in sass with single-line comments ([view](https://github.com/videojs/video.js/pull/2827))
|
||||
* @gkatsev added a Player#reset method. Fixes #2852 ([view](https://github.com/videojs/video.js/pull/2880))
|
||||
* @chemoish emulated HTMLTrackElement to enable track load events ([view](https://github.com/videojs/video.js/pull/2804))
|
||||
* @gkatsev added nullcheck for cues in updateForTrack. Fixes #2870 ([view](https://github.com/videojs/video.js/pull/2896))
|
||||
* @gkatsev added ability to release next tag from master ([view](https://github.com/videojs/video.js/pull/2894))
|
||||
* @gkatsev added chg- and github- release for next releases ([view](https://github.com/videojs/video.js/pull/2899))
|
||||
|
||||
## 5.3.0 (2015-11-25)
|
||||
* @forbesjo updated formatTime to not go negative ([view](https://github.com/videojs/video.js/pull/2821))
|
||||
* @imbcmdth added sourceOrder option for source-first ordering in selectSource ([view](https://github.com/videojs/video.js/pull/2847))
|
||||
|
||||
## 5.2.4 (2015-11-25)
|
||||
* @gesinger checked for track changes before tech started listening ([view](https://github.com/videojs/video.js/pull/2835))
|
||||
* @gesinger fixed handler explosion for cuechange events ([view](https://github.com/videojs/video.js/pull/2849))
|
||||
* @mmcc fixed vertical volume ([view](https://github.com/videojs/video.js/pull/2859))
|
||||
|
||||
## 5.2.3 (2015-11-24)
|
||||
* @gkatsev fixed clearing out errors ([view](https://github.com/videojs/video.js/pull/2850))
|
||||
|
||||
## 5.2.2 (2015-11-23)
|
||||
* @DatTran fixed bower paths. Fixes #2740 ([view](https://github.com/videojs/video.js/pull/2775))
|
||||
* @nbibler ensured classes begin with alpha characters. Fixes #2828 ([view](https://github.com/videojs/video.js/pull/2829))
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ npm install
|
||||
Build a local copy of video.js and run tests
|
||||
|
||||
```bash
|
||||
grunt dist
|
||||
grunt
|
||||
grunt test
|
||||
```
|
||||
|
||||
|
||||
+4
-4
@@ -9,8 +9,8 @@ Thanks to the awesome folks over at [Fastly](http://www.fastly.com/), there's a
|
||||
`<head>`:
|
||||
|
||||
```html
|
||||
<link href="//vjs.zencdn.net/5.0/video-js.min.css" rel="stylesheet">
|
||||
<script src="//vjs.zencdn.net/5.0/video.min.js"></script>
|
||||
<link href="http://vjs.zencdn.net/5.0/video-js.min.css" rel="stylesheet">
|
||||
<script src="http://vjs.zencdn.net/5.0/video.min.js"></script>
|
||||
```
|
||||
|
||||
Then, whenever you want to use Video.js you can simply use the `<video>` element as your normally would, but with an additional `data-setup` attribute containing any Video.js options. These options
|
||||
@@ -20,8 +20,8 @@ can include any Video.js option plus potential [plugin](https://github.com/video
|
||||
<video id="really-cool-video" class="video-js vjs-default-skin" controls
|
||||
preload="auto" width="640" height="264" poster="really-cool-video-poster.jpg"
|
||||
data-setup='{}'>
|
||||
<source src="really-cool-video.mp4" type="video/mp4">
|
||||
<source src="really-cool-video.webm" type="video/webm">
|
||||
<source src="really-cool-video.mp4" type='video/mp4'>
|
||||
<source src="really-cool-video.webm" type='video/webm'>
|
||||
<p class="vjs-no-js">
|
||||
To view this video please enable JavaScript, and consider upgrading to a web browser
|
||||
that <a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a>
|
||||
|
||||
+19
-42
@@ -1,4 +1,3 @@
|
||||
import {gruntCustomizer, gruntOptionsMaker} from './options-customizer.js';
|
||||
module.exports = function(grunt) {
|
||||
require('time-grunt')(grunt);
|
||||
|
||||
@@ -42,19 +41,6 @@ module.exports = function(grunt) {
|
||||
]
|
||||
};
|
||||
|
||||
const githubReleaseDefaults = {
|
||||
options: {
|
||||
release: {
|
||||
tag_name: 'v'+ version.full,
|
||||
name: version.full,
|
||||
body: require('chg').find(version.full).changesRaw
|
||||
},
|
||||
},
|
||||
files: {
|
||||
src: [`dist/video-js-${version.full}.zip`] // Files that you want to attach to Release
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Customizes _.merge behavior in `browserifyGruntOptions` to concatenate
|
||||
* arrays. This can be overridden on a per-call basis to
|
||||
@@ -66,7 +52,11 @@ module.exports = function(grunt) {
|
||||
* @param {Mixed} sourceValue
|
||||
* @return {Object}
|
||||
*/
|
||||
const browserifyGruntCustomizer = gruntCustomizer;
|
||||
function browserifyGruntCustomizer(objectValue, sourceValue) {
|
||||
if (Array.isArray(objectValue)) {
|
||||
return objectValue.concat(sourceValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a unique object of Browserify Grunt task options.
|
||||
@@ -80,10 +70,9 @@ module.exports = function(grunt) {
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
const browserifyGruntOptions = gruntOptionsMaker(browserifyGruntDefaults, browserifyGruntCustomizer);
|
||||
|
||||
const githubReleaseCustomizer = gruntCustomizer;
|
||||
const githubReleaseOptions = gruntOptionsMaker(githubReleaseDefaults, githubReleaseCustomizer);
|
||||
function browserifyGruntOptions(options = null, customizer = browserifyGruntCustomizer) {
|
||||
return _.merge({}, browserifyGruntDefaults, options, customizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates processor functions for license banners.
|
||||
@@ -151,7 +140,7 @@ module.exports = function(grunt) {
|
||||
watch: {
|
||||
skin: {
|
||||
files: ['src/css/**/*'],
|
||||
tasks: ['sass', 'wrapcodepoints']
|
||||
tasks: 'sass'
|
||||
},
|
||||
jshint: {
|
||||
files: ['src/**/*', 'test/unit/**/*.js', 'Gruntfile.js'],
|
||||
@@ -196,7 +185,7 @@ module.exports = function(grunt) {
|
||||
sass: {
|
||||
build: {
|
||||
files: {
|
||||
'build/temp/video-js.css': 'src/css/vjs.scss'
|
||||
'build/temp/video-js.css': 'src/css/video-js.scss'
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -305,16 +294,16 @@ module.exports = function(grunt) {
|
||||
auth: {
|
||||
user: process.env.VJS_GITHUB_USER,
|
||||
password: process.env.VJS_GITHUB_TOKEN
|
||||
},
|
||||
release: {
|
||||
tag_name: 'v'+ version.full,
|
||||
name: version.full,
|
||||
body: require('chg').find(version.full).changesRaw
|
||||
}
|
||||
},
|
||||
release: githubReleaseOptions(),
|
||||
prerelease: githubReleaseOptions({
|
||||
options: {
|
||||
release: {
|
||||
prerelease: true
|
||||
}
|
||||
}
|
||||
})
|
||||
files: {
|
||||
src: [`dist/video-js-${version.full}.zip`] // Files that you want to attach to Release
|
||||
}
|
||||
},
|
||||
browserify: {
|
||||
options: browserifyGruntOptions(),
|
||||
@@ -327,7 +316,7 @@ module.exports = function(grunt) {
|
||||
options: browserifyGruntOptions({
|
||||
transform: [
|
||||
['browserify-versionify', {
|
||||
placeholder: '../node_modules/videojs-vtt.js/dist/vtt.js',
|
||||
placeholder: '../node_modules/vtt.js/dist/vtt.js',
|
||||
version: 'https://cdn.rawgit.com/gkatsev/vtt.js/vjs-v0.12.1/dist/vtt.min.js'
|
||||
}],
|
||||
]
|
||||
@@ -455,7 +444,6 @@ module.exports = function(grunt) {
|
||||
'uglify',
|
||||
|
||||
'sass',
|
||||
'wrapcodepoints',
|
||||
'version:css',
|
||||
'cssmin',
|
||||
|
||||
@@ -480,17 +468,6 @@ module.exports = function(grunt) {
|
||||
'zip:dist'
|
||||
]);
|
||||
|
||||
// Sass turns unicode codepoints into utf8 characters.
|
||||
// We don't want that so we unwrapped them in the templates/scss.hbs file.
|
||||
// After sass has generated our css file, we need to wrap the codepoints
|
||||
// in quotes for it to work.
|
||||
grunt.registerTask('wrapcodepoints', function() {
|
||||
const sassConfig = grunt.config.get('sass.build.files');
|
||||
const cssPath = Object.keys(sassConfig)[0];
|
||||
const css = grunt.file.read(cssPath);
|
||||
grunt.file.write(cssPath, css.replace(/(\\f\w+);/g, "'$1';"));
|
||||
});
|
||||
|
||||
// Default task - build and test
|
||||
grunt.registerTask('default', ['test']);
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
import _ from 'lodash-compat';
|
||||
/**
|
||||
* Customizes _.merge behavior in `gruntOptions` to concatenate
|
||||
* arrays. This can be overridden on a per-call basis to
|
||||
*
|
||||
* @see https://lodash.com/docs#merge
|
||||
* @function GruntCustomizer
|
||||
* @private
|
||||
* @param {Mixed} objectValue
|
||||
* @param {Mixed} sourceValue
|
||||
* @return {Object}
|
||||
*/
|
||||
function gruntCustomizer(objectValue, sourceValue) {
|
||||
if (Array.isArray(objectValue)) {
|
||||
return objectValue.concat(sourceValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a gruntOptions instance for the specific defaultOptions and gruntCustomizer
|
||||
*
|
||||
* @function browserifyGruntOptions
|
||||
* @private
|
||||
* @param {Object} [options]
|
||||
* @param {Function} [customizer=gruntCustomizer]
|
||||
* If the default array-concatenation behavior is not desireable,
|
||||
* pass _.noop or a unique customizer (https://lodash.com/docs#merge).
|
||||
*
|
||||
* @return {Function}
|
||||
*/
|
||||
function gruntOptionsMaker(defaultOptions, gruntCustomizer) {
|
||||
/**
|
||||
* Creates a unique object of Browserify Grunt task options.
|
||||
*
|
||||
* @function gruntOptions
|
||||
* @private
|
||||
* @param {Object} [options]
|
||||
* @param {Function} [customizer=browserifyGruntCustomizer]
|
||||
* If the default array-concatenation behavior is not desireable,
|
||||
* pass _.noop or a unique customizer (https://lodash.com/docs#merge).
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
return function gruntOptions(options = null, customizer = gruntCustomizer) {
|
||||
return _.merge({}, defaultOptions, options, customizer);
|
||||
}
|
||||
};
|
||||
|
||||
export { gruntCustomizer, gruntOptionsMaker };
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "video.js",
|
||||
"description": "An HTML5 and Flash video player with a common API and skin for both.",
|
||||
"version": "5.6.0",
|
||||
"version": "5.2.2",
|
||||
"keywords": [
|
||||
"videojs",
|
||||
"html5",
|
||||
|
||||
+3
-27
@@ -250,37 +250,15 @@
|
||||
]
|
||||
},
|
||||
|
||||
"next": {
|
||||
"patch": {
|
||||
"description": "Create a patch release and tag it @next on npm",
|
||||
"release_type": "patch",
|
||||
"steps": [{ "include": "release run_next" }]
|
||||
},
|
||||
"minor": {
|
||||
"description": "Create a minor release and tag it @next on npm",
|
||||
"release_type": "minor",
|
||||
"steps": [{ "include": "release run_next" }]
|
||||
},
|
||||
"major": {
|
||||
"description": "Create a major release and tag it @next on npm",
|
||||
"release_type": "major",
|
||||
"steps": [{ "include": "release run_next" }]
|
||||
}
|
||||
},
|
||||
|
||||
"prerelease": {
|
||||
"release_type": "prerelease",
|
||||
"steps": [{ "include": "release run_next" }]
|
||||
},
|
||||
|
||||
"run_next": {
|
||||
"steps": [
|
||||
[ "git checkout master", "Checkout the developmet branch" ],
|
||||
[ "git pull upstream master", "Update the developmet branch" ],
|
||||
{ "include": "branch check" },
|
||||
{ "include": "update local master" },
|
||||
[ "git checkout -b temp-release-branch master","Create a temporary branch for the dist" ],
|
||||
[ "grunt version:{{release_type}}", "Bump package versions" ],
|
||||
[ "./build/bin/version", "Return the current VJS Version from the package.json file", "version" ],
|
||||
[ "grunt chg-release:{{version}}", "Update the changelog with the new release" ],
|
||||
[ "git commit -am 'v{{version}}'", "Add and commit the package changes" ],
|
||||
[ "git checkout master", "Checkout the developmet branch" ],
|
||||
[ "git merge temp-release-branch", "Merge package changes into the dev brach" ],
|
||||
@@ -291,13 +269,11 @@
|
||||
[ "git commit -m 'v{{version}} dist'", "Commit the dist changes" ],
|
||||
[ "git tag -a v{{version}} -m 'v{{version}}'", "Tag the release" ],
|
||||
[ "git push upstream --tags", "Push the new tag to the repo" ],
|
||||
[ "grunt github-release:prerelease", "Create a new pre-release on Github" ],
|
||||
[ "npm publish --tag next", "Publish to npm as 'next'" ],
|
||||
[ "git checkout master", "Checkout the developmet branch" ],
|
||||
[ "git branch -D temp-release-branch", "Delete the temp release branch" ]
|
||||
]
|
||||
},
|
||||
|
||||
"run": {
|
||||
"steps": [
|
||||
{ "include": "branch check" },
|
||||
@@ -316,7 +292,7 @@
|
||||
[ "git tag -a v{{version}} -m 'v{{version}}'", "Tag the release" ],
|
||||
[ "git push upstream --tags", "Push the new tag to the repo" ],
|
||||
[ "npm publish", "Publish to npm" ],
|
||||
[ "grunt github-release:release", "Create a new release on Github" ],
|
||||
[ "grunt github-release", "Create a new release on Github" ],
|
||||
[ "git checkout stable", "Checkout the developmet branch" ],
|
||||
[ "git branch -D temp-release-branch", "Delete the temp release branch" ]
|
||||
]
|
||||
|
||||
externo
+317
-1387
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
externo
+8
-11
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
+1
-1
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+24
-17
@@ -1,30 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Video.js | HTML5 Video Player</title>
|
||||
|
||||
<head>
|
||||
<title>Video.js | HTML5 Video Player</title>
|
||||
<link href="http://vjs.zencdn.net/5.0.2/video-js.css" rel="stylesheet">
|
||||
<script src="http://vjs.zencdn.net/ie8/1.1.0/videojs-ie8.min.js"></script>
|
||||
<script src="http://vjs.zencdn.net/5.0.2/video.js"></script>
|
||||
<!-- Chang URLs to wherever Video.js files will be hosted -->
|
||||
<!-- Default URLs assume the examples folder is included alongside video.js -->
|
||||
<link href="../../video-js.min.css" rel="stylesheet" type="text/css">
|
||||
|
||||
</head>
|
||||
<!-- Include ES5 shim, sham and html5 shiv for ie8 support -->
|
||||
<!-- Exclude this if you don't need ie8 support -->
|
||||
<script src="../../ie8/videojs-ie8.min.js"></script>
|
||||
|
||||
<!-- video.js must be in the <head> for older IEs to work. -->
|
||||
<script src="../../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";
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<video id="example_video_1" class="video-js vjs-default-skin" controls preload="none" width="640" height="264" poster="http://vjs.zencdn.net/v/oceans.png" data-setup="{}">
|
||||
<source src="http://vjs.zencdn.net/v/oceans.mp4" type="video/mp4">
|
||||
<source src="http://vjs.zencdn.net/v/oceans.webm" type="video/webm">
|
||||
<source src="http://vjs.zencdn.net/v/oceans.ogv" type="video/ogg">
|
||||
<track kind="captions" src="../shared/example-captions.vtt" srclang="en" label="English"></track>
|
||||
<!-- Tracks need an ending tag thanks to IE9 -->
|
||||
<track kind="subtitles" src="../shared/example-captions.vtt" srclang="en" label="English"></track>
|
||||
<!-- Tracks need an ending tag thanks to IE9 -->
|
||||
<video id="example_video_1" class="video-js vjs-default-skin" controls preload="none" width="640" height="264"
|
||||
poster="http://video-js.zencoder.com/oceans-clip.png"
|
||||
data-setup="{}">
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg' />
|
||||
<track kind="captions" src="../shared/example-captions.vtt" srclang="en" label="English"></track><!-- Tracks need an ending tag thanks to IE9 -->
|
||||
<track kind="subtitles" src="../shared/example-captions.vtt" srclang="en" label="English"></track><!-- Tracks need an ending tag thanks to IE9 -->
|
||||
<p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a></p>
|
||||
</video>
|
||||
</body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
BIN
Arquivo binário não exibido.
externo
+358
-983
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
externo
+1
-1
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
-26
@@ -1,26 +0,0 @@
|
||||
videojs.addLanguage("nb",{
|
||||
"Play": "Spill",
|
||||
"Pause": "Pause",
|
||||
"Current Time": "Aktuell tid",
|
||||
"Duration Time": "Varighet",
|
||||
"Remaining Time": "Gjenstående tid",
|
||||
"Stream Type": "Type strøm",
|
||||
"LIVE": "DIREKTE",
|
||||
"Loaded": "Lastet inn",
|
||||
"Progress": "Status",
|
||||
"Fullscreen": "Fullskjerm",
|
||||
"Non-Fullscreen": "Lukk fullskjerm",
|
||||
"Mute": "Lyd av",
|
||||
"Unmuted": "Lyd på",
|
||||
"Playback Rate": "Avspillingsrate",
|
||||
"Subtitles": "Undertekst på",
|
||||
"subtitles off": "Undertekst av",
|
||||
"Captions": "Undertekst for hørselshemmede på",
|
||||
"captions off": "Undertekst for hørselshemmede av",
|
||||
"Chapters": "Kapitler",
|
||||
"You aborted the media playback": "Du avbrøt avspillingen.",
|
||||
"A network error caused the media download to fail part-way.": "En nettverksfeil avbrøt nedlasting av videoen.",
|
||||
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikke lastes ned, på grunn av nettverksfeil eller serverfeil, eller fordi formatet ikke er støttet.",
|
||||
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoavspillingen ble avbrudt på grunn av ødelagte data eller fordi videoen ville gjøre noe som nettleseren din ikke har støtte for.",
|
||||
"No compatible source was found for this media.": "Fant ikke en kompatibel kilde for dette mediainnholdet."
|
||||
});
|
||||
externo
-26
@@ -1,26 +0,0 @@
|
||||
videojs.addLanguage("nn",{
|
||||
"Play": "Spel",
|
||||
"Pause": "Pause",
|
||||
"Current Time": "Aktuell tid",
|
||||
"Duration Time": "Varigheit",
|
||||
"Remaining Time": "Tid attende",
|
||||
"Stream Type": "Type straum",
|
||||
"LIVE": "DIREKTE",
|
||||
"Loaded": "Lasta inn",
|
||||
"Progress": "Status",
|
||||
"Fullscreen": "Fullskjerm",
|
||||
"Non-Fullscreen": "Stenga fullskjerm",
|
||||
"Mute": "Ljod av",
|
||||
"Unmuted": "Ljod på",
|
||||
"Playback Rate": "Avspelingsrate",
|
||||
"Subtitles": "Teksting på",
|
||||
"subtitles off": "Teksting av",
|
||||
"Captions": "Teksting for høyrselshemma på",
|
||||
"captions off": "Teksting for høyrselshemma av",
|
||||
"Chapters": "Kapitel",
|
||||
"You aborted the media playback": "Du avbraut avspelinga.",
|
||||
"A network error caused the media download to fail part-way.": "Ein nettverksfeil avbraut nedlasting av videoen.",
|
||||
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikkje lastas ned, på grunn av ein nettverksfeil eller serverfeil, eller av di formatet ikkje er stoda.",
|
||||
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoavspelinga blei broten på grunn av øydelagde data eller av di videoen ville gjera noe som nettlesaren din ikkje stodar.",
|
||||
"No compatible source was found for this media.": "Fant ikke en kompatibel kilde for dette mediainnholdet."
|
||||
});
|
||||
Arquivo binário não exibido.
externo
+137
-48
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
+1
-1
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
+317
-1387
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
externo
+29
-39
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
+9
-11
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
externo
+1
-1
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
@@ -1,30 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Video.js | HTML5 Video Player</title>
|
||||
|
||||
<head>
|
||||
<title>Video.js | HTML5 Video Player</title>
|
||||
<link href="http://vjs.zencdn.net/5.0.2/video-js.css" rel="stylesheet">
|
||||
<script src="http://vjs.zencdn.net/ie8/1.1.0/videojs-ie8.min.js"></script>
|
||||
<script src="http://vjs.zencdn.net/5.0.2/video.js"></script>
|
||||
<!-- Chang URLs to wherever Video.js files will be hosted -->
|
||||
<!-- Default URLs assume the examples folder is included alongside video.js -->
|
||||
<link href="../../video-js.min.css" rel="stylesheet" type="text/css">
|
||||
|
||||
</head>
|
||||
<!-- Include ES5 shim, sham and html5 shiv for ie8 support -->
|
||||
<!-- Exclude this if you don't need ie8 support -->
|
||||
<script src="../../ie8/videojs-ie8.min.js"></script>
|
||||
|
||||
<!-- video.js must be in the <head> for older IEs to work. -->
|
||||
<script src="../../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";
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<video id="example_video_1" class="video-js vjs-default-skin" controls preload="none" width="640" height="264" poster="http://vjs.zencdn.net/v/oceans.png" data-setup="{}">
|
||||
<source src="http://vjs.zencdn.net/v/oceans.mp4" type="video/mp4">
|
||||
<source src="http://vjs.zencdn.net/v/oceans.webm" type="video/webm">
|
||||
<source src="http://vjs.zencdn.net/v/oceans.ogv" type="video/ogg">
|
||||
<track kind="captions" src="../shared/example-captions.vtt" srclang="en" label="English"></track>
|
||||
<!-- Tracks need an ending tag thanks to IE9 -->
|
||||
<track kind="subtitles" src="../shared/example-captions.vtt" srclang="en" label="English"></track>
|
||||
<!-- Tracks need an ending tag thanks to IE9 -->
|
||||
<video id="example_video_1" class="video-js vjs-default-skin" controls preload="none" width="640" height="264"
|
||||
poster="http://video-js.zencoder.com/oceans-clip.png"
|
||||
data-setup="{}">
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg' />
|
||||
<track kind="captions" src="../shared/example-captions.vtt" srclang="en" label="English"></track><!-- Tracks need an ending tag thanks to IE9 -->
|
||||
<track kind="subtitles" src="../shared/example-captions.vtt" srclang="en" label="English"></track><!-- Tracks need an ending tag thanks to IE9 -->
|
||||
<p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a></p>
|
||||
</video>
|
||||
</body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -17,7 +17,7 @@ Wait Until the Player is Ready
|
||||
------------------------------
|
||||
The time it takes Video.js to set up the video and API will vary depending on the playback technology being used (HTML5 will often be much faster to load than Flash). For that reason we want to use the player's 'ready' function to trigger any code that requires the player's API.
|
||||
|
||||
```js
|
||||
```javascript
|
||||
videojs("example_video_1").ready(function(){
|
||||
var myPlayer = this;
|
||||
|
||||
|
||||
+14
-14
@@ -89,12 +89,12 @@ NOTE: These need to be added after the core Video.js script.
|
||||
3. During a Video.js player instantiation. Adding the languages to the configuration object provided in the `data-setup` attribute.
|
||||
|
||||
```html
|
||||
<video id="example_video_1" class="video-js vjs-default-skin"
|
||||
controls preload="auto" width="640" height="264"
|
||||
data-setup='{"languages":{"es":{"Play":"Juego"}}}'>
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg' />
|
||||
<video id="example_video_1" class="video-js vjs-default-skin"
|
||||
controls preload="auto" width="640" height="264"
|
||||
data-setup='{"languages":{"es":{"Play":"Juego"}}}'>
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg' />
|
||||
|
||||
<track kind="captions" src="http://example.com/path/to/captions.vtt" srclang="en" label="English" default>
|
||||
|
||||
@@ -110,12 +110,12 @@ Setting Default Language in a Video.js Player
|
||||
During a Video.js player instantiation you can force it to localize to a specific language by including the locale value into the configuration object via the `data-setup` attribute. Valid options listed at the bottom of the page for reference.
|
||||
|
||||
```html
|
||||
<video id="example_video_1" class="video-js vjs-default-skin"
|
||||
controls preload="auto" width="640" height="264"
|
||||
data-setup='{"language":"es"}'>
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg' />
|
||||
<video id="example_video_1" class="video-js vjs-default-skin"
|
||||
controls preload="auto" width="640" height="264"
|
||||
data-setup='{"language":"es"}'>
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg' />
|
||||
|
||||
<track kind="captions" src="http://example.com/path/to/captions.vtt" srclang="en" label="English" default>
|
||||
|
||||
@@ -145,7 +145,7 @@ Localization in Plugins
|
||||
|
||||
When you're developing a plugin, you can also introduce new localized strings. Simply wrap the string with the player's `localize` function:
|
||||
|
||||
```js
|
||||
```javascript
|
||||
var details = '<div class="vjs-errors-details">' + player.localize('Technical details') + '</div>';
|
||||
```
|
||||
|
||||
@@ -153,7 +153,7 @@ Language Codes
|
||||
--------------
|
||||
The following is a list of official language codes.
|
||||
|
||||
**NOTE:** For supported language translations, please see the [Languages Folder (/lang)](https://github.com/videojs/video.js/tree/master/lang) folder located in the project root.
|
||||
**NOTE:** For supported language translations, please see the [Languages Folder (/lang)](../../lang) folder located in the project root.
|
||||
|
||||
<table border="0" cellspacing="5" cellpadding="5">
|
||||
<tr>
|
||||
|
||||
@@ -119,7 +119,7 @@ Component Options
|
||||
You can set the options for any single player component. For instance, if you wanted to remove the `muteToggle` button, which
|
||||
is a child of `controlBar`, you can just set that component to false:
|
||||
|
||||
```js
|
||||
```javascript
|
||||
var player = videojs('video-id', {
|
||||
controlBar: {
|
||||
muteToggle: false
|
||||
@@ -134,5 +134,5 @@ notation.
|
||||
<video ... data-setup='{ "controlBar": { "muteToggle": false } }'></video>
|
||||
```
|
||||
|
||||
The [components guide](./components.md) has an excellent breakdown of the structure of a player, you
|
||||
just need to remember to nest child components in a `children` array for each level.
|
||||
The [components guide](components.md) has an excellent breakdown of the structure of a player, you
|
||||
just need to remember to nest child components in a `children` object for each level.
|
||||
|
||||
@@ -11,23 +11,19 @@ Step 1: Write Some Javascript
|
||||
-----------------------------
|
||||
You may have already done this step. Code up something interesting and then wrap it in a function. At the most basic level, that's all a video.js plugin is. By convention, plugins take a hash of options as their first argument:
|
||||
|
||||
```js
|
||||
function examplePlugin(options) {
|
||||
this.on('play', function(e) {
|
||||
console.log('playback has started!');
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
When it's activated, `this` will be the Video.js player your plugin is attached to. You can use anything you'd like in the [Video.js API](./api.md) when you're writing a plugin: change the `src`, mess up the DOM, or listen for and emit your own events.
|
||||
When it's activated, `this` will be the Video.js player your plugin is attached to. You can use anything you'd like in the [Video.js API](api.md) when you're writing a plugin: change the `src`, mess up the DOM, or listen for and emit your own events.
|
||||
|
||||
Step 2: Registering A Plugin
|
||||
-------------------------------
|
||||
It's time to give the rest of the world the opportunity to be awed by your genius. When your plugin is loaded, it needs to let Video.js know this amazing new functionality is now available:
|
||||
|
||||
```js
|
||||
videojs.plugin('examplePlugin', examplePlugin);
|
||||
```
|
||||
|
||||
From this point on, your plugin will be added to the Video.js prototype and will show up as a property on every instance created. Make sure you choose a unique name that doesn't clash with any of the properties already in Video.js. Which leads us to...
|
||||
|
||||
@@ -35,7 +31,6 @@ Step 3: Using A Plugin
|
||||
----------------------
|
||||
There are two ways to initialize a plugin. If you're creating your video tag dynamically, you can specify the plugins you'd like to initialize with it and any options you want to pass to them:
|
||||
|
||||
```js
|
||||
videojs('vidId', {
|
||||
plugins: {
|
||||
examplePlugin: {
|
||||
@@ -43,17 +38,10 @@ There are two ways to initialize a plugin. If you're creating your video tag dyn
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
If you've already initialized your video tag, you can activate a plugin at any time by calling its setup function directly:
|
||||
|
||||
```js
|
||||
var video = videojs('cool-vid');
|
||||
video.examplePlugin({ exampleOption: true });
|
||||
```
|
||||
|
||||
That's it. Head on over to the [Video.js wiki](https://github.com/videojs/video.js/wiki/Plugins) and add your plugin to the list so everyone else can check it out.
|
||||
|
||||
## How should I use the Video.js icons in my plugin?
|
||||
|
||||
If you'd like to use any of the icons available in the [Video.js icon set](http://videojs.github.io/font/), please target them via the CSS class names instead of codepoints. The codepoints *may* change between versions of the font, so using the class names ensures that your plugin will stay up to date with any font changes.
|
||||
|
||||
@@ -6,11 +6,11 @@ Sometimes, you want to remove players after page load (in single page apps or mo
|
||||
Call `.dispose()`
|
||||
-----------------
|
||||
|
||||
To remove the html associated with your videojs player from the page always call the player's [`dispose()`](http://docs.videojs.com/docs/api/player.html#Methodsdispose) method:
|
||||
To remove the html associated with your videojs player from the page always call the player's [`dispose()`](https://github.com/videojs/video.js/blob/stable/docs/api/vjs.Player.md#dispose) method:
|
||||
|
||||
```js
|
||||
```javascript```
|
||||
var oldPlayer = document.getElementById('my-player');
|
||||
videojs(oldPlayer).dispose();
|
||||
videojs(oldPlayer).dispose();
|
||||
```
|
||||
|
||||
This method will:
|
||||
|
||||
@@ -9,17 +9,15 @@ Step 1: Include the Video.js Javascript and CSS files in the head of your page.
|
||||
You can download the Video.js source and host it on your own servers, or use the free CDN hosted version. As of Video.js 5.0, the source is [transpiled from ES2015](http://babeljs.io/) (formerly known as ES6) to [ES5](https://es5.github.io/), but IE8 only supports ES3. In order to continue to support IE8, we've bundled an [ES5 shim and sham](https://github.com/es-shims/es5-shim) together and hosted it on the CDN.
|
||||
|
||||
```html
|
||||
<script src="//vjs.zencdn.net/ie8/1.1.1/videojs-ie8.min.js"></script>
|
||||
<script src="//vjs.zencdn.net/ie8/1.1.0/videojs-ie8.min.js"></script>
|
||||
```
|
||||
|
||||
### CDN Version ###
|
||||
```html
|
||||
<link href="//vjs.zencdn.net/5.4.6/video-js.min.css" rel="stylesheet">
|
||||
<script src="//vjs.zencdn.net/5.4.6/video.min.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>
|
||||
```
|
||||
|
||||
Alternatively you can always [go here](http://videojs.com/getting-started/) to get the latest URL for videojs CDN.
|
||||
|
||||
We include a stripped down Google Analytics pixel that tracks a random percentage (currently 1%) of players loaded from the CDN. This allows us to see (roughly) what browsers are in use in the wild, along with other useful metrics such as OS and device. If you'd like to disable analytics, you can simply include the following global **before** including Video.js:
|
||||
|
||||
```js
|
||||
@@ -58,7 +56,7 @@ With Video.js you just use an HTML5 video tag to embed a video. Video.js will th
|
||||
|
||||
> Note: The `data-setup` attribute described here should not be used if you use the alternative setup described in the next section.
|
||||
|
||||
1. The 'data-setup' Attribute tells Video.js to automatically set up the video when the page is ready, and read any options (in JSON format) from the attribute (see [options](./options.md)). There are other methods for initializing the player, but this is the easiest.
|
||||
1. The 'data-setup' Attribute tells Video.js to automatically set up the video when the page is ready, and read any options (in JSON format) from the attribute (see [options](options.md)). There are other methods for initializing the player, but this is the easiest.
|
||||
|
||||
2. The 'id' Attribute: Should be used and unique for every video on the same page.
|
||||
|
||||
@@ -72,9 +70,9 @@ Otherwise include/exclude attributes, settings, sources, and tracks exactly as y
|
||||
controls preload="auto" width="640" height="264"
|
||||
poster="http://video-js.zencoder.com/oceans-clip.png"
|
||||
data-setup='{"example_option":true}'>
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type="video/mp4" />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type="video/webm" />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type="video/ogg" />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg' />
|
||||
<p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a></p>
|
||||
</video>
|
||||
```
|
||||
|
||||
@@ -9,7 +9,7 @@ enabled, you'll need to manually include them.
|
||||
|
||||
## Icons
|
||||
|
||||
You can view all of the icons available in the base theme by renaming and viewing [`icons.html.example`](https://github.com/videojs/video.js/blob/master/sandbox/icons.html.example) in the sandbox directory.
|
||||
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
|
||||
|
||||
|
||||
@@ -49,40 +49,6 @@ When adding additional Tech to a video player, make sure to add the supported te
|
||||
techOrder: ["html5", "flash", "other supported tech"]
|
||||
});
|
||||
|
||||
Technology Ordering
|
||||
==================
|
||||
By default Video.js performs "Tech-first" ordering when it searches for a source/tech combination to play videos. This means that if you have two sources and two techs, video.js will try to play each video with the first tech in the `techOrder` option property before moving on to try the next playback technology.
|
||||
|
||||
Tech-first ordering can present a problem if you have a `sourceHandler` that supports both `Html5` and `Flash` techs such as videojs-contrib-hls.
|
||||
|
||||
For example, given the following video element:
|
||||
|
||||
<video data-setup='{"techOrder": ["html5", "flash"]}'>
|
||||
<source src="http://your.static.provider.net/path/to/video.m3u8" type="application/x-mpegURL">
|
||||
<source src="http://your.static.provider.net/path/to/video.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
There is a good chance that the mp4 source will be selected on platforms that do not have media source extensions. Video.js will try all sources against the first playback technology, in this case `Html5`, and select the first source that can play - in this case MP4.
|
||||
|
||||
In "Tech-first" mode, the tests run something like this:
|
||||
Can video.m3u8 play with Html5? No...
|
||||
Can video.mp4 play with Html5? Yes! Use the second source.
|
||||
|
||||
Video.js now provides another method of selecting the source - "Source-first" ordering. In this mode, Video.js tries the first source against every tech in `techOrder` before moving onto the next source.
|
||||
|
||||
With a player setup as follows:
|
||||
|
||||
<video data-setup='{"techOrder": ["html5", "flash"], "sourceOrder": true}'>
|
||||
<source src="http://your.static.provider.net/path/to/video.m3u8" type="application/x-mpegURL">
|
||||
<source src="http://your.static.provider.net/path/to/video.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
The Flash-based HLS support will be tried before falling back to the MP4 source.
|
||||
|
||||
In "Source-first" mode, the tests run something like this:
|
||||
Can video.m3u8 play with Html5? No...
|
||||
Can video.m3u8 play with Flash? Yes! Use the first source.
|
||||
|
||||
Flash Technology
|
||||
==================
|
||||
The Flash playback tech is a part of the default `techOrder`. You may notice undesirable playback behavior in browsers that are subject to using this playback tech, in particular when scrubbing and seeking within a video. This behavior is a result of Flash's progressive video playback.
|
||||
|
||||
+25
-3
@@ -23,9 +23,9 @@ Once you have your WebVTT file created, you can add it to Video.js using the tra
|
||||
<video id="example_video_1" class="video-js vjs-default-skin"
|
||||
controls preload="auto" width="640" height="264"
|
||||
data-setup='{"example_option":true}'>
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type="video/mp4" />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type="video/webm" />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type="video/ogg" />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm' />
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg' />
|
||||
|
||||
<track kind="captions" src="http://example.com/path/to/captions.vtt" srclang="en" label="English" default>
|
||||
|
||||
@@ -56,6 +56,8 @@ The two-letter code (valid BCP 47 language tag) for the language of the text tra
|
||||
|
||||
<table border="0" cellspacing="5" cellpadding="5">
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
<table>
|
||||
<tr><th>ab<th><td>Abkhazian</td></tr>
|
||||
<tr><th>aa<th><td>Afar</td></tr>
|
||||
@@ -94,6 +96,12 @@ The two-letter code (valid BCP 47 language tag) for the language of the text tra
|
||||
<tr><th>fa<th><td>Farsi</td></tr>
|
||||
<tr><th>fj<th><td>Fiji</td></tr>
|
||||
<tr><th>fi<th><td>Finnish</td></tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<table>
|
||||
<tr><th>fr<th><td>French</td></tr>
|
||||
<tr><th>fy<th><td>Frisian</td></tr>
|
||||
<tr><th>gl<th><td>Galician</td></tr>
|
||||
@@ -131,6 +139,12 @@ The two-letter code (valid BCP 47 language tag) for the language of the text tra
|
||||
<tr><th>ku<th><td>Kurdish</td></tr>
|
||||
<tr><th>lo<th><td>Laothian</td></tr>
|
||||
<tr><th>la<th><td>Latin</td></tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<table>
|
||||
<tr><th>lv<th><td>Latvian (Lettish)</td></tr>
|
||||
<tr><th>li<th><td>Limburgish ( Limburger)</td></tr>
|
||||
<tr><th>ln<th><td>Lingala</td></tr>
|
||||
@@ -168,6 +182,12 @@ The two-letter code (valid BCP 47 language tag) for the language of the text tra
|
||||
<tr><th>sn<th><td>Shona</td></tr>
|
||||
<tr><th>ii<th><td>Sichuan Yi</td></tr>
|
||||
<tr><th>sd<th><td>Sindhi</td></tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<table>
|
||||
<tr><th>si<th><td>Sinhalese</td></tr>
|
||||
<tr><th>ss<th><td>Siswati</td></tr>
|
||||
<tr><th>sk<th><td>Slovak</td></tr>
|
||||
@@ -204,5 +224,7 @@ The two-letter code (valid BCP 47 language tag) for the language of the text tra
|
||||
<tr><th>yo<th><td>Yoruba</td></tr>
|
||||
<tr><th>zu<th><td>Zulu</td></tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"Play": "Spill",
|
||||
"Pause": "Pause",
|
||||
"Current Time": "Aktuell tid",
|
||||
"Duration Time": "Varighet",
|
||||
"Remaining Time": "Gjenstående tid",
|
||||
"Stream Type": "Type strøm",
|
||||
"LIVE": "DIREKTE",
|
||||
"Loaded": "Lastet inn",
|
||||
"Progress": "Status",
|
||||
"Fullscreen": "Fullskjerm",
|
||||
"Non-Fullscreen": "Lukk fullskjerm",
|
||||
"Mute": "Lyd av",
|
||||
"Unmuted": "Lyd på",
|
||||
"Playback Rate": "Avspillingsrate",
|
||||
"Subtitles": "Undertekst på",
|
||||
"subtitles off": "Undertekst av",
|
||||
"Captions": "Undertekst for hørselshemmede på",
|
||||
"captions off": "Undertekst for hørselshemmede av",
|
||||
"Chapters": "Kapitler",
|
||||
"You aborted the media playback": "Du avbrøt avspillingen.",
|
||||
"A network error caused the media download to fail part-way.": "En nettverksfeil avbrøt nedlasting av videoen.",
|
||||
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikke lastes ned, på grunn av nettverksfeil eller serverfeil, eller fordi formatet ikke er støttet.",
|
||||
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoavspillingen ble avbrudt på grunn av ødelagte data eller fordi videoen ville gjøre noe som nettleseren din ikke har støtte for.",
|
||||
"No compatible source was found for this media.": "Fant ikke en kompatibel kilde for dette mediainnholdet."
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"Play": "Spel",
|
||||
"Pause": "Pause",
|
||||
"Current Time": "Aktuell tid",
|
||||
"Duration Time": "Varigheit",
|
||||
"Remaining Time": "Tid attende",
|
||||
"Stream Type": "Type straum",
|
||||
"LIVE": "DIREKTE",
|
||||
"Loaded": "Lasta inn",
|
||||
"Progress": "Status",
|
||||
"Fullscreen": "Fullskjerm",
|
||||
"Non-Fullscreen": "Stenga fullskjerm",
|
||||
"Mute": "Ljod av",
|
||||
"Unmuted": "Ljod på",
|
||||
"Playback Rate": "Avspelingsrate",
|
||||
"Subtitles": "Teksting på",
|
||||
"subtitles off": "Teksting av",
|
||||
"Captions": "Teksting for høyrselshemma på",
|
||||
"captions off": "Teksting for høyrselshemma av",
|
||||
"Chapters": "Kapitel",
|
||||
"You aborted the media playback": "Du avbraut avspelinga.",
|
||||
"A network error caused the media download to fail part-way.": "Ein nettverksfeil avbraut nedlasting av videoen.",
|
||||
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikkje lastas ned, på grunn av ein nettverksfeil eller serverfeil, eller av di formatet ikkje er stoda.",
|
||||
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoavspelinga blei broten på grunn av øydelagde data eller av di videoen ville gjera noe som nettlesaren din ikkje stodar.",
|
||||
"No compatible source was found for this media.": "Fant ikke en kompatibel kilde for dette mediainnholdet."
|
||||
}
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "video.js",
|
||||
"description": "An HTML5 and Flash video player with a common API and skin for both.",
|
||||
"version": "5.6.0",
|
||||
"version": "5.2.2",
|
||||
"copyright": "Copyright Brightcove, Inc. <https://www.brightcove.com/>",
|
||||
"license": "Apache-2.0",
|
||||
"keywords": [
|
||||
@@ -28,10 +28,10 @@
|
||||
"object.assign": "^4.0.1",
|
||||
"safe-json-parse": "^4.0.0",
|
||||
"tsml": "1.0.1",
|
||||
"videojs-font": "1.5.1",
|
||||
"videojs-ie8": "1.1.2",
|
||||
"videojs-font": "1.4.0",
|
||||
"videojs-ie8": "1.1.0",
|
||||
"videojs-swf": "5.0.1",
|
||||
"videojs-vtt.js": "^0.12.1",
|
||||
"vtt.js": "git+https://github.com/gkatsev/vtt.js.git#vjs-v0.12.1",
|
||||
"xhr": "~2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
</div>
|
||||
|
||||
<video id="vid1" class="video-js vjs-default-skin" controls preload="auto" width="640" height="264"
|
||||
poster="http://vjs.zencdn.net/v/oceans.png"
|
||||
poster="http://video-js.zencoder.com/oceans-clip.png"
|
||||
data-setup='{}'>
|
||||
<source src="http://vjs.zencdn.net/v/oceans.mp4" type="video/mp4">
|
||||
<source src="http://vjs.zencdn.net/v/oceans.webm" type="video/webm">
|
||||
<source src="http://vjs.zencdn.net/v/oceans.ogv" type="video/ogg">
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4'>
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm'>
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg'>
|
||||
<track kind="captions" src="../docs/examples/shared/example-captions.vtt" srclang="en" label="English"></track><!-- Tracks need an ending tag thanks to IE9 -->
|
||||
<p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a></p>
|
||||
</video>
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
<body>
|
||||
<p style="background-color:#eee; border: 1px solid #777; padding: 10px; font-size: .8em; line-height: 1.5em; font-family: Verdana, sans-serif;">This page shows you how to create, register and initialize a Video.js plugin.</p>
|
||||
|
||||
<video id="vid1" class="video-js vjs-default-skin" controls preload="auto" width="640" height="264" poster="http://vjs.zencdn.net/v/oceans.png">
|
||||
<source src="http://vjs.zencdn.net/v/oceans.mp4" type="video/mp4">
|
||||
<source src="http://vjs.zencdn.net/v/oceans.webm" type="video/webm">
|
||||
<source src="http://vjs.zencdn.net/v/oceans.ogv" type="video/ogg">
|
||||
<video id="vid1" class="video-js vjs-default-skin" controls preload="auto" width="640" height="264" poster="http://video-js.zencoder.com/oceans-clip.png">
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4'>
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm'>
|
||||
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg'>
|
||||
<p>Video Playback Not Supported</p>
|
||||
</video>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Text, icons, hover states
|
||||
$primary-foreground-color: #fff !default;
|
||||
$primary-foreground-color: #fff;
|
||||
|
||||
// Control backgrounds (control bar, big play, menus)
|
||||
$primary-background-color: #2B333F !default;
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
$icon-font-path: 'font' !default;
|
||||
$icon-codepoints: false !default;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
opacity: 1;
|
||||
border: 0.06666em solid $primary-foreground-color;
|
||||
|
||||
// Need a slightly gray bg so it can be seen on black backgrounds
|
||||
/* Need a slightly gray bg so it can be seen on black backgrounds */
|
||||
@include background-color-with-alpha($primary-background-color, $primary-background-transparency);
|
||||
@include border-radius(0.3em);
|
||||
@include transition(all 0.4s);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
}
|
||||
|
||||
.vjs-chapters-button .vjs-menu {
|
||||
left: -10em; // (Width of vjs-menu - width of vjs-control) / 2
|
||||
left: -10em; /* (Width of vjs-menu - width of vjs-control) / 2 */
|
||||
width: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
.vjs-controls-disabled .vjs-control-bar,
|
||||
.vjs-using-native-controls .vjs-control-bar,
|
||||
.vjs-error .vjs-control-bar {
|
||||
// !important is ok in this context.
|
||||
/* !important is ok in this context. */
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@@ -42,16 +42,17 @@
|
||||
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
|
||||
/* 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";
|
||||
.vjs-user-inactive.vjs-playing .vjs-control-bar :before {
|
||||
@media #{$ie8screen} { content: ""; }
|
||||
}
|
||||
|
||||
// IE 8 + 9 Support
|
||||
/* IE 8 + 9 Support */
|
||||
.vjs-has-started.vjs-no-flex .vjs-control-bar {
|
||||
display: table;
|
||||
}
|
||||
|
||||
@@ -19,19 +19,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Replacement for focus outline
|
||||
/* 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-foreground-color, 1);
|
||||
}
|
||||
|
||||
// Hide control text visually, but have it available for screenreaders
|
||||
/* Hide control text visually, but have it available for screenreaders */
|
||||
.video-js .vjs-control-text {
|
||||
@include hide-visually;
|
||||
}
|
||||
|
||||
// IE 8 + 9 Support
|
||||
/* IE 8 + 9 Support */
|
||||
.vjs-no-flex .vjs-control {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
.video-js .vjs-fullscreen-control {
|
||||
@extend .vjs-icon-fullscreen-enter;
|
||||
}
|
||||
// Switch to the exit icon when the player is in fullscreen
|
||||
/* Switch to the exit icon when the player is in fullscreen */
|
||||
.video-js.vjs-fullscreen .vjs-fullscreen-control {
|
||||
@extend .vjs-icon-fullscreen-exit;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
.video-js {
|
||||
// display:inline-block would be closer to the video el's display:inline
|
||||
// but it results in flash reloading when going into fullscreen [#2205]
|
||||
/* display:inline-block would be closer to the video el's display:inline
|
||||
* but it results in flash reloading when going into fullscreen [#2205]
|
||||
*/
|
||||
display: block;
|
||||
// Make video.js videos align top when next to video elements
|
||||
/* Make video.js videos align top when next to video elements */
|
||||
vertical-align: top;
|
||||
box-sizing: border-box;
|
||||
|
||||
@@ -10,21 +11,21 @@
|
||||
background-color: #000;
|
||||
position: relative;
|
||||
padding: 0;
|
||||
// Start with 10px for base font size so other dimensions can be em based and
|
||||
// easily calculable.
|
||||
/* Start with 10px for base font size so other dimensions can be em based and
|
||||
easily calculable. */
|
||||
font-size: 10px;
|
||||
line-height: 1;
|
||||
|
||||
// Provide some basic defaults for fonts
|
||||
/* Provide some basic defaults for fonts */
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
// Avoiding helvetica: issue #376
|
||||
/* 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.
|
||||
/* Fix for Firefox 9 fullscreen (only if it is enabled). Not needed when
|
||||
checking fullScreenEnabled. */
|
||||
&:-moz-full-screen { position: absolute; }
|
||||
|
||||
&:-webkit-full-screen {
|
||||
@@ -33,35 +34,35 @@
|
||||
}
|
||||
}
|
||||
|
||||
// All elements inherit border-box sizing
|
||||
/* All elements inherit border-box sizing */
|
||||
.video-js *,
|
||||
.video-js *:before,
|
||||
.video-js *:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
// List style reset
|
||||
/* List style reset */
|
||||
.video-js ul {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
list-style-position: outside;
|
||||
|
||||
// Important to specify each
|
||||
/* Important to specify each */
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
// Fill the width of the containing element and use padding to create the
|
||||
// desired aspect ratio. Default to 16x9 unless another ratio is given.
|
||||
/* Fill the width of the containing element and use padding to create the
|
||||
desired aspect ratio. Default to 16x9 unless another ratio is given. */
|
||||
@mixin apply-aspect-ratio($width, $height) {
|
||||
padding-top: 100% * ($height/$width);
|
||||
}
|
||||
|
||||
// Not including a default AR in vjs-fluid because it would override
|
||||
// the user set AR injected into the header.
|
||||
/* Not including a default AR in vjs-fluid because it would override
|
||||
the user set AR injected into the header. */
|
||||
.video-js.vjs-fluid,
|
||||
.video-js.vjs-16-9,
|
||||
.video-js.vjs-4-3 {
|
||||
@@ -83,8 +84,8 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// Playback technology elements expand to the width/height of the containing div
|
||||
// <video> or <object>
|
||||
/* Playback technology elements expand to the width/height of the containing div
|
||||
<video> or <object> */
|
||||
.video-js .vjs-tech {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -93,12 +94,12 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// Fullscreen Styles
|
||||
/* 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
|
||||
/* Fix for IE6 full-window. http://www.cssplay.co.uk/layouts/fixed.html */
|
||||
overflow-y: auto;
|
||||
}
|
||||
.vjs-full-window .video-js.vjs-fullscreen {
|
||||
@@ -113,7 +114,7 @@ body.vjs-full-window {
|
||||
.video-js.vjs-fullscreen {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
// Undo any aspect ratio padding for fluid layouts
|
||||
/* Undo any aspect ratio padding for fluid layouts */
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
.video-js.vjs-fullscreen.vjs-user-inactive {
|
||||
@@ -121,7 +122,7 @@ body.vjs-full-window {
|
||||
}
|
||||
|
||||
|
||||
// Hide disabled or unsupported controls.
|
||||
/* Hide disabled or unsupported controls. */
|
||||
.vjs-hidden { display: none !important; }
|
||||
|
||||
// Visually hidden offscreen, but accessible to screen readers.
|
||||
@@ -139,10 +140,10 @@ body.vjs-full-window {
|
||||
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.
|
||||
/* 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: #fff;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
margin: -25px 0 0 -25px;
|
||||
opacity: 0.85;
|
||||
|
||||
// Need to fix centered page layouts
|
||||
/* Need to fix centered page layouts */
|
||||
text-align: left;
|
||||
|
||||
border: 6px solid rgba($primary-background-color, $primary-background-transparency);
|
||||
@@ -33,14 +33,14 @@
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
border-radius: inherit;
|
||||
// Keep 100% opacity so they don't show through each other
|
||||
/* Keep 100% opacity so they don't show through each other */
|
||||
opacity: 1;
|
||||
border: inherit;
|
||||
border-color: transparent;
|
||||
border-top-color: white;
|
||||
}
|
||||
|
||||
// only animate when showing because it can be processor heavy
|
||||
/* only animate when showing because it can be processor heavy */
|
||||
.vjs-seeking .vjs-loading-spinner:before,
|
||||
.vjs-seeking .vjs-loading-spinner:after,
|
||||
.vjs-waiting .vjs-loading-spinner:before,
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// Used for IE8 fallback
|
||||
/* Used for IE8 fallback */
|
||||
.vjs-poster img {
|
||||
display: block;
|
||||
vertical-align: middle;
|
||||
@@ -25,23 +25,23 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// Hide the poster after the video has started playing
|
||||
/* Hide the poster after the video has started playing */
|
||||
.vjs-has-started .vjs-poster {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Don't hide the poster if we're playing audio
|
||||
/* Don't hide the poster if we're playing audio */
|
||||
.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
|
||||
/* Hide the poster when controls are disabled because it's clickable
|
||||
and the native poster can take over */
|
||||
.vjs-controls-disabled .vjs-poster {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Hide the poster when native controls are used otherwise it covers them
|
||||
/* Hide the poster when native controls are used otherwise it covers them */
|
||||
.vjs-using-native-controls .vjs-poster {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
//
|
||||
// Let's talk pixel math!
|
||||
// Start with a base font size of 10px (assuming that hasn't changed)
|
||||
// No Hover:
|
||||
// - Progress holder is 3px
|
||||
// - Progress handle is 9px
|
||||
// - Progress handle is pulled up 3px to center it.
|
||||
//
|
||||
// Hover:
|
||||
// - Progress holder becomes 5px
|
||||
// - Progress handle becomes 15px
|
||||
// - Progress handle is pulled up 5px to center it
|
||||
//
|
||||
/**
|
||||
* Let's talk pixel math!
|
||||
* Start with a base font size of 10px (assuming that hasn't changed)
|
||||
* No Hover:
|
||||
* - Progress holder is 3px
|
||||
* - Progress handle is 9px
|
||||
* - Progress handle is pulled up 3px to center it.
|
||||
*
|
||||
* Hover:
|
||||
* - Progress holder becomes 5px
|
||||
* - Progress handle becomes 15px
|
||||
* - Progress handle is pulled up 5px to center it
|
||||
*/
|
||||
|
||||
.video-js .vjs-progress-control {
|
||||
@include flex(auto);
|
||||
@@ -21,30 +21,30 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Box containing play and load progresses. Also acts as seek scrubber.
|
||||
/* Box containing play and load progresses. Also acts as seek scrubber. */
|
||||
.video-js .vjs-progress-holder {
|
||||
@include flex(auto);
|
||||
@include transition(all 0.2s);
|
||||
height: 0.3em;
|
||||
}
|
||||
|
||||
// We need an increased hit area on hover
|
||||
/* We need an increased hit area on hover */
|
||||
.video-js .vjs-progress-control:hover .vjs-progress-holder {
|
||||
font-size: 1.666666666666666666em
|
||||
}
|
||||
|
||||
/* If we let the font size grow as much as everything else, the current time tooltip ends up
|
||||
ginormous. If you'd like to enable the current time tooltip all the time, this should be disabled
|
||||
to avoid a weird hitch when you roll off the hover. */
|
||||
|
||||
// Also show the current time tooltip
|
||||
/* Also show the current time tooltip */
|
||||
.video-js .vjs-progress-control:hover .vjs-mouse-display:after,
|
||||
.video-js .vjs-progress-control:hover .vjs-play-progress:after {
|
||||
display: block;
|
||||
|
||||
/* If we let the font size grow as much as everything else, the current time tooltip ends up
|
||||
ginormous. If you'd like to enable the current time tooltip all the time, this should be disabled
|
||||
to avoid a weird hitch when you roll off the hover. */
|
||||
font-size: 0.6em;
|
||||
}
|
||||
|
||||
// Progress Bars
|
||||
/* 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 {
|
||||
@@ -53,9 +53,9 @@
|
||||
height: 0.3em;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
// updated by javascript during playback
|
||||
/* updated by javascript during playback */
|
||||
width: 0;
|
||||
// Needed for IE6
|
||||
/* Needed for IE6 *///
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
@@ -81,9 +81,9 @@
|
||||
}
|
||||
|
||||
// Current Time "tooltip"
|
||||
// By default this is hidden and only shown when hovering over the progress control
|
||||
.video-js .vjs-mouse-display:after,
|
||||
.video-js .vjs-play-progress:after {
|
||||
/* By default this is hidden and only shown when hovering over the progress control */
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: -2.4em;
|
||||
@@ -101,18 +101,18 @@
|
||||
}
|
||||
|
||||
.video-js .vjs-load-progress {
|
||||
// For IE8 we'll lighten the color
|
||||
background: lighten($secondary-background-color, 25%);
|
||||
// Otherwise we'll rely on stacked opacities
|
||||
/* For IE8 we'll lighten the color */
|
||||
background: ligthen($secondary-background-color, 25%);
|
||||
/* Otherwise we'll rely on stacked opacities */
|
||||
background: rgba($secondary-background-color, $secondary-background-transparency);
|
||||
}
|
||||
|
||||
// there are child elements of the load progress bar that represent the
|
||||
// specific time ranges that have been buffered
|
||||
/* 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 {
|
||||
// For IE8 we'll lighten the color
|
||||
background: lighten($secondary-background-color, 50%);
|
||||
// Otherwise we'll rely on stacked opacities
|
||||
/* For IE8 we'll lighten the color */
|
||||
background: ligthen($secondary-background-color, 50%);
|
||||
/* Otherwise we'll rely on stacked opacities */
|
||||
background: rgba($secondary-background-color, 0.75);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Emulated tracks
|
||||
/* Emulated tracks */
|
||||
.vjs-text-track-display {
|
||||
position: absolute;
|
||||
bottom: 3em;
|
||||
@@ -8,30 +8,30 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// Move captions down when controls aren't being shown
|
||||
/* Move captions down when controls aren't being shown */
|
||||
.video-js.vjs-user-inactive.vjs-playing .vjs-text-track-display {
|
||||
bottom: 1em;
|
||||
}
|
||||
|
||||
// Individual tracks
|
||||
/* 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)
|
||||
/* Transparent black background, or fallback to all black (oldIE) */
|
||||
@include background-color-with-alpha(#000, 0.5);
|
||||
}
|
||||
|
||||
.vjs-subtitles { color: #fff; } // Subtitles are white
|
||||
.vjs-captions { color: #fc6; } // Captions are yellow
|
||||
.vjs-subtitles { color: #fff /* Subtitles are white */; }
|
||||
.vjs-captions { color: #fc6 /* Captions are yellow */; }
|
||||
.vjs-tt-cue { display: block; }
|
||||
|
||||
// Native tracks
|
||||
/* Native tracks */
|
||||
video::-webkit-media-text-track-display {
|
||||
@include transform(translateY(-3em));
|
||||
}
|
||||
|
||||
// Move captions down when controls aren't being shown
|
||||
/* Move captions down when controls aren't being shown */
|
||||
.video-js.vjs-user-inactive.vjs-playing video::-webkit-media-text-track-display {
|
||||
@include transform(translateY(-1.5em));
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
// We need the extra specificity that referencing .vjs-no-flex provides.
|
||||
/* We need the extra specificity that referencing .vjs-no-flex provides. */
|
||||
.video-js .vjs-current-time,
|
||||
.vjs-no-flex .vjs-current-time {
|
||||
display: none;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
}
|
||||
|
||||
.video-js .vjs-volume-bar {
|
||||
margin: 1.35em 0.45em;
|
||||
margin: 1.35em;
|
||||
}
|
||||
|
||||
.vjs-volume-bar.vjs-slider-horizontal {
|
||||
@@ -36,7 +36,6 @@
|
||||
.vjs-volume-bar.vjs-slider-vertical {
|
||||
width: 0.3em;
|
||||
height: 5em;
|
||||
margin: 1.35em auto;
|
||||
}
|
||||
|
||||
.video-js .vjs-volume-level {
|
||||
@@ -74,7 +73,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Assumes volume starts at 1.0.
|
||||
/* Assumes volume starts at 1.0. */
|
||||
.vjs-volume-bar.vjs-slider-vertical .vjs-volume-level {
|
||||
height: 100%;
|
||||
}
|
||||
@@ -83,11 +82,11 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// 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.
|
||||
/* 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. */
|
||||
.vjs-menu-button-popup.vjs-volume-menu-button .vjs-menu {
|
||||
display: block;
|
||||
width: 0;
|
||||
@@ -97,7 +96,6 @@
|
||||
|
||||
.vjs-menu-button-popup.vjs-volume-menu-button-vertical .vjs-menu {
|
||||
left: 0.5em;
|
||||
height: 8em;
|
||||
}
|
||||
.vjs-menu-button-popup.vjs-volume-menu-button-horizontal .vjs-menu {
|
||||
left: -2em;
|
||||
@@ -113,23 +111,19 @@
|
||||
}
|
||||
|
||||
.vjs-volume-menu-button-vertical:hover .vjs-menu-content,
|
||||
.vjs-volume-menu-button-vertical:focus .vjs-menu-content,
|
||||
.vjs-volume-menu-button-vertical.vjs-slider-active .vjs-menu-content,
|
||||
.vjs-volume-menu-button-vertical .vjs-lock-showing .vjs-menu-content {
|
||||
height: 8em;
|
||||
width: 2.9em;
|
||||
}
|
||||
|
||||
.vjs-volume-menu-button-horizontal:hover .vjs-menu-content,
|
||||
.vjs-volume-menu-button-horizontal:focus .vjs-menu-content,
|
||||
.vjs-volume-menu-button-horizontal .vjs-slider-active .vjs-menu-content,
|
||||
.vjs-volume-menu-button-horizontal .vjs-lock-showing .vjs-menu-content {
|
||||
height: 2.9em;
|
||||
width: 8em;
|
||||
}
|
||||
|
||||
.vjs-volume-menu-button.vjs-menu-button-inline .vjs-menu-content {
|
||||
// An inline volume should never have a menu background color.
|
||||
// This protects it from external changes to background colors.
|
||||
/* An inline volume should never have a menu background color.
|
||||
This protects it from external changes to background colors. */
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
width: auto;
|
||||
|
||||
position: absolute;
|
||||
left: 4em;
|
||||
left: 2.2222222em;
|
||||
top: 0;
|
||||
|
||||
padding: 0;
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 10em;
|
||||
left: -3em; // (Width of vjs-menu - width of button) / 2
|
||||
left: -3em; /* (Width of vjs-menu - width of button) / 2 */
|
||||
height: 0em;
|
||||
margin-bottom: 1.5em;
|
||||
border-top-color: rgba($primary-background-color, $primary-background-transparency); // Same as ul background
|
||||
border-top-color: rgba($primary-background-color, $primary-background-transparency); /* Same as ul background */
|
||||
}
|
||||
|
||||
// Button Pop-up Menu
|
||||
.vjs-menu-button-popup .vjs-menu .vjs-menu-content {
|
||||
/* Button Pop-up Menu */
|
||||
.vjs-menu-button-popup .vjs-menu ul {
|
||||
@include background-color-with-alpha($primary-background-color, $primary-background-transparency);
|
||||
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
bottom: 1.5em; // Same bottom as vjs-menu border-top
|
||||
bottom: 1.5em; /* Same bottom as vjs-menu border-top */
|
||||
max-height: 15em;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
// prevent menus from opening while scrubbing (FF, IE)
|
||||
/* prevent menus from opening while scrubbing (FF, IE) */
|
||||
.vjs-scrubbing .vjs-menu-button:hover .vjs-menu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
@import "private-variables";
|
||||
@import "utilities";
|
||||
|
||||
@if $icon-codepoints {
|
||||
@import "../../node_modules/videojs-font/scss/icons-codepoints";
|
||||
} @else {
|
||||
@import "../../node_modules/videojs-font/scss/icons";
|
||||
}
|
||||
@import "../../node_modules/videojs-font/scss/icons";
|
||||
|
||||
@import "components/layout";
|
||||
@import "components/big-play";
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
$icon-codepoints: true;
|
||||
|
||||
@import "video-js";
|
||||
+73
-29
@@ -1,11 +1,10 @@
|
||||
/**
|
||||
* @file button.js
|
||||
*/
|
||||
import ClickableComponent from './clickable-component.js';
|
||||
import Component from './component';
|
||||
import * as Dom from './utils/dom.js';
|
||||
import * as Events from './utils/events.js';
|
||||
import * as Fn from './utils/fn.js';
|
||||
import log from './utils/log.js';
|
||||
import document from 'global/document';
|
||||
import assign from 'object.assign';
|
||||
|
||||
@@ -14,77 +13,122 @@ import assign from 'object.assign';
|
||||
*
|
||||
* @param {Object} player Main Player
|
||||
* @param {Object=} options Object of option names and values
|
||||
* @extends ClickableComponent
|
||||
* @extends Component
|
||||
* @class Button
|
||||
*/
|
||||
class Button extends ClickableComponent {
|
||||
class Button extends Component {
|
||||
|
||||
constructor(player, options) {
|
||||
super(player, options);
|
||||
|
||||
this.emitTapEvents();
|
||||
|
||||
this.on('tap', this.handleClick);
|
||||
this.on('click', this.handleClick);
|
||||
this.on('focus', this.handleFocus);
|
||||
this.on('blur', this.handleBlur);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the component's DOM element
|
||||
*
|
||||
* @param {String=} type Element's node type. e.g. 'div'
|
||||
* @param {Object=} props An object of properties that should be set on the element
|
||||
* @param {Object=} attributes An object of attributes that should be set on the element
|
||||
* @param {Object=} props An object of element attributes that should be set on the element Tag name
|
||||
* @return {Element}
|
||||
* @method createEl
|
||||
*/
|
||||
createEl(tag='button', props={}, attributes={}) {
|
||||
props = assign({
|
||||
className: this.buildCSSClass()
|
||||
className: this.buildCSSClass(),
|
||||
tabIndex: 0
|
||||
}, props);
|
||||
|
||||
if (tag !== 'button') {
|
||||
log.warn(`Creating a Button with an HTML element of ${tag} is deprecated; use ClickableComponent instead.`);
|
||||
}
|
||||
|
||||
// Add attributes for button element
|
||||
// Add standard Aria info
|
||||
attributes = assign({
|
||||
role: 'button',
|
||||
type: 'button', // Necessary since the default button type is "submit"
|
||||
'aria-live': 'polite' // let the screen reader user know that the text of the button may change
|
||||
}, attributes);
|
||||
|
||||
let el = Component.prototype.createEl.call(this, tag, props, attributes);
|
||||
let el = super.createEl(tag, props, attributes);
|
||||
|
||||
this.createControlTextEl(el);
|
||||
this.controlTextEl_ = Dom.createEl('span', {
|
||||
className: 'vjs-control-text'
|
||||
});
|
||||
|
||||
el.appendChild(this.controlTextEl_);
|
||||
|
||||
this.controlText(this.controlText_);
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a child component inside this button
|
||||
* Controls text - both request and localize
|
||||
*
|
||||
* @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 {Component} The child component (created by this process if a string was used)
|
||||
* @deprecated
|
||||
* @method addChild
|
||||
* @param {String} text Text for button
|
||||
* @return {String}
|
||||
* @method controlText
|
||||
*/
|
||||
addChild(child, options={}) {
|
||||
let className = this.constructor.name;
|
||||
log.warn(`Adding an actionable (user controllable) child to a Button (${className}) is not supported; use a ClickableComponent instead.`);
|
||||
controlText(text) {
|
||||
if (!text) return this.controlText_ || 'Need Text';
|
||||
|
||||
// Avoid the error message generated by ClickableComponent's addChild method
|
||||
return Component.prototype.addChild.call(this, child, options);
|
||||
this.controlText_ = text;
|
||||
this.controlTextEl_.innerHTML = this.localize(this.controlText_);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle KeyPress (document level) - Extend with specific functionality for button
|
||||
* Allows sub components to stack CSS class names
|
||||
*
|
||||
* @return {String}
|
||||
* @method buildCSSClass
|
||||
*/
|
||||
buildCSSClass() {
|
||||
return `vjs-control vjs-button ${super.buildCSSClass()}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Click - Override with specific functionality for button
|
||||
*
|
||||
* @method handleClick
|
||||
*/
|
||||
handleClick() {}
|
||||
|
||||
/**
|
||||
* Handle Focus - Add keyboard functionality to element
|
||||
*
|
||||
* @method handleFocus
|
||||
*/
|
||||
handleFocus() {
|
||||
Events.on(document, 'keydown', Fn.bind(this, this.handleKeyPress));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle KeyPress (document level) - Trigger click when keys are pressed
|
||||
*
|
||||
* @method handleKeyPress
|
||||
*/
|
||||
handleKeyPress(event) {
|
||||
// Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button.
|
||||
// Check for space bar (32) or enter (13) keys
|
||||
if (event.which === 32 || event.which === 13) {
|
||||
} else {
|
||||
super.handleKeyPress(event); // Pass keypress handling up for unsupported keys
|
||||
event.preventDefault();
|
||||
this.handleClick(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Blur - Remove keyboard triggers
|
||||
*
|
||||
* @method handleBlur
|
||||
*/
|
||||
handleBlur() {
|
||||
Events.off(document, 'keydown', Fn.bind(this, this.handleKeyPress));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Component.registerComponent('Button', Button);
|
||||
export default Button;
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
/**
|
||||
* @file button.js
|
||||
*/
|
||||
import Component from './component';
|
||||
import * as Dom from './utils/dom.js';
|
||||
import * as Events from './utils/events.js';
|
||||
import * as Fn from './utils/fn.js';
|
||||
import log from './utils/log.js';
|
||||
import document from 'global/document';
|
||||
import assign from 'object.assign';
|
||||
|
||||
/**
|
||||
* Clickable Component which is clickable or keyboard actionable, but is not a native HTML button
|
||||
*
|
||||
* @param {Object} player Main Player
|
||||
* @param {Object=} options Object of option names and values
|
||||
* @extends Component
|
||||
* @class ClickableComponent
|
||||
*/
|
||||
class ClickableComponent extends Component {
|
||||
|
||||
constructor(player, options) {
|
||||
super(player, options);
|
||||
|
||||
this.emitTapEvents();
|
||||
|
||||
this.on('tap', this.handleClick);
|
||||
this.on('click', this.handleClick);
|
||||
this.on('focus', this.handleFocus);
|
||||
this.on('blur', this.handleBlur);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the component's DOM element
|
||||
*
|
||||
* @param {String=} type Element's node type. e.g. 'div'
|
||||
* @param {Object=} props An object of properties that should be set on the element
|
||||
* @param {Object=} attributes An object of attributes that should be set on the element
|
||||
* @return {Element}
|
||||
* @method createEl
|
||||
*/
|
||||
createEl(tag='div', props={}, attributes={}) {
|
||||
props = assign({
|
||||
className: this.buildCSSClass(),
|
||||
tabIndex: 0
|
||||
}, props);
|
||||
|
||||
if (tag === 'button') {
|
||||
log.error(`Creating a ClickableComponent with an HTML element of ${tag} is not supported; use a Button instead.`);
|
||||
}
|
||||
|
||||
// Add ARIA attributes for clickable element which is not a native HTML button
|
||||
attributes = assign({
|
||||
role: 'button',
|
||||
'aria-live': 'polite' // let the screen reader user know that the text of the element may change
|
||||
}, attributes);
|
||||
|
||||
let el = super.createEl(tag, props, attributes);
|
||||
|
||||
this.createControlTextEl(el);
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
/**
|
||||
* create control text
|
||||
*
|
||||
* @param {Element} el Parent element for the control text
|
||||
* @return {Element}
|
||||
* @method controlText
|
||||
*/
|
||||
createControlTextEl(el) {
|
||||
this.controlTextEl_ = Dom.createEl('span', {
|
||||
className: 'vjs-control-text'
|
||||
});
|
||||
|
||||
if (el) {
|
||||
el.appendChild(this.controlTextEl_);
|
||||
}
|
||||
|
||||
this.controlText(this.controlText_);
|
||||
|
||||
return this.controlTextEl_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls text - both request and localize
|
||||
*
|
||||
* @param {String} text Text for element
|
||||
* @return {String}
|
||||
* @method controlText
|
||||
*/
|
||||
controlText(text) {
|
||||
if (!text) return this.controlText_ || 'Need Text';
|
||||
|
||||
this.controlText_ = text;
|
||||
this.controlTextEl_.innerHTML = this.localize(this.controlText_);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows sub components to stack CSS class names
|
||||
*
|
||||
* @return {String}
|
||||
* @method buildCSSClass
|
||||
*/
|
||||
buildCSSClass() {
|
||||
return `vjs-control vjs-button ${super.buildCSSClass()}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a child component inside this clickable-component
|
||||
*
|
||||
* @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 {Component} The child component (created by this process if a string was used)
|
||||
* @method addChild
|
||||
*/
|
||||
addChild(child, options={}) {
|
||||
// TODO: Fix adding an actionable child to a ClickableComponent; currently
|
||||
// it will cause issues with assistive technology (e.g. screen readers)
|
||||
// which support ARIA, since an element with role="button" cannot have
|
||||
// actionable child elements.
|
||||
|
||||
//let className = this.constructor.name;
|
||||
//log.warn(`Adding a child to a ClickableComponent (${className}) can cause issues with assistive technology which supports ARIA, since an element with role="button" cannot have actionable child elements.`);
|
||||
|
||||
return super.addChild(child, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Click - Override with specific functionality for component
|
||||
*
|
||||
* @method handleClick
|
||||
*/
|
||||
handleClick() {}
|
||||
|
||||
/**
|
||||
* Handle Focus - Add keyboard functionality to element
|
||||
*
|
||||
* @method handleFocus
|
||||
*/
|
||||
handleFocus() {
|
||||
Events.on(document, 'keydown', Fn.bind(this, this.handleKeyPress));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle KeyPress (document level) - Trigger click when Space or Enter key is pressed
|
||||
*
|
||||
* @method handleKeyPress
|
||||
*/
|
||||
handleKeyPress(event) {
|
||||
// Support Space (32) or Enter (13) key operation to fire a click event
|
||||
if (event.which === 32 || event.which === 13) {
|
||||
event.preventDefault();
|
||||
this.handleClick(event);
|
||||
} else if (super.handleKeyPress) {
|
||||
super.handleKeyPress(event); // Pass keypress handling up for unsupported keys
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Blur - Remove keyboard triggers
|
||||
*
|
||||
* @method handleBlur
|
||||
*/
|
||||
handleBlur() {
|
||||
Events.off(document, 'keydown', Fn.bind(this, this.handleKeyPress));
|
||||
}
|
||||
}
|
||||
|
||||
Component.registerComponent('ClickableComponent', ClickableComponent);
|
||||
export default ClickableComponent;
|
||||
@@ -38,8 +38,6 @@ class ControlBar extends Component {
|
||||
createEl() {
|
||||
return super.createEl('div', {
|
||||
className: 'vjs-control-bar'
|
||||
}, {
|
||||
'role': 'group' // The control bar is a group, so it can contain menuitems
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,8 +76,9 @@ class MuteToggle extends Button {
|
||||
// This causes unnecessary and confusing information for screen reader users.
|
||||
// This check is needed because this function gets called every time the volume level is changed.
|
||||
let toMute = this.player_.muted() ? 'Unmute' : 'Mute';
|
||||
if (this.controlText() !== toMute) {
|
||||
this.controlText(toMute);
|
||||
let localizedMute = this.localize(toMute);
|
||||
if (this.controlText() !== localizedMute) {
|
||||
this.controlText(localizedMute);
|
||||
}
|
||||
|
||||
/* TODO improve muted icon classes */
|
||||
|
||||
@@ -19,17 +19,12 @@ import Component from '../../component.js';
|
||||
'kind': options['kind'],
|
||||
'player': player,
|
||||
'label': options['kind'] + ' settings',
|
||||
'selectable': false,
|
||||
'default': false,
|
||||
mode: 'disabled'
|
||||
};
|
||||
|
||||
// CaptionSettingsMenuItem has no concept of 'selected'
|
||||
options['selectable'] = false;
|
||||
|
||||
super(player, options);
|
||||
this.addClass('vjs-texttrack-settings');
|
||||
this.controlText(', opens ' + options['kind'] + ' settings dialog');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,7 +34,6 @@ import Component from '../../component.js';
|
||||
*/
|
||||
handleClick() {
|
||||
this.player().getChild('textTrackSettings').show();
|
||||
this.player().getChild('textTrackSettings').el_.focus();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -77,13 +77,21 @@ class ChaptersButton extends TextTrackButton {
|
||||
let chaptersTrack;
|
||||
let items = this.items = [];
|
||||
|
||||
for (let i = 0, length = tracks.length; i < length; i++) {
|
||||
for (let i = 0, l = tracks.length; i < l; i++) {
|
||||
let track = tracks[i];
|
||||
|
||||
if (track['kind'] === this.kind_) {
|
||||
chaptersTrack = track;
|
||||
|
||||
break;
|
||||
if (!track.cues) {
|
||||
track['mode'] = 'hidden';
|
||||
/* jshint loopfunc:true */
|
||||
// TODO see if we can figure out a better way of doing this https://github.com/videojs/video.js/issues/1864
|
||||
window.setTimeout(Fn.bind(this, function() {
|
||||
this.createMenu();
|
||||
}), 100);
|
||||
/* jshint loopfunc:false */
|
||||
} else {
|
||||
chaptersTrack = track;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,17 +105,7 @@ class ChaptersButton extends TextTrackButton {
|
||||
}));
|
||||
}
|
||||
|
||||
if (chaptersTrack && chaptersTrack.cues == null) {
|
||||
chaptersTrack['mode'] = 'hidden';
|
||||
|
||||
let remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(chaptersTrack);
|
||||
|
||||
if (remoteTextTrackEl) {
|
||||
remoteTextTrackEl.addEventListener('load', (event) => this.update());
|
||||
}
|
||||
}
|
||||
|
||||
if (chaptersTrack && chaptersTrack.cues && chaptersTrack.cues.length > 0) {
|
||||
if (chaptersTrack) {
|
||||
let cues = chaptersTrack['cues'], cue;
|
||||
|
||||
for (let i = 0, l = cues.length; i < l; i++) {
|
||||
@@ -122,7 +120,6 @@ class ChaptersButton extends TextTrackButton {
|
||||
|
||||
menu.addChild(mi);
|
||||
}
|
||||
|
||||
this.addChild(menu);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,6 @@ class OffTextTrackMenuItem extends TextTrackMenuItem {
|
||||
'mode': 'disabled'
|
||||
};
|
||||
|
||||
// MenuItem is selectable
|
||||
options['selectable'] = true;
|
||||
|
||||
super(player, options);
|
||||
this.selected(true);
|
||||
}
|
||||
|
||||
@@ -57,8 +57,6 @@ class TextTrackButton extends MenuButton {
|
||||
// only add tracks that are of the appropriate kind and have a label
|
||||
if (track['kind'] === this.kind_) {
|
||||
items.push(new TextTrackMenuItem(this.player_, {
|
||||
// MenuItem is selectable
|
||||
'selectable': true,
|
||||
'track': track
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ class TextTrackMenuItem extends MenuItem {
|
||||
// Modify options for parent MenuItem class's init.
|
||||
options['label'] = track['label'] || track['language'] || 'Unknown';
|
||||
options['selected'] = track['default'] || track['mode'] === 'showing';
|
||||
|
||||
super(player, options);
|
||||
|
||||
this.track = track;
|
||||
|
||||
@@ -44,14 +44,11 @@ class VolumeBar extends Slider {
|
||||
* @method handleMouseMove
|
||||
*/
|
||||
handleMouseMove(event) {
|
||||
this.checkMuted();
|
||||
this.player_.volume(this.calculateDistance(event));
|
||||
}
|
||||
|
||||
checkMuted() {
|
||||
if (this.player_.muted()) {
|
||||
this.player_.muted(false);
|
||||
}
|
||||
|
||||
this.player_.volume(this.calculateDistance(event));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +71,6 @@ class VolumeBar extends Slider {
|
||||
* @method stepForward
|
||||
*/
|
||||
stepForward() {
|
||||
this.checkMuted();
|
||||
this.player_.volume(this.player_.volume() + 0.1);
|
||||
}
|
||||
|
||||
@@ -84,7 +80,6 @@ class VolumeBar extends Slider {
|
||||
* @method stepBack
|
||||
*/
|
||||
stepBack() {
|
||||
this.checkMuted();
|
||||
this.player_.volume(this.player_.volume() - 0.1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
/**
|
||||
* @file volume-menu-button.js
|
||||
*/
|
||||
import * as Fn from '../utils/fn.js';
|
||||
import Button from '../button.js';
|
||||
import Component from '../component.js';
|
||||
import Popup from '../popup/popup.js';
|
||||
import PopupButton from '../popup/popup-button.js';
|
||||
import Menu from '../menu/menu.js';
|
||||
import MenuButton from '../menu/menu-button.js';
|
||||
import MuteToggle from './mute-toggle.js';
|
||||
import VolumeBar from './volume-control/volume-bar.js';
|
||||
import document from 'global/document';
|
||||
|
||||
/**
|
||||
* Button for volume popup
|
||||
* Button for volume menu
|
||||
*
|
||||
* @param {Player|Object} player
|
||||
* @param {Object=} options
|
||||
* @extends PopupButton
|
||||
* @extends MenuButton
|
||||
* @class VolumeMenuButton
|
||||
*/
|
||||
class VolumeMenuButton extends PopupButton {
|
||||
class VolumeMenuButton extends MenuButton {
|
||||
|
||||
constructor(player, options={}){
|
||||
// Default to inline
|
||||
@@ -66,14 +65,6 @@ class VolumeMenuButton extends PopupButton {
|
||||
this.on(this.volumeBar, ['sliderinactive', 'blur'], function(){
|
||||
this.removeClass('vjs-slider-active');
|
||||
});
|
||||
|
||||
this.on(this.volumeBar, ['focus'], function(){
|
||||
this.addClass('vjs-lock-showing');
|
||||
});
|
||||
|
||||
this.on(this.volumeBar, ['blur'], function(){
|
||||
this.removeClass('vjs-lock-showing');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,27 +87,24 @@ class VolumeMenuButton extends PopupButton {
|
||||
/**
|
||||
* Allow sub components to stack CSS class names
|
||||
*
|
||||
* @return {Popup} The volume popup button
|
||||
* @method createPopup
|
||||
* @return {Menu} The volume menu button
|
||||
* @method createMenu
|
||||
*/
|
||||
createPopup() {
|
||||
let popup = new Popup(this.player_, {
|
||||
createMenu() {
|
||||
let menu = new Menu(this.player_, {
|
||||
contentElType: 'div'
|
||||
});
|
||||
|
||||
let vb = new VolumeBar(this.player_, this.options_.volumeBar);
|
||||
|
||||
popup.addChild(vb);
|
||||
menu.addChild(vb);
|
||||
|
||||
this.volumeBar = vb;
|
||||
|
||||
this.attachVolumeBarEvents();
|
||||
|
||||
return popup;
|
||||
return menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle click on volume popup and calls super
|
||||
* Handle click on volume menu and calls super
|
||||
*
|
||||
* @method handleClick
|
||||
*/
|
||||
@@ -125,18 +113,6 @@ class VolumeMenuButton extends PopupButton {
|
||||
super.handleClick();
|
||||
}
|
||||
|
||||
attachVolumeBarEvents() {
|
||||
this.on(['mousedown', 'touchdown'], this.handleMouseDown);
|
||||
}
|
||||
|
||||
handleMouseDown(event) {
|
||||
this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
|
||||
this.on(document, ['mouseup', 'touchend'], this.handleMouseUp);
|
||||
}
|
||||
|
||||
handleMouseUp(event) {
|
||||
this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
|
||||
}
|
||||
}
|
||||
|
||||
VolumeMenuButton.prototype.volumeUpdate = MuteToggle.prototype.update;
|
||||
|
||||
@@ -52,7 +52,6 @@ class ErrorDisplay extends ModalDialog {
|
||||
|
||||
ErrorDisplay.prototype.options_ = mergeOptions(ModalDialog.prototype.options_, {
|
||||
fillAlways: true,
|
||||
temporary: false,
|
||||
uncloseable: true
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file menu-button.js
|
||||
*/
|
||||
import ClickableComponent from '../clickable-component.js';
|
||||
import Button from '../button.js';
|
||||
import Component from '../component.js';
|
||||
import Menu from './menu.js';
|
||||
import * as Dom from '../utils/dom.js';
|
||||
@@ -16,16 +16,16 @@ import toTitleCase from '../utils/to-title-case.js';
|
||||
* @extends Button
|
||||
* @class MenuButton
|
||||
*/
|
||||
class MenuButton extends ClickableComponent {
|
||||
class MenuButton extends Button {
|
||||
|
||||
constructor(player, options={}){
|
||||
super(player, options);
|
||||
|
||||
this.update();
|
||||
|
||||
this.on('keydown', this.handleKeyPress);
|
||||
this.el_.setAttribute('aria-haspopup', true);
|
||||
this.el_.setAttribute('role', 'menuitem');
|
||||
this.on('keydown', this.handleSubmenuKeyPress);
|
||||
this.el_.setAttribute('role', 'button');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,7 +50,6 @@ class MenuButton extends ClickableComponent {
|
||||
* @private
|
||||
*/
|
||||
this.buttonPressed_ = false;
|
||||
this.el_.setAttribute('aria-expanded', false);
|
||||
|
||||
if (this.items && this.items.length === 0) {
|
||||
this.hide();
|
||||
@@ -127,6 +126,27 @@ class MenuButton extends ClickableComponent {
|
||||
return `vjs-menu-button ${menuButtonClass} ${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.
|
||||
*
|
||||
* @method handleFocus
|
||||
*/
|
||||
handleFocus() {}
|
||||
|
||||
/**
|
||||
* Can't turn off list display that we turned
|
||||
* on with focus, because list would go away.
|
||||
*
|
||||
* @method handleBlur
|
||||
*/
|
||||
handleBlur() {}
|
||||
|
||||
/**
|
||||
* When you click the button it adds focus, which
|
||||
* will show the menu indefinitely.
|
||||
@@ -151,48 +171,25 @@ class MenuButton extends ClickableComponent {
|
||||
/**
|
||||
* Handle key press on menu
|
||||
*
|
||||
* @param {Object} event Key press event
|
||||
* @param {Object} Key press event
|
||||
* @method handleKeyPress
|
||||
*/
|
||||
handleKeyPress(event) {
|
||||
|
||||
// Escape (27) key or Tab (9) key unpress the 'button'
|
||||
if (event.which === 27 || event.which === 9) {
|
||||
if (this.buttonPressed_) {
|
||||
// Check for space bar (32) or enter (13) keys
|
||||
if (event.which === 32 || event.which === 13) {
|
||||
if (this.buttonPressed_){
|
||||
this.unpressButton();
|
||||
}
|
||||
// Don't preventDefault for Tab key - we still want to lose focus
|
||||
if (event.which !== 9) {
|
||||
event.preventDefault();
|
||||
}
|
||||
// Up (38) key or Down (40) key press the 'button'
|
||||
} else if (event.which === 38 || event.which === 40) {
|
||||
if (!this.buttonPressed_) {
|
||||
} else {
|
||||
this.pressButton();
|
||||
event.preventDefault();
|
||||
}
|
||||
} else {
|
||||
super.handleKeyPress(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle key press on submenu
|
||||
*
|
||||
* @param {Object} event Key press event
|
||||
* @method handleSubmenuKeyPress
|
||||
*/
|
||||
handleSubmenuKeyPress(event) {
|
||||
|
||||
// Escape (27) key or Tab (9) key unpress the 'button'
|
||||
if (event.which === 27 || event.which === 9){
|
||||
event.preventDefault();
|
||||
// Check for escape (27) key
|
||||
} else if (event.which === 27){
|
||||
if (this.buttonPressed_){
|
||||
this.unpressButton();
|
||||
}
|
||||
// Don't preventDefault for Tab key - we still want to lose focus
|
||||
if (event.which !== 9) {
|
||||
event.preventDefault();
|
||||
}
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,8 +201,10 @@ class MenuButton extends ClickableComponent {
|
||||
pressButton() {
|
||||
this.buttonPressed_ = true;
|
||||
this.menu.lockShowing();
|
||||
this.el_.setAttribute('aria-expanded', true);
|
||||
this.menu.focus(); // set the focus into the submenu
|
||||
this.el_.setAttribute('aria-pressed', true);
|
||||
if (this.items && this.items.length > 0) {
|
||||
this.items[0].el().focus(); // set the focus to the title of the submenu
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,8 +215,7 @@ class MenuButton extends ClickableComponent {
|
||||
unpressButton() {
|
||||
this.buttonPressed_ = false;
|
||||
this.menu.unlockShowing();
|
||||
this.el_.setAttribute('aria-expanded', false);
|
||||
this.el_.focus(); // Set focus back to this menu button
|
||||
this.el_.setAttribute('aria-pressed', false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-29
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file menu-item.js
|
||||
*/
|
||||
import ClickableComponent from '../clickable-component.js';
|
||||
import Button from '../button.js';
|
||||
import Component from '../component.js';
|
||||
import assign from 'object.assign';
|
||||
|
||||
@@ -13,22 +13,11 @@ import assign from 'object.assign';
|
||||
* @extends Button
|
||||
* @class MenuItem
|
||||
*/
|
||||
class MenuItem extends ClickableComponent {
|
||||
class MenuItem extends Button {
|
||||
|
||||
constructor(player, options) {
|
||||
super(player, options);
|
||||
|
||||
this.selectable = options['selectable'];
|
||||
|
||||
this.selected(options['selected']);
|
||||
|
||||
if (this.selectable) {
|
||||
// TODO: May need to be either menuitemcheckbox or menuitemradio,
|
||||
// and may need logical grouping of menu items.
|
||||
this.el_.setAttribute('role', 'menuitemcheckbox');
|
||||
} else {
|
||||
this.el_.setAttribute('role', 'menuitem');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,8 +31,7 @@ class MenuItem extends ClickableComponent {
|
||||
createEl(type, props, attrs) {
|
||||
return super.createEl('li', assign({
|
||||
className: 'vjs-menu-item',
|
||||
innerHTML: this.localize(this.options_['label']),
|
||||
tabIndex: -1
|
||||
innerHTML: this.localize(this.options_['label'])
|
||||
}, props), attrs);
|
||||
}
|
||||
|
||||
@@ -63,22 +51,15 @@ class MenuItem extends ClickableComponent {
|
||||
* @method selected
|
||||
*/
|
||||
selected(selected) {
|
||||
if (this.selectable) {
|
||||
if (selected) {
|
||||
this.addClass('vjs-selected');
|
||||
this.el_.setAttribute('aria-checked',true);
|
||||
// aria-checked isn't fully supported by browsers/screen readers,
|
||||
// so indicate selected state to screen reader in the control text.
|
||||
this.controlText(', selected');
|
||||
} else {
|
||||
this.removeClass('vjs-selected');
|
||||
this.el_.setAttribute('aria-checked',false);
|
||||
// Indicate un-selected state to screen reader
|
||||
// Note that a space clears out the selected state text
|
||||
this.controlText(' ');
|
||||
}
|
||||
if (selected) {
|
||||
this.addClass('vjs-selected');
|
||||
this.el_.setAttribute('aria-selected',true);
|
||||
} else {
|
||||
this.removeClass('vjs-selected');
|
||||
this.el_.setAttribute('aria-selected',false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Component.registerComponent('MenuItem', MenuItem);
|
||||
|
||||
@@ -15,14 +15,6 @@ import * as Events from '../utils/events.js';
|
||||
*/
|
||||
class Menu extends Component {
|
||||
|
||||
constructor (player, options) {
|
||||
super(player, options);
|
||||
|
||||
this.focusedChild_ = -1;
|
||||
|
||||
this.on('keydown', this.handleKeyPress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a menu item to the menu
|
||||
*
|
||||
@@ -33,7 +25,6 @@ class Menu extends Component {
|
||||
this.addChild(component);
|
||||
component.on('click', Fn.bind(this, function(){
|
||||
this.unlockShowing();
|
||||
//TODO: Need to set keyboard focus back to the menuButton
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -48,12 +39,10 @@ class Menu extends Component {
|
||||
this.contentEl_ = Dom.createEl(contentElType, {
|
||||
className: 'vjs-menu-content'
|
||||
});
|
||||
this.contentEl_.setAttribute('role', 'menu');
|
||||
var el = super.createEl('div', {
|
||||
append: this.contentEl_,
|
||||
className: 'vjs-menu'
|
||||
});
|
||||
el.setAttribute('role', 'presentation');
|
||||
el.appendChild(this.contentEl_);
|
||||
|
||||
// Prevent clicks from bubbling up. Needed for Menu Buttons,
|
||||
@@ -65,72 +54,6 @@ class Menu extends Component {
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle key press for menu
|
||||
*
|
||||
* @param {Object} event Event object
|
||||
* @method handleKeyPress
|
||||
*/
|
||||
handleKeyPress (event) {
|
||||
if (event.which === 37 || event.which === 40) { // Left and Down Arrows
|
||||
event.preventDefault();
|
||||
this.stepForward();
|
||||
} else if (event.which === 38 || event.which === 39) { // Up and Right Arrows
|
||||
event.preventDefault();
|
||||
this.stepBack();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move to next (lower) menu item for keyboard users
|
||||
*
|
||||
* @method stepForward
|
||||
*/
|
||||
stepForward () {
|
||||
let stepChild = 0;
|
||||
|
||||
if (this.focusedChild_ !== undefined) {
|
||||
stepChild = this.focusedChild_ + 1;
|
||||
}
|
||||
this.focus(stepChild);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move to previous (higher) menu item for keyboard users
|
||||
*
|
||||
* @method stepBack
|
||||
*/
|
||||
stepBack () {
|
||||
let stepChild = 0;
|
||||
|
||||
if (this.focusedChild_ !== undefined) {
|
||||
stepChild = this.focusedChild_ - 1;
|
||||
}
|
||||
this.focus(stepChild);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set focus on a menu item in the menu
|
||||
*
|
||||
* @param {Object|String} item Index of child item set focus on
|
||||
* @method focus
|
||||
*/
|
||||
focus (item = 0) {
|
||||
let children = this.children();
|
||||
|
||||
if (children.length > 0) {
|
||||
if (item < 0) {
|
||||
item = 0;
|
||||
} else if (item >= children.length) {
|
||||
item = children.length - 1;
|
||||
}
|
||||
|
||||
this.focusedChild_ = item;
|
||||
|
||||
children[item].el_.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.registerComponent('Menu', Menu);
|
||||
|
||||
+34
-115
@@ -224,7 +224,7 @@ class Player extends Component {
|
||||
// prevent dispose from being called twice
|
||||
this.off('dispose');
|
||||
|
||||
if (this.styleEl_ && this.styleEl_.parentNode) {
|
||||
if (this.styleEl_) {
|
||||
this.styleEl_.parentNode.removeChild(this.styleEl_);
|
||||
}
|
||||
|
||||
@@ -269,7 +269,6 @@ class Player extends Component {
|
||||
// Update tag id/class for use as HTML5 playback tech
|
||||
// Might think we should do this after embedding in container so .vjs-tech class
|
||||
// doesn't flash 100% width/height, but class only applies with .video-js parent
|
||||
tag.playerId = tag.id;
|
||||
tag.id += '_html5_api';
|
||||
tag.className = 'vjs-tech';
|
||||
|
||||
@@ -613,30 +612,6 @@ class Player extends Component {
|
||||
this.tech_ = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the current tech.
|
||||
* It will only return a reference to the tech if given an object with the
|
||||
* `IWillNotUseThisInPlugins` property on it. This is try and prevent misuse
|
||||
* of techs by plugins.
|
||||
*
|
||||
* @param {Object}
|
||||
* @return {Object} The Tech
|
||||
* @method tech
|
||||
*/
|
||||
tech(safety) {
|
||||
if (safety && safety.IWillNotUseThisInPlugins) {
|
||||
return this.tech_;
|
||||
}
|
||||
let errorText = `
|
||||
Please make sure that you are not using this inside of a plugin.
|
||||
To disable this alert and error, please pass in an object with
|
||||
\`IWillNotUseThisInPlugins\` to the \`tech\` method. See
|
||||
https://github.com/videojs/video.js/issues/2617 for more info.
|
||||
`;
|
||||
window.alert(errorText);
|
||||
throw new Error(errorText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up click and touch listeners for the playback element
|
||||
*
|
||||
@@ -721,7 +696,7 @@ class Player extends Component {
|
||||
// In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
|
||||
// In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
|
||||
// This fixes both issues. Need to wait for API, so it updates displays correctly
|
||||
if (this.src() && this.tag && this.options_.autoplay && this.paused()) {
|
||||
if (this.tag && this.options_.autoplay && this.paused()) {
|
||||
delete this.tag.poster; // Chrome Fix. Fixed in Chrome v16.
|
||||
this.play();
|
||||
}
|
||||
@@ -1718,75 +1693,43 @@ class Player extends Component {
|
||||
}
|
||||
|
||||
/**
|
||||
* Select source based on tech-order or source-order
|
||||
* Uses source-order selection if `options.sourceOrder` is truthy. Otherwise,
|
||||
* defaults to tech-order selection
|
||||
* Select source based on tech order
|
||||
*
|
||||
* @param {Array} sources The sources for a media asset
|
||||
* @return {Object|Boolean} Object of source and tech order, otherwise false
|
||||
* @method selectSource
|
||||
*/
|
||||
selectSource(sources) {
|
||||
// Get only the techs specified in `techOrder` that exist and are supported by the
|
||||
// current platform
|
||||
let techs =
|
||||
this.options_.techOrder
|
||||
.map(toTitleCase)
|
||||
.map((techName) => {
|
||||
// `Component.getComponent(...)` is for support of old behavior of techs
|
||||
// being registered as components.
|
||||
// Remove once that deprecated behavior is removed.
|
||||
return [techName, Tech.getTech(techName) || Component.getComponent(techName)];
|
||||
})
|
||||
.filter(([techName, tech]) => {
|
||||
// Check if the current tech is defined before continuing
|
||||
if (tech) {
|
||||
// Check if the browser supports this technology
|
||||
return tech.isSupported();
|
||||
}
|
||||
|
||||
log.error(`The "${techName}" tech is undefined. Skipped browser support check for that tech.`);
|
||||
return false;
|
||||
});
|
||||
|
||||
// Iterate over each `innerArray` element once per `outerArray` element and execute
|
||||
// `tester` with both. If `tester` returns a non-falsy value, exit early and return
|
||||
// that value.
|
||||
let findFirstPassingTechSourcePair = function (outerArray, innerArray, tester) {
|
||||
let found;
|
||||
|
||||
outerArray.some((outerChoice) => {
|
||||
return innerArray.some((innerChoice) => {
|
||||
found = tester(outerChoice, innerChoice);
|
||||
|
||||
if (found) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return found;
|
||||
};
|
||||
|
||||
let foundSourceAndTech;
|
||||
let flip = (fn) => (a, b) => fn(b, a);
|
||||
let finder = ([techName, tech], source) => {
|
||||
if (tech.canPlaySource(source)) {
|
||||
return {source: source, tech: techName};
|
||||
// Loop through each playback technology in the options order
|
||||
for (var i=0,j=this.options_.techOrder;i<j.length;i++) {
|
||||
let techName = toTitleCase(j[i]);
|
||||
let tech = Tech.getTech(techName);
|
||||
// Support old behavior of techs being registered as components.
|
||||
// Remove once that deprecated behavior is removed.
|
||||
if (!tech) {
|
||||
tech = Component.getComponent(techName);
|
||||
}
|
||||
// Check if the current tech is defined before continuing
|
||||
if (!tech) {
|
||||
log.error(`The "${techName}" tech is undefined. Skipped browser support check for that tech.`);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
// Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources
|
||||
// to select from them based on their priority.
|
||||
if (this.options_.sourceOrder) {
|
||||
// Source-first ordering
|
||||
foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder));
|
||||
} else {
|
||||
// Tech-first ordering
|
||||
foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder);
|
||||
// Check if the browser supports this technology
|
||||
if (tech.isSupported()) {
|
||||
// Loop through each source object
|
||||
for (var a=0,b=sources;a<b.length;a++) {
|
||||
var source = b[a];
|
||||
|
||||
// Check if source can be played with this technology
|
||||
if (tech.canPlaySource(source)) {
|
||||
return { source: source, tech: techName };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return foundSourceAndTech || false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1924,19 +1867,6 @@ class Player extends Component {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the player. Loads the first tech in the techOrder,
|
||||
* and calls `reset` on the tech`.
|
||||
*
|
||||
* @return {Player} Returns the player
|
||||
* @method reset
|
||||
*/
|
||||
reset() {
|
||||
this.loadTech_(toTitleCase(this.options_.techOrder[0]), null);
|
||||
this.techCall_('reset');
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4
|
||||
* Can be used in conjuction with `currentType` to assist in rebuilding the current source object.
|
||||
@@ -1980,7 +1910,7 @@ class Player extends Component {
|
||||
/**
|
||||
* Get or set the autoplay attribute.
|
||||
*
|
||||
* @param {Boolean} value Boolean to determine if video should autoplay
|
||||
* @param {Boolean} value Boolean to determine if preload should be used
|
||||
* @return {String} The autoplay attribute value when getting
|
||||
* @return {Player} Returns the player when setting
|
||||
* @method autoplay
|
||||
@@ -1997,7 +1927,7 @@ class Player extends Component {
|
||||
/**
|
||||
* Get or set the loop attribute on the video element.
|
||||
*
|
||||
* @param {Boolean} value Boolean to determine if video should loop
|
||||
* @param {Boolean} value Boolean to determine if preload should be used
|
||||
* @return {String} The loop attribute value when getting
|
||||
* @return {Player} Returns the player when setting
|
||||
* @method loop
|
||||
@@ -2177,7 +2107,6 @@ class Player extends Component {
|
||||
if (err === null) {
|
||||
this.error_ = err;
|
||||
this.removeClass('vjs-error');
|
||||
this.errorDisplay.close();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -2188,6 +2117,9 @@ class Player extends Component {
|
||||
this.error_ = new MediaError(err);
|
||||
}
|
||||
|
||||
// fire an error event on the player
|
||||
this.trigger('error');
|
||||
|
||||
// add the vjs-error classname to the player
|
||||
this.addClass('vjs-error');
|
||||
|
||||
@@ -2195,9 +2127,6 @@ class Player extends Component {
|
||||
// ie8 just logs "[object object]" if you just log the error object
|
||||
log.error(`(CODE:${this.error_.code} ${MediaError.errorTypes[this.error_.code]})`, this.error_.message, this.error_);
|
||||
|
||||
// fire an error event on the player
|
||||
this.trigger('error');
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -2493,16 +2422,6 @@ class Player extends Component {
|
||||
return this.tech_ && this.tech_['remoteTextTracks']();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of remote html track elements
|
||||
*
|
||||
* @return {HTMLTrackElement[]}
|
||||
* @method remoteTextTrackEls
|
||||
*/
|
||||
remoteTextTrackEls() {
|
||||
return this.tech_ && this.tech_['remoteTextTrackEls']();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a text track
|
||||
* In addition to the W3C settings we allow adding additional info through options.
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/**
|
||||
* @file popup-button.js
|
||||
*/
|
||||
import ClickableComponent from '../clickable-component.js';
|
||||
import Component from '../component.js';
|
||||
import Popup from './popup.js';
|
||||
import * as Dom from '../utils/dom.js';
|
||||
import * as Fn from '../utils/fn.js';
|
||||
import toTitleCase from '../utils/to-title-case.js';
|
||||
|
||||
/**
|
||||
* A button class with a popup control
|
||||
*
|
||||
* @param {Player|Object} player
|
||||
* @param {Object=} options
|
||||
* @extends ClickableComponent
|
||||
* @class PopupButton
|
||||
*/
|
||||
class PopupButton extends ClickableComponent {
|
||||
|
||||
constructor(player, options={}){
|
||||
super(player, options);
|
||||
|
||||
this.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update popup
|
||||
*
|
||||
* @method update
|
||||
*/
|
||||
update() {
|
||||
let popup = this.createPopup();
|
||||
|
||||
if (this.popup) {
|
||||
this.removeChild(this.popup);
|
||||
}
|
||||
|
||||
this.popup = popup;
|
||||
this.addChild(popup);
|
||||
|
||||
if (this.items && this.items.length === 0) {
|
||||
this.hide();
|
||||
} else if (this.items && this.items.length > 1) {
|
||||
this.show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create popup - Override with specific functionality for component
|
||||
*
|
||||
* @return {Popup} The constructed popup
|
||||
* @method createPopup
|
||||
*/
|
||||
createPopup() {}
|
||||
|
||||
/**
|
||||
* Create the component's DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* @method createEl
|
||||
*/
|
||||
createEl() {
|
||||
return super.createEl('div', {
|
||||
className: this.buildCSSClass()
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow sub components to stack CSS class names
|
||||
*
|
||||
* @return {String} The constructed class name
|
||||
* @method buildCSSClass
|
||||
*/
|
||||
buildCSSClass() {
|
||||
var menuButtonClass = 'vjs-menu-button';
|
||||
|
||||
// If the inline option is passed, we want to use different styles altogether.
|
||||
if (this.options_.inline === true) {
|
||||
menuButtonClass += '-inline';
|
||||
} else {
|
||||
menuButtonClass += '-popup';
|
||||
}
|
||||
|
||||
return `vjs-menu-button ${menuButtonClass} ${super.buildCSSClass()}`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Component.registerComponent('PopupButton', PopupButton);
|
||||
export default PopupButton;
|
||||
@@ -1,59 +0,0 @@
|
||||
/**
|
||||
* @file popup.js
|
||||
*/
|
||||
import Component from '../component.js';
|
||||
import * as Dom from '../utils/dom.js';
|
||||
import * as Fn from '../utils/fn.js';
|
||||
import * as Events from '../utils/events.js';
|
||||
|
||||
/**
|
||||
* The Popup component is used to build pop up controls.
|
||||
*
|
||||
* @extends Component
|
||||
* @class Popup
|
||||
*/
|
||||
class Popup extends Component {
|
||||
|
||||
/**
|
||||
* Add a popup item to the popup
|
||||
*
|
||||
* @param {Object|String} component Component or component type to add
|
||||
* @method addItem
|
||||
*/
|
||||
addItem(component) {
|
||||
this.addChild(component);
|
||||
component.on('click', Fn.bind(this, function(){
|
||||
this.unlockShowing();
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the component's DOM element
|
||||
*
|
||||
* @return {Element}
|
||||
* @method createEl
|
||||
*/
|
||||
createEl() {
|
||||
let contentElType = this.options_.contentElType || 'ul';
|
||||
this.contentEl_ = Dom.createEl(contentElType, {
|
||||
className: 'vjs-menu-content'
|
||||
});
|
||||
var el = super.createEl('div', {
|
||||
append: this.contentEl_,
|
||||
className: 'vjs-menu'
|
||||
});
|
||||
el.appendChild(this.contentEl_);
|
||||
|
||||
// Prevent clicks from bubbling up. Needed for Popup Buttons,
|
||||
// where a click on the parent is significant
|
||||
Events.on(el, 'click', function(event){
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
});
|
||||
|
||||
return el;
|
||||
}
|
||||
}
|
||||
|
||||
Component.registerComponent('Popup', Popup);
|
||||
export default Popup;
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file poster-image.js
|
||||
*/
|
||||
import ClickableComponent from './clickable-component.js';
|
||||
import Button from './button.js';
|
||||
import Component from './component.js';
|
||||
import * as Fn from './utils/fn.js';
|
||||
import * as Dom from './utils/dom.js';
|
||||
@@ -15,7 +15,7 @@ import * as browser from './utils/browser.js';
|
||||
* @extends Button
|
||||
* @class PosterImage
|
||||
*/
|
||||
class PosterImage extends ClickableComponent {
|
||||
class PosterImage extends Button {
|
||||
|
||||
constructor(player, options){
|
||||
super(player, options);
|
||||
|
||||
+19
-60
@@ -49,7 +49,6 @@ class Html5 extends Tech {
|
||||
while (nodesLength--) {
|
||||
let node = nodes[nodesLength];
|
||||
let nodeName = node.nodeName.toLowerCase();
|
||||
|
||||
if (nodeName === 'track') {
|
||||
if (!this.featuresNativeTextTracks) {
|
||||
// Empty video tag tracks so the built-in player doesn't use them also.
|
||||
@@ -58,8 +57,6 @@ class Html5 extends Tech {
|
||||
// captions and subtitles. videoElement.textTracks
|
||||
removeNodes.push(node);
|
||||
} else {
|
||||
// store HTMLTrackElement and TextTrack to remote list
|
||||
this.remoteTextTrackEls().addTrackElement_(node);
|
||||
this.remoteTextTracks().addTrack_(node.track);
|
||||
}
|
||||
}
|
||||
@@ -489,15 +486,6 @@ class Html5 extends Tech {
|
||||
this.el_.load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the tech. Removes all sources and calls `load`.
|
||||
*
|
||||
* @method reset
|
||||
*/
|
||||
reset() {
|
||||
Html5.resetMediaElement(this.el_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current source
|
||||
*
|
||||
@@ -734,11 +722,11 @@ class Html5 extends Tech {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a remote text track object and returns a html track element
|
||||
* Creates and returns a remote text track object
|
||||
*
|
||||
* @param {Object} options The object should contain values for
|
||||
* kind, language, label and src (location of the WebVTT file)
|
||||
* @return {HTMLTrackElement}
|
||||
* @return {TextTrackObject}
|
||||
* @method addRemoteTextTrack
|
||||
*/
|
||||
addRemoteTextTrack(options={}) {
|
||||
@@ -746,34 +734,32 @@ class Html5 extends Tech {
|
||||
return super.addRemoteTextTrack(options);
|
||||
}
|
||||
|
||||
let htmlTrackElement = document.createElement('track');
|
||||
var track = document.createElement('track');
|
||||
|
||||
if (options.kind) {
|
||||
htmlTrackElement.kind = options.kind;
|
||||
if (options['kind']) {
|
||||
track['kind'] = options['kind'];
|
||||
}
|
||||
if (options.label) {
|
||||
htmlTrackElement.label = options.label;
|
||||
if (options['label']) {
|
||||
track['label'] = options['label'];
|
||||
}
|
||||
if (options.language || options.srclang) {
|
||||
htmlTrackElement.srclang = options.language || options.srclang;
|
||||
if (options['language'] || options['srclang']) {
|
||||
track['srclang'] = options['language'] || options['srclang'];
|
||||
}
|
||||
if (options.default) {
|
||||
htmlTrackElement.default = options.default;
|
||||
if (options['default']) {
|
||||
track['default'] = options['default'];
|
||||
}
|
||||
if (options.id) {
|
||||
htmlTrackElement.id = options.id;
|
||||
if (options['id']) {
|
||||
track['id'] = options['id'];
|
||||
}
|
||||
if (options.src) {
|
||||
htmlTrackElement.src = options.src;
|
||||
if (options['src']) {
|
||||
track['src'] = options['src'];
|
||||
}
|
||||
|
||||
this.el().appendChild(htmlTrackElement);
|
||||
this.el().appendChild(track);
|
||||
|
||||
// store HTMLTrackElement and TextTrack to remote list
|
||||
this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
|
||||
this.remoteTextTracks().addTrack_(htmlTrackElement.track);
|
||||
this.remoteTextTracks().addTrack_(track.track);
|
||||
|
||||
return htmlTrackElement;
|
||||
return track;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -787,12 +773,8 @@ class Html5 extends Tech {
|
||||
return super.removeRemoteTextTrack(track);
|
||||
}
|
||||
|
||||
let tracks, i;
|
||||
var tracks, i;
|
||||
|
||||
let trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
|
||||
|
||||
// remove HTMLTrackElement and TextTrack from remote list
|
||||
this.remoteTextTrackEls().removeTrackElement_(trackElement);
|
||||
this.remoteTextTracks().removeTrack_(track);
|
||||
|
||||
tracks = this.$$('track');
|
||||
@@ -1110,29 +1092,6 @@ Html5.disposeMediaElement = function(el){
|
||||
}
|
||||
};
|
||||
|
||||
Html5.resetMediaElement = function(el){
|
||||
if (!el) { return; }
|
||||
|
||||
let sources = el.querySelectorAll('source');
|
||||
let i = sources.length;
|
||||
while (i--) {
|
||||
el.removeChild(sources[i]);
|
||||
}
|
||||
|
||||
// remove any src reference.
|
||||
// not setting `src=''` because that throws an error
|
||||
el.removeAttribute('src');
|
||||
|
||||
if (typeof el.load === 'function') {
|
||||
// wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
|
||||
(function() {
|
||||
try {
|
||||
el.load();
|
||||
} catch (e) {}
|
||||
})();
|
||||
}
|
||||
};
|
||||
|
||||
Component.registerComponent('Html5', Html5);
|
||||
Tech.registerTech('Html5', Html5);
|
||||
export default Html5;
|
||||
|
||||
+13
-48
@@ -5,9 +5,6 @@
|
||||
*/
|
||||
|
||||
import Component from '../component';
|
||||
import HTMLTrackElement from '../tracks/html-track-element';
|
||||
import HTMLTrackElementList from '../tracks/html-track-element-list';
|
||||
import mergeOptions from '../utils/merge-options.js';
|
||||
import TextTrack from '../tracks/text-track';
|
||||
import TextTrackList from '../tracks/text-track-list';
|
||||
import * as Fn from '../utils/fn.js';
|
||||
@@ -236,13 +233,6 @@ class Tech extends Component {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the tech. Removes all sources and resets readyState.
|
||||
*
|
||||
* @method reset
|
||||
*/
|
||||
reset() {}
|
||||
|
||||
/**
|
||||
* When invoked without an argument, returns a MediaError object
|
||||
* representing the current error state of the player or null if
|
||||
@@ -326,13 +316,14 @@ class Tech extends Component {
|
||||
|
||||
if (!window['WebVTT'] && this.el().parentNode != null) {
|
||||
let script = document.createElement('script');
|
||||
script.src = this.options_['vtt.js'] || '../node_modules/videojs-vtt.js/dist/vtt.js';
|
||||
script.src = this.options_['vtt.js'] || '../node_modules/vtt.js/dist/vtt.js';
|
||||
this.el().parentNode.appendChild(script);
|
||||
window['WebVTT'] = true;
|
||||
}
|
||||
|
||||
let updateDisplay = () => this.trigger('texttrackchange');
|
||||
let textTracksChanges = () => {
|
||||
let textTracksChanges = Fn.bind(this, function() {
|
||||
let updateDisplay = () => this.trigger('texttrackchange');
|
||||
|
||||
updateDisplay();
|
||||
|
||||
for (let i = 0; i < tracks.length; i++) {
|
||||
@@ -342,9 +333,8 @@ class Tech extends Component {
|
||||
track.addEventListener('cuechange', updateDisplay);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
textTracksChanges();
|
||||
tracks.addEventListener('change', textTracksChanges);
|
||||
|
||||
this.on('dispose', function() {
|
||||
@@ -380,17 +370,6 @@ class Tech extends Component {
|
||||
return this.remoteTextTracks_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get remote htmltrackelements
|
||||
*
|
||||
* @returns {HTMLTrackElementList}
|
||||
* @method remoteTextTrackEls
|
||||
*/
|
||||
remoteTextTrackEls() {
|
||||
this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new HTMLTrackElementList();
|
||||
return this.remoteTextTrackEls_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a remote text track object
|
||||
*
|
||||
@@ -410,28 +389,19 @@ class Tech extends Component {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a remote text track object and returns a emulated html track element
|
||||
* Creates and returns a remote text track object
|
||||
*
|
||||
* @param {Object} options The object should contain values for
|
||||
* kind, language, label and src (location of the WebVTT file)
|
||||
* @return {HTMLTrackElement}
|
||||
* @return {TextTrackObject}
|
||||
* @method addRemoteTextTrack
|
||||
*/
|
||||
addRemoteTextTrack(options) {
|
||||
let track = mergeOptions(options, {
|
||||
tech: this
|
||||
});
|
||||
|
||||
let htmlTrackElement = new HTMLTrackElement(track);
|
||||
|
||||
// store HTMLTrackElement and TextTrack to remote list
|
||||
this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
|
||||
this.remoteTextTracks().addTrack_(htmlTrackElement.track);
|
||||
|
||||
// must come after remoteTextTracks()
|
||||
this.textTracks().addTrack_(htmlTrackElement.track);
|
||||
|
||||
return htmlTrackElement;
|
||||
let track = createTrackHelper(this, options.kind, options.label, options.language, options);
|
||||
this.remoteTextTracks().addTrack_(track);
|
||||
return {
|
||||
track: track
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -442,11 +412,6 @@ class Tech extends Component {
|
||||
*/
|
||||
removeRemoteTextTrack(track) {
|
||||
this.textTracks().removeTrack_(track);
|
||||
|
||||
let trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
|
||||
|
||||
// remove HTMLTrackElement and TextTrack from remote list
|
||||
this.remoteTextTrackEls().removeTrackElement_(trackElement);
|
||||
this.remoteTextTracks().removeTrack_(track);
|
||||
}
|
||||
|
||||
@@ -475,7 +440,7 @@ class Tech extends Component {
|
||||
/*
|
||||
* Return whether the argument is a Tech or not.
|
||||
* Can be passed either a Class like `Html5` or a instance like `player.tech_`
|
||||
*
|
||||
*
|
||||
* @param {Object} component An item to check
|
||||
* @return {Boolean} Whether it is a tech or not
|
||||
*/
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/**
|
||||
* @file html-track-element-list.js
|
||||
*/
|
||||
|
||||
import * as browser from '../utils/browser.js';
|
||||
import document from 'global/document';
|
||||
|
||||
class HtmlTrackElementList {
|
||||
constructor(trackElements = []) {
|
||||
let list = this;
|
||||
|
||||
if (browser.IS_IE8) {
|
||||
list = document.createElement('custom');
|
||||
|
||||
for (let prop in HtmlTrackElementList.prototype) {
|
||||
if (prop !== 'constructor') {
|
||||
list[prop] = HtmlTrackElementList.prototype[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list.trackElements_ = [];
|
||||
|
||||
Object.defineProperty(list, 'length', {
|
||||
get() {
|
||||
return this.trackElements_.length;
|
||||
}
|
||||
});
|
||||
|
||||
for (let i = 0, length = trackElements.length; i < length; i++) {
|
||||
list.addTrackElement_(trackElements[i]);
|
||||
}
|
||||
|
||||
if (browser.IS_IE8) {
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
addTrackElement_(trackElement) {
|
||||
this.trackElements_.push(trackElement);
|
||||
}
|
||||
|
||||
getTrackElementByTrack_(track) {
|
||||
let trackElement_;
|
||||
|
||||
for (let i = 0, length = this.trackElements_.length; i < length; i++) {
|
||||
if (track === this.trackElements_[i].track) {
|
||||
trackElement_ = this.trackElements_[i];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return trackElement_;
|
||||
}
|
||||
|
||||
removeTrackElement_(trackElement) {
|
||||
for (let i = 0, length = this.trackElements_.length; i < length; i++) {
|
||||
if (trackElement === this.trackElements_[i]) {
|
||||
this.trackElements_.splice(i, 1);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default HtmlTrackElementList;
|
||||
@@ -1,101 +0,0 @@
|
||||
/**
|
||||
* @file html-track-element.js
|
||||
*/
|
||||
|
||||
import * as browser from '../utils/browser.js';
|
||||
import document from 'global/document';
|
||||
import EventTarget from '../event-target';
|
||||
import TextTrack from '../tracks/text-track';
|
||||
|
||||
const NONE = 0;
|
||||
const LOADING = 1;
|
||||
const LOADED = 2;
|
||||
const ERROR = 3;
|
||||
|
||||
/**
|
||||
* https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement
|
||||
*
|
||||
* interface HTMLTrackElement : HTMLElement {
|
||||
* attribute DOMString kind;
|
||||
* attribute DOMString src;
|
||||
* attribute DOMString srclang;
|
||||
* attribute DOMString label;
|
||||
* attribute boolean default;
|
||||
*
|
||||
* const unsigned short NONE = 0;
|
||||
* const unsigned short LOADING = 1;
|
||||
* const unsigned short LOADED = 2;
|
||||
* const unsigned short ERROR = 3;
|
||||
* readonly attribute unsigned short readyState;
|
||||
*
|
||||
* readonly attribute TextTrack track;
|
||||
* };
|
||||
*
|
||||
* @param {Object} options TextTrack configuration
|
||||
* @class HTMLTrackElement
|
||||
*/
|
||||
|
||||
class HTMLTrackElement extends EventTarget {
|
||||
constructor(options = {}) {
|
||||
super();
|
||||
|
||||
let readyState,
|
||||
trackElement = this;
|
||||
|
||||
if (browser.IS_IE8) {
|
||||
trackElement = document.createElement('custom');
|
||||
|
||||
for (let prop in HTMLTrackElement.prototype) {
|
||||
if (prop !== 'constructor') {
|
||||
trackElement[prop] = HTMLTrackElement.prototype[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let track = new TextTrack(options);
|
||||
|
||||
trackElement.kind = track.kind;
|
||||
trackElement.src = track.src;
|
||||
trackElement.srclang = track.language;
|
||||
trackElement.label = track.label;
|
||||
trackElement.default = track.default;
|
||||
|
||||
Object.defineProperty(trackElement, 'readyState', {
|
||||
get() {
|
||||
return readyState;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(trackElement, 'track', {
|
||||
get() {
|
||||
return track;
|
||||
}
|
||||
});
|
||||
|
||||
readyState = NONE;
|
||||
|
||||
track.addEventListener('loadeddata', function() {
|
||||
readyState = LOADED;
|
||||
|
||||
trackElement.trigger({
|
||||
type: 'load',
|
||||
target: trackElement
|
||||
});
|
||||
});
|
||||
|
||||
if (browser.IS_IE8) {
|
||||
return trackElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HTMLTrackElement.prototype.allowedEvents_ = {
|
||||
load: 'load'
|
||||
};
|
||||
|
||||
HTMLTrackElement.NONE = NONE;
|
||||
HTMLTrackElement.LOADING = LOADING;
|
||||
HTMLTrackElement.LOADED = LOADED;
|
||||
HTMLTrackElement.ERROR = ERROR;
|
||||
|
||||
export default HTMLTrackElement;
|
||||
@@ -141,12 +141,7 @@ class TextTrackDisplay extends Component {
|
||||
|
||||
let i = cues.length;
|
||||
while (i--) {
|
||||
let cue = cues[i];
|
||||
if (!cue) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let cueDiv = cue.displayState;
|
||||
let cueDiv = cues[i].displayState;
|
||||
if (overrides.color) {
|
||||
cueDiv.firstChild.style.color = overrides.color;
|
||||
}
|
||||
|
||||
@@ -69,13 +69,6 @@ for (let event in TextTrackList.prototype.allowedEvents_) {
|
||||
TextTrackList.prototype['on' + event] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add TextTrack from TextTrackList
|
||||
*
|
||||
* @param {TextTrack} track
|
||||
* @method addTrack_
|
||||
* @private
|
||||
*/
|
||||
TextTrackList.prototype.addTrack_ = function(track) {
|
||||
let index = this.tracks_.length;
|
||||
if (!(''+index in this)) {
|
||||
@@ -97,31 +90,18 @@ TextTrackList.prototype.addTrack_ = function(track) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove TextTrack from TextTrackList
|
||||
* NOTE: Be mindful of what is passed in as it may be a HTMLTrackElement
|
||||
*
|
||||
* @param {TextTrack} rtrack
|
||||
* @method removeTrack_
|
||||
* @private
|
||||
*/
|
||||
TextTrackList.prototype.removeTrack_ = function(rtrack) {
|
||||
let result = null;
|
||||
let track;
|
||||
|
||||
for (let i = 0, l = this.length; i < l; i++) {
|
||||
if (this[i] === rtrack) {
|
||||
track = this[i];
|
||||
|
||||
track = this[i];
|
||||
if (track === rtrack) {
|
||||
this.tracks_.splice(i, 1);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!track) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.trigger({
|
||||
type: 'removetrack',
|
||||
track: track
|
||||
|
||||
@@ -45,9 +45,7 @@ let TextTrack = function(options={}) {
|
||||
tt = document.createElement('custom');
|
||||
|
||||
for (let prop in TextTrack.prototype) {
|
||||
if (prop !== 'constructor') {
|
||||
tt[prop] = TextTrack.prototype[prop];
|
||||
}
|
||||
tt[prop] = TextTrack.prototype[prop];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,25 +233,24 @@ TextTrack.prototype.removeCue = function(removeCue) {
|
||||
* Downloading stuff happens below this point
|
||||
*/
|
||||
var parseCues = function(srcContent, track) {
|
||||
let parser = new window.WebVTT.Parser(window, window.vttjs, window.WebVTT.StringDecoder());
|
||||
if (typeof window['WebVTT'] !== 'function') {
|
||||
//try again a bit later
|
||||
return window.setTimeout(function() {
|
||||
parseCues(srcContent, track);
|
||||
}, 25);
|
||||
}
|
||||
|
||||
parser.oncue = function(cue) {
|
||||
let parser = new window['WebVTT']['Parser'](window, window['vttjs'], window['WebVTT']['StringDecoder']());
|
||||
|
||||
parser['oncue'] = function(cue) {
|
||||
track.addCue(cue);
|
||||
};
|
||||
|
||||
parser.onparsingerror = function(error) {
|
||||
parser['onparsingerror'] = function(error) {
|
||||
log.error(error);
|
||||
};
|
||||
|
||||
parser.onflush = function() {
|
||||
track.trigger({
|
||||
type: 'loadeddata',
|
||||
target: track
|
||||
});
|
||||
};
|
||||
|
||||
parser.parse(srcContent);
|
||||
parser.flush();
|
||||
parser['parse'](srcContent);
|
||||
parser['flush']();
|
||||
};
|
||||
|
||||
var loadTrack = function(src, track) {
|
||||
@@ -272,15 +269,7 @@ var loadTrack = function(src, track) {
|
||||
}
|
||||
|
||||
track.loaded_ = true;
|
||||
|
||||
// NOTE: this is only used for the alt/video.novtt.js build
|
||||
if (typeof window.WebVTT !== 'function') {
|
||||
window.setTimeout(function() {
|
||||
parseCues(responseBody, track);
|
||||
}, 100);
|
||||
} else {
|
||||
parseCues(responseBody, track);
|
||||
}
|
||||
parseCues(responseBody, track);
|
||||
}));
|
||||
};
|
||||
|
||||
|
||||
@@ -79,9 +79,8 @@ export function getEl(id){
|
||||
/**
|
||||
* Creates an element and applies properties.
|
||||
*
|
||||
* @param {String} [tagName='div'] Name of tag to be created.
|
||||
* @param {Object} [properties={}] Element properties to be applied.
|
||||
* @param {Object} [attributes={}] Element attributes to be applied.
|
||||
* @param {String=} tagName Name of tag to be created.
|
||||
* @param {Object=} properties Element properties to be applied.
|
||||
* @return {Element}
|
||||
* @function createEl
|
||||
*/
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
* @function formatTime
|
||||
*/
|
||||
function formatTime(seconds, guide=seconds) {
|
||||
seconds = seconds < 0 ? 0 : seconds;
|
||||
let s = Math.floor(seconds % 60);
|
||||
let m = Math.floor(seconds / 60 % 60);
|
||||
let h = Math.floor(seconds / 3600);
|
||||
|
||||
+3
-14
@@ -52,8 +52,8 @@ if (typeof HTMLVideoElement === 'undefined') {
|
||||
* @mixes videojs
|
||||
* @method videojs
|
||||
*/
|
||||
let videojs = function(id, options, ready){
|
||||
let tag; // Element of ID
|
||||
var videojs = function(id, options, ready){
|
||||
var tag; // Element of ID
|
||||
|
||||
// Allow for element or ID to be passed in
|
||||
// String ID
|
||||
@@ -95,7 +95,7 @@ let videojs = function(id, options, ready){
|
||||
|
||||
// Element may have a player attr referring to an already created player instance.
|
||||
// If not, set up a new player and return the instance.
|
||||
return tag['player'] || Player.players[tag.playerId] || new Player(tag, options, ready);
|
||||
return tag['player'] || new Player(tag, options, ready);
|
||||
};
|
||||
|
||||
// Add default styles
|
||||
@@ -563,17 +563,6 @@ videojs.isEl = Dom.isEl;
|
||||
*/
|
||||
videojs.isTextNode = Dom.isTextNode;
|
||||
|
||||
/**
|
||||
* Creates an element and applies properties.
|
||||
*
|
||||
* @method createEl
|
||||
* @param {String} [tagName='div'] Name of tag to be created.
|
||||
* @param {Object} [properties={}] Element properties to be applied.
|
||||
* @param {Object} [attributes={}] Element attributes to be applied.
|
||||
* @return {Element}
|
||||
*/
|
||||
videojs.createEl = Dom.createEl;
|
||||
|
||||
/**
|
||||
* Check if an element has a CSS class
|
||||
*
|
||||
|
||||
@@ -61,7 +61,6 @@ test('should be able to access expected player API methods', function() {
|
||||
|
||||
// TextTrack methods
|
||||
ok(player.textTracks, 'textTracks exists');
|
||||
ok(player.remoteTextTrackEls, 'remoteTextTrackEls exists');
|
||||
ok(player.remoteTextTracks, 'remoteTextTracks exists');
|
||||
ok(player.addTextTrack, 'addTextTrack exists');
|
||||
ok(player.addRemoteTextTrack, 'addRemoteTextTrack exists');
|
||||
|
||||
@@ -4,7 +4,7 @@ import TestHelpers from './test-helpers.js';
|
||||
q.module('Button');
|
||||
|
||||
test('should localize its text', function(){
|
||||
expect(2);
|
||||
expect(1);
|
||||
|
||||
var player, testButton, el;
|
||||
|
||||
@@ -21,6 +21,5 @@ test('should localize its text', function(){
|
||||
testButton.controlText_ = 'Play';
|
||||
el = testButton.createEl();
|
||||
|
||||
ok(el.nodeName.toLowerCase().match('button'));
|
||||
ok(el.innerHTML.match('Juego'));
|
||||
});
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import ClickableComponent from '../../src/js/clickable-component.js';
|
||||
import TestHelpers from './test-helpers.js';
|
||||
|
||||
q.module('ClickableComponent');
|
||||
|
||||
test('should create a div with role="button"', function(){
|
||||
expect(2);
|
||||
|
||||
var player, testClickableComponent, el;
|
||||
|
||||
player = TestHelpers.makePlayer({
|
||||
});
|
||||
|
||||
testClickableComponent = new ClickableComponent(player);
|
||||
el = testClickableComponent.createEl();
|
||||
|
||||
equal(el.nodeName.toLowerCase(), 'div', 'the name of the element is "div"');
|
||||
equal(el.getAttribute('role').toLowerCase(), 'button', 'the role of the element is "button"');
|
||||
});
|
||||
+64
-133
@@ -7,9 +7,6 @@ import MediaError from '../../src/js/media-error.js';
|
||||
import Html5 from '../../src/js/tech/html5.js';
|
||||
import TestHelpers from './test-helpers.js';
|
||||
import document from 'global/document';
|
||||
import window from 'global/window';
|
||||
import Tech from '../../src/js/tech/tech.js';
|
||||
import TechFaker from './tech/tech-faker.js';
|
||||
|
||||
q.module('Player', {
|
||||
'setup': function() {
|
||||
@@ -20,6 +17,36 @@ q.module('Player', {
|
||||
}
|
||||
});
|
||||
|
||||
// Compiler doesn't like using 'this' in setup/teardown.
|
||||
// module("Player", {
|
||||
// /**
|
||||
// * @this {*}
|
||||
// */
|
||||
// setup: function(){
|
||||
// window.player1 = true; // using window works
|
||||
// },
|
||||
|
||||
// /**
|
||||
// * @this {*}
|
||||
// */
|
||||
// teardown: function(){
|
||||
// // if (this.player && this.player.el() !== null) {
|
||||
// // this.player.dispose();
|
||||
// // this.player = null;
|
||||
// // }
|
||||
// }
|
||||
// });
|
||||
|
||||
// Object.size = function(obj) {
|
||||
// var size = 0, key;
|
||||
// for (key in obj) {
|
||||
// console.log('key', key)
|
||||
// if (obj.hasOwnProperty(key)) size++;
|
||||
// }
|
||||
// return size;
|
||||
// };
|
||||
|
||||
|
||||
test('should create player instance that inherits from component and dispose it', function(){
|
||||
var player = TestHelpers.makePlayer();
|
||||
|
||||
@@ -30,15 +57,6 @@ test('should create player instance that inherits from component and dispose it'
|
||||
ok(player.el() === null, 'element disposed');
|
||||
});
|
||||
|
||||
test('dispose should not throw if styleEl is missing', function(){
|
||||
var player = TestHelpers.makePlayer();
|
||||
|
||||
player.styleEl_.parentNode.removeChild(player.styleEl_);
|
||||
|
||||
player.dispose();
|
||||
ok(player.el() === null, 'element disposed');
|
||||
});
|
||||
|
||||
// technically, all uses of videojs.options should be replaced with
|
||||
// Player.prototype.options_ in this file and a equivalent test using
|
||||
// videojs.options should be made in video.test.js. Keeping this here
|
||||
@@ -321,6 +339,24 @@ test('should set controls and trigger events', function() {
|
||||
player.dispose();
|
||||
});
|
||||
|
||||
// Can't figure out how to test fullscreen events with tests
|
||||
// Browsers aren't triggering the events at least
|
||||
// asyncTest('should trigger the fullscreenchange event', function() {
|
||||
// expect(3);
|
||||
|
||||
// var player = TestHelpers.makePlayer();
|
||||
// player.on('fullscreenchange', function(){
|
||||
// ok(true, 'fullscreenchange event fired');
|
||||
// ok(this.isFullscreen() === true, 'isFullscreen is true');
|
||||
// ok(this.el().className.indexOf('vjs-fullscreen') !== -1, 'vjs-fullscreen class added');
|
||||
|
||||
// player.dispose();
|
||||
// start();
|
||||
// });
|
||||
|
||||
// player.requestFullscreen();
|
||||
// });
|
||||
|
||||
test('should toggle user the user state between active and inactive', function(){
|
||||
var player = TestHelpers.makePlayer({});
|
||||
|
||||
@@ -420,42 +456,27 @@ test('make sure that controls listeners do not get added too many times', functi
|
||||
player.dispose();
|
||||
});
|
||||
|
||||
test('should select the proper tech based on the the sourceOrder option',
|
||||
function() {
|
||||
let fixture = document.getElementById('qunit-fixture');
|
||||
let html =
|
||||
'<video id="example_1">' +
|
||||
'<source src="fake.foo1" type="video/unsupported-format">' +
|
||||
'<source src="fake.foo2" type="video/foo-format">' +
|
||||
'</video>';
|
||||
// test('should use custom message when encountering an unsupported video type',
|
||||
// function() {
|
||||
// videojs.options['notSupportedMessage'] = 'Video no go <a href="">link</a>';
|
||||
// var fixture = document.getElementById('qunit-fixture');
|
||||
|
||||
// Extend TechFaker to create a tech that plays the only mime-type that TechFaker
|
||||
// will not play
|
||||
class PlaysUnsupported extends TechFaker {
|
||||
constructor(options, handleReady){
|
||||
super(options, handleReady);
|
||||
}
|
||||
// Support ONLY "video/unsupported-format"
|
||||
static isSupported() { return true; }
|
||||
static canPlayType(type) { return (type === 'video/unsupported-format' ? 'maybe' : ''); }
|
||||
static canPlaySource(srcObj) { return srcObj.type === 'video/unsupported-format'; }
|
||||
}
|
||||
Tech.registerTech('PlaysUnsupported', PlaysUnsupported);
|
||||
// var html =
|
||||
// '<video id="example_1">' +
|
||||
// '<source src="fake.foo" type="video/foo">' +
|
||||
// '</video>';
|
||||
|
||||
fixture.innerHTML += html;
|
||||
let tag = document.getElementById('example_1');
|
||||
// fixture.innerHTML += html;
|
||||
|
||||
let player = new Player(tag, { techOrder: ['techFaker', 'playsUnsupported'], sourceOrder: true });
|
||||
equal(player.techName_, 'PlaysUnsupported', 'selected the PlaysUnsupported tech when sourceOrder is truthy');
|
||||
player.dispose();
|
||||
// var tag = document.getElementById('example_1');
|
||||
// var player = new Player(tag, { techOrder: ['techFaker'] });
|
||||
|
||||
fixture.innerHTML += html;
|
||||
tag = document.getElementById('example_1');
|
||||
// var incompatibilityMessage = player.el().getElementsByTagName('p')[0];
|
||||
// // ie8 capitalizes tag names
|
||||
// equal(incompatibilityMessage.innerHTML.toLowerCase(), 'video no go <a href="">link</a>');
|
||||
|
||||
player = new Player(tag, { techOrder: ['techFaker', 'playsUnsupported']});
|
||||
equal(player.techName_, 'TechFaker', 'selected the TechFaker tech when sourceOrder is falsey');
|
||||
player.dispose();
|
||||
});
|
||||
// player.dispose();
|
||||
// });
|
||||
|
||||
test('should register players with generated ids', function(){
|
||||
var fixture, video, player, id;
|
||||
@@ -853,93 +874,3 @@ test('createModal() options object', function() {
|
||||
strictEqual(modal.options_.label, 'boo', 'modal options are set properly');
|
||||
modal.close();
|
||||
});
|
||||
|
||||
test('you can clear error in the error event', function() {
|
||||
let player = TestHelpers.makePlayer();
|
||||
|
||||
sinon.stub(log, 'error');
|
||||
|
||||
player.error({code: 4});
|
||||
ok(player.error(), 'we have an error');
|
||||
player.error(null);
|
||||
|
||||
player.one('error', function() {
|
||||
player.error(null);
|
||||
});
|
||||
player.error({code: 4});
|
||||
ok(!player.error(), 'we no longer have an error');
|
||||
|
||||
log.error.restore();
|
||||
});
|
||||
|
||||
test('Player#tech will return tech given the appropriate input', function() {
|
||||
let tech_ = {};
|
||||
let returnedTech = Player.prototype.tech.call({tech_}, {IWillNotUseThisInPlugins: true});
|
||||
|
||||
equal(returnedTech, tech_, 'We got back the tech we wanted');
|
||||
});
|
||||
|
||||
test('Player#tech alerts and throws without the appropriate input', function() {
|
||||
let alertCalled;
|
||||
let oldAlert = window.alert;
|
||||
window.alert = () => alertCalled = true;
|
||||
|
||||
let tech_ = {};
|
||||
throws(function() {
|
||||
Player.prototype.tech.call({tech_});
|
||||
}, new RegExp('https://github.com/videojs/video.js/issues/2617'),
|
||||
'we threw an error');
|
||||
|
||||
ok(alertCalled, 'we called an alert');
|
||||
window.alert = oldAlert;
|
||||
});
|
||||
|
||||
test('player#reset loads the Html5 tech and then techCalls reset', function() {
|
||||
let loadedTech;
|
||||
let loadedSource;
|
||||
let techCallMethod;
|
||||
|
||||
let testPlayer = {
|
||||
options_: {
|
||||
techOrder: ['html5', 'flash'],
|
||||
},
|
||||
loadTech_(tech, source) {
|
||||
loadedTech = tech;
|
||||
loadedSource = source;
|
||||
},
|
||||
techCall_(method) {
|
||||
techCallMethod = method;
|
||||
}
|
||||
};
|
||||
|
||||
Player.prototype.reset.call(testPlayer);
|
||||
|
||||
equal(loadedTech, 'Html5', 'we loaded the html5 tech');
|
||||
equal(loadedSource, null, 'with a null source');
|
||||
equal(techCallMethod, 'reset', 'we then reset the tech');
|
||||
});
|
||||
|
||||
test('player#reset loads the first item in the techOrder and then techCalls reset', function() {
|
||||
let loadedTech;
|
||||
let loadedSource;
|
||||
let techCallMethod;
|
||||
|
||||
let testPlayer = {
|
||||
options_: {
|
||||
techOrder: ['flash', 'html5'],
|
||||
},
|
||||
loadTech_(tech, source) {
|
||||
loadedTech = tech;
|
||||
loadedSource = source;
|
||||
},
|
||||
techCall_(method) {
|
||||
techCallMethod = method;
|
||||
}
|
||||
};
|
||||
|
||||
Player.prototype.reset.call(testPlayer);
|
||||
|
||||
equal(loadedTech, 'Flash', 'we loaded the Flash tech');
|
||||
equal(loadedSource, null, 'with a null source');
|
||||
equal(techCallMethod, 'reset', 'we then reset the tech');
|
||||
});
|
||||
|
||||
@@ -304,50 +304,3 @@ test('should fire makeup events when a video tag is initialized late', function(
|
||||
testStates({ networkState: 1, readyState: 3 }, ['loadstart', 'loadedmetadata', 'loadeddata', 'canplay']);
|
||||
testStates({ networkState: 1, readyState: 4 }, ['loadstart', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough']);
|
||||
});
|
||||
|
||||
test('Html5.resetMediaElement should remove sources and call load', function() {
|
||||
let selector;
|
||||
let removedChildren = [];
|
||||
let removedAttribute;
|
||||
let loaded;
|
||||
|
||||
let children = ['source1', 'source2', 'source3'];
|
||||
let testEl = {
|
||||
querySelectorAll(input) {
|
||||
selector = input;
|
||||
return children;
|
||||
},
|
||||
|
||||
removeChild(child) {
|
||||
removedChildren.push(child);
|
||||
},
|
||||
|
||||
removeAttribute(attr) {
|
||||
removedAttribute = attr;
|
||||
},
|
||||
|
||||
load() {
|
||||
loaded = true;
|
||||
}
|
||||
};
|
||||
|
||||
Html5.resetMediaElement(testEl);
|
||||
equal(selector, 'source', 'we got the source elements from the test el');
|
||||
deepEqual(removedChildren, children.reverse(), 'we removed the children that were present');
|
||||
equal(removedAttribute, 'src', 'we removed the src attribute');
|
||||
ok(loaded, 'we called load on the element');
|
||||
});
|
||||
|
||||
test('Html5#reset calls Html5.resetMediaElement when called', function() {
|
||||
let oldResetMedia = Html5.resetMediaElement;
|
||||
let resetEl;
|
||||
|
||||
Html5.resetMediaElement = (el) => resetEl = el;
|
||||
|
||||
let el = {};
|
||||
Html5.prototype.reset.call({el_: el});
|
||||
|
||||
equal(resetEl, el, 'we called resetMediaElement with the tech\'s el');
|
||||
|
||||
Html5.resetMediaElement = oldResetMedia;
|
||||
});
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
import HTMLTrackElement from '../../../src/js/tracks/html-track-element.js';
|
||||
import HTMLTrackElementList from '../../../src/js/tracks/html-track-element-list.js';
|
||||
import TextTrack from '../../../src/js/tracks/text-track.js';
|
||||
|
||||
let noop = Function.prototype;
|
||||
let defaultTech = {
|
||||
textTracks: noop,
|
||||
on: noop,
|
||||
off: noop,
|
||||
currentTime: noop
|
||||
};
|
||||
|
||||
let track1 = new TextTrack({
|
||||
id: 1,
|
||||
tech: defaultTech
|
||||
});
|
||||
let track2 = new TextTrack({
|
||||
id: 2,
|
||||
tech: defaultTech
|
||||
});
|
||||
|
||||
var genericHtmlTrackElements = [{
|
||||
kind: 'captions',
|
||||
tech: noop,
|
||||
track: track1
|
||||
}, {
|
||||
kind: 'chapters',
|
||||
tech: noop,
|
||||
track: track2
|
||||
}];
|
||||
|
||||
q.module('HTML Track Element List');
|
||||
|
||||
test('HTMLTrackElementList\'s length is set correctly', function() {
|
||||
let htmlTrackElementList = new HTMLTrackElementList(genericHtmlTrackElements);
|
||||
|
||||
equal(htmlTrackElementList.length, genericHtmlTrackElements.length, `the length is ${genericHtmlTrackElements.length}`);
|
||||
});
|
||||
|
||||
test('can get html track element by track', function() {
|
||||
let htmlTrackElementList = new HTMLTrackElementList(genericHtmlTrackElements);
|
||||
|
||||
equal(htmlTrackElementList.getTrackElementByTrack_(track1).kind, 'captions', 'track1 has kind of captions');
|
||||
equal(htmlTrackElementList.getTrackElementByTrack_(track2).kind, 'chapters', 'track2 has kind of captions');
|
||||
});
|
||||
|
||||
test('length is updated when new tracks are added or removed', function() {
|
||||
let htmlTrackElementList = new HTMLTrackElementList(genericHtmlTrackElements);
|
||||
|
||||
htmlTrackElementList.addTrackElement_({tech: noop});
|
||||
equal(htmlTrackElementList.length, genericHtmlTrackElements.length + 1, `the length is ${genericHtmlTrackElements.length + 1}`);
|
||||
htmlTrackElementList.addTrackElement_({tech: noop});
|
||||
equal(htmlTrackElementList.length, genericHtmlTrackElements.length + 2, `the length is ${genericHtmlTrackElements.length + 2}`);
|
||||
|
||||
htmlTrackElementList.removeTrackElement_(htmlTrackElementList.getTrackElementByTrack_(track1));
|
||||
equal(htmlTrackElementList.length, genericHtmlTrackElements.length + 1, `the length is ${genericHtmlTrackElements.length + 1}`);
|
||||
htmlTrackElementList.removeTrackElement_(htmlTrackElementList.getTrackElementByTrack_(track2));
|
||||
equal(htmlTrackElementList.length, genericHtmlTrackElements.length, `the length is ${genericHtmlTrackElements.length}`);
|
||||
});
|
||||
@@ -1,81 +0,0 @@
|
||||
import HTMLTrackElement from '../../../src/js/tracks/html-track-element.js';
|
||||
import TextTrack from '../../../src/js/tracks/text-track.js';
|
||||
import window from 'global/window';
|
||||
|
||||
let noop = Function.prototype;
|
||||
let defaultTech = {
|
||||
textTracks: noop,
|
||||
on: noop,
|
||||
off: noop,
|
||||
currentTime: noop
|
||||
};
|
||||
|
||||
q.module('HTML Track Element');
|
||||
|
||||
test('html track element requires a tech', function() {
|
||||
window.throws(
|
||||
function() {
|
||||
new HTMLTrackElement();
|
||||
},
|
||||
new Error('A tech was not provided.'),
|
||||
'a tech is required for html track element'
|
||||
);
|
||||
});
|
||||
|
||||
test('can create a html track element with various properties', function() {
|
||||
let kind = 'chapters',
|
||||
label = 'English',
|
||||
language = 'en',
|
||||
src = 'http://www.example.com';
|
||||
|
||||
let htmlTrackElement = new HTMLTrackElement({
|
||||
kind,
|
||||
label,
|
||||
language,
|
||||
src,
|
||||
tech: defaultTech
|
||||
});
|
||||
|
||||
equal(htmlTrackElement.default, undefined, 'we have a default');
|
||||
equal(htmlTrackElement.kind, kind, 'we have a kind');
|
||||
equal(htmlTrackElement.label, label, 'we have a label');
|
||||
equal(htmlTrackElement.readyState, 0, 'we have a readyState');
|
||||
equal(htmlTrackElement.src, src, 'we have a src');
|
||||
equal(htmlTrackElement.srclang, language, 'we have a srclang');
|
||||
equal(htmlTrackElement.track.cues, null, 'we have a track');
|
||||
});
|
||||
|
||||
test('defaults when items not provided', function() {
|
||||
let htmlTrackElement = new HTMLTrackElement({
|
||||
tech: defaultTech
|
||||
});
|
||||
|
||||
equal(htmlTrackElement.default, undefined, 'we have a default');
|
||||
equal(htmlTrackElement.kind, 'subtitles', 'we have a kind');
|
||||
equal(htmlTrackElement.label, '', 'we have a label');
|
||||
equal(htmlTrackElement.readyState, 0, 'we have a readyState');
|
||||
equal(htmlTrackElement.src, undefined, 'we have a src');
|
||||
equal(htmlTrackElement.srclang, '', 'we have a srclang');
|
||||
equal(htmlTrackElement.track.cues.length, 0, 'we have a track');
|
||||
});
|
||||
|
||||
test('fires loadeddata when track cues become populated', function() {
|
||||
let changes = 0,
|
||||
loadHandler;
|
||||
|
||||
loadHandler = function() {
|
||||
changes++;
|
||||
};
|
||||
|
||||
let htmlTrackElement = new HTMLTrackElement({
|
||||
tech: noop
|
||||
});
|
||||
|
||||
htmlTrackElement.addEventListener('load', loadHandler);
|
||||
|
||||
// trigger loaded cues event
|
||||
htmlTrackElement.track.trigger('loadeddata');
|
||||
|
||||
equal(changes, 1, 'a loadeddata event trigger addEventListener');
|
||||
equal(htmlTrackElement.readyState, 2, 'readyState is loaded');
|
||||
});
|
||||
@@ -166,7 +166,7 @@ test('trigger "change" event when "modechange" is fired on a track', function()
|
||||
equal(changes, 2, 'two change events should have fired');
|
||||
});
|
||||
|
||||
test('trigger "change" event when mode changes on a TextTrack', function() {
|
||||
test('trigger "change" event when mode changes on a TextTracl', function() {
|
||||
var tt = new TextTrack({
|
||||
tech: {
|
||||
on: noop
|
||||
|
||||
@@ -2,7 +2,6 @@ import ChaptersButton from '../../../src/js/control-bar/text-track-controls/chap
|
||||
import SubtitlesButton from '../../../src/js/control-bar/text-track-controls/subtitles-button.js';
|
||||
import CaptionsButton from '../../../src/js/control-bar/text-track-controls/captions-button.js';
|
||||
|
||||
import TextTrack from '../../../src/js/tracks/text-track.js';
|
||||
import TextTrackDisplay from '../../../src/js/tracks/text-track-display.js';
|
||||
import Html5 from '../../../src/js/tech/html5.js';
|
||||
import Flash from '../../../src/js/tech/flash.js';
|
||||
@@ -15,14 +14,7 @@ import document from 'global/document';
|
||||
import window from 'global/window';
|
||||
import TechFaker from '../tech/tech-faker.js';
|
||||
|
||||
q.module('Tracks', {
|
||||
'setup': function() {
|
||||
this.clock = sinon.useFakeTimers();
|
||||
},
|
||||
'teardown': function() {
|
||||
this.clock.restore();
|
||||
}
|
||||
});
|
||||
q.module('Tracks');
|
||||
|
||||
test('should place title list item into ul', function() {
|
||||
var player, chaptersButton;
|
||||
@@ -350,121 +342,3 @@ if (Html5.supportsNativeTextTracks()) {
|
||||
emulatedTt.on('addtrack', addtrack);
|
||||
});
|
||||
}
|
||||
|
||||
test('should check for text track changes when emulating text tracks', function() {
|
||||
let tech = new Tech();
|
||||
let numTextTrackChanges = 0;
|
||||
tech.on('texttrackchange', function() {
|
||||
numTextTrackChanges++;
|
||||
});
|
||||
tech.emulateTextTracks();
|
||||
equal(numTextTrackChanges, 1, 'we got a texttrackchange event');
|
||||
});
|
||||
|
||||
test('removes cuechange event when text track is hidden for emulated tracks', function() {
|
||||
let player = TestHelpers.makePlayer();
|
||||
let tt = new TextTrack({
|
||||
tech: player.tech_,
|
||||
mode: 'showing'
|
||||
});
|
||||
tt.addCue({
|
||||
id: '1',
|
||||
startTime: 2,
|
||||
endTime: 5
|
||||
});
|
||||
player.tech_.textTracks().addTrack_(tt);
|
||||
player.tech_.emulateTextTracks();
|
||||
|
||||
let numTextTrackChanges = 0;
|
||||
player.tech_.on('texttrackchange', function() {
|
||||
numTextTrackChanges++;
|
||||
});
|
||||
|
||||
tt.mode = 'showing';
|
||||
equal(numTextTrackChanges, 1,
|
||||
'texttrackchange should be called once for mode change');
|
||||
tt.mode = 'showing';
|
||||
equal(numTextTrackChanges, 2,
|
||||
'texttrackchange should be called once for mode change');
|
||||
|
||||
player.tech_.currentTime = function() {
|
||||
return 3;
|
||||
};
|
||||
player.tech_.trigger('timeupdate');
|
||||
equal(numTextTrackChanges, 3,
|
||||
'texttrackchange should be triggered once for the cuechange');
|
||||
|
||||
tt.mode = 'hidden';
|
||||
equal(numTextTrackChanges, 4,
|
||||
'texttrackchange should be called once for the mode change');
|
||||
|
||||
player.tech_.currentTime = function() {
|
||||
return 7;
|
||||
};
|
||||
player.tech_.trigger('timeupdate');
|
||||
equal(numTextTrackChanges, 4,
|
||||
'texttrackchange should be not be called since mode is hidden');
|
||||
});
|
||||
|
||||
test('should return correct remote text track values', function () {
|
||||
let fixture = document.getElementById('qunit-fixture');
|
||||
|
||||
let html = '<video id="example_1" class="video-js" autoplay preload="none">';
|
||||
html += '<source src="http://google.com" type="video/mp4">';
|
||||
html += '<source src="http://google.com" type="video/webm">';
|
||||
html += '<track kind="captions" label="label">';
|
||||
html += '</video>';
|
||||
|
||||
fixture.innerHTML += html;
|
||||
|
||||
let tag = document.getElementById('example_1');
|
||||
|
||||
let player = TestHelpers.makePlayer({}, tag);
|
||||
|
||||
this.clock.tick(1);
|
||||
|
||||
equal(player.remoteTextTracks().length, 1, 'add text track via html');
|
||||
equal(player.remoteTextTrackEls().length, 1, 'add html track element via html');
|
||||
|
||||
let htmlTrackElement = player.addRemoteTextTrack({
|
||||
kind: 'captions',
|
||||
label: 'label'
|
||||
});
|
||||
|
||||
equal(player.remoteTextTracks().length, 2, 'add text track via method');
|
||||
equal(player.remoteTextTrackEls().length, 2, 'add html track element via method');
|
||||
|
||||
player.removeRemoteTextTrack(htmlTrackElement.track);
|
||||
|
||||
equal(player.remoteTextTracks().length, 1, 'remove text track via method');
|
||||
equal(player.remoteTextTrackEls().length, 1, 'remove html track element via method');
|
||||
|
||||
player.dispose();
|
||||
});
|
||||
|
||||
test('should uniformly create html track element when adding text track', function () {
|
||||
let player = TestHelpers.makePlayer();
|
||||
|
||||
let track = {
|
||||
kind: 'kind',
|
||||
src: 'src',
|
||||
language: 'language',
|
||||
label: 'label',
|
||||
default: 'default'
|
||||
};
|
||||
|
||||
equal(player.remoteTextTrackEls().length, 0, 'no html text tracks');
|
||||
|
||||
let htmlTrackElement = player.addRemoteTextTrack(track);
|
||||
|
||||
equal(htmlTrackElement.kind, htmlTrackElement.track.kind, 'verify html track element kind');
|
||||
equal(htmlTrackElement.src, htmlTrackElement.track.src, 'verify html track element src');
|
||||
equal(htmlTrackElement.srclang, htmlTrackElement.track.language, 'verify html track element language');
|
||||
equal(htmlTrackElement.label, htmlTrackElement.track.label, 'verify html track element label');
|
||||
equal(htmlTrackElement.default, htmlTrackElement.track.default, 'verify html track element default');
|
||||
|
||||
equal(player.remoteTextTrackEls().length, 1, 'html track element exist');
|
||||
equal(player.remoteTextTrackEls().getTrackElementByTrack_(htmlTrackElement.track), htmlTrackElement, 'verify same html track element');
|
||||
|
||||
player.dispose();
|
||||
});
|
||||
|
||||
@@ -20,10 +20,6 @@ test('should format time as a string', function(){
|
||||
// Don't do extra leading zeros for hours
|
||||
ok(formatTime(1,36000) === '0:00:01');
|
||||
ok(formatTime(1,360000) === '0:00:01');
|
||||
|
||||
// Do not display negative time
|
||||
ok(formatTime(-1) === '0:00');
|
||||
ok(formatTime(-1,3600) === '0:00:00');
|
||||
});
|
||||
|
||||
test('should format invalid times as dashes', function(){
|
||||
|
||||
@@ -30,50 +30,6 @@ test('should return a video player instance', function(){
|
||||
var playerAgain = videojs('test_vid_id');
|
||||
ok(player === playerAgain, 'did not create a second player from same tag');
|
||||
|
||||
equal(player, playerAgain, 'we did not make a new player');
|
||||
|
||||
var tag2 = document.getElementById('test_vid_id2');
|
||||
var player2 = videojs(tag2, { techOrder: ['techFaker'] });
|
||||
ok(player2.id() === 'test_vid_id2', 'created player from element');
|
||||
});
|
||||
|
||||
test('should return a video player instance from el html5 tech', function() {
|
||||
var fixture = document.getElementById('qunit-fixture');
|
||||
fixture.innerHTML += '<video id="test_vid_id"></video><video id="test_vid_id2"></video>';
|
||||
|
||||
var vid = document.querySelector('#test_vid_id');
|
||||
|
||||
var player = videojs(vid);
|
||||
ok(player, 'created player from tag');
|
||||
ok(player.id() === 'test_vid_id');
|
||||
ok(videojs.getPlayers()['test_vid_id'] === player, 'added player to global reference');
|
||||
|
||||
var playerAgain = videojs(vid);
|
||||
ok(player === playerAgain, 'did not create a second player from same tag');
|
||||
|
||||
equal(player, playerAgain, 'we did not make a new player');
|
||||
|
||||
var tag2 = document.getElementById('test_vid_id2');
|
||||
var player2 = videojs(tag2, { techOrder: ['techFaker'] });
|
||||
ok(player2.id() === 'test_vid_id2', 'created player from element');
|
||||
});
|
||||
|
||||
test('should return a video player instance from el techfaker', function() {
|
||||
var fixture = document.getElementById('qunit-fixture');
|
||||
fixture.innerHTML += '<video id="test_vid_id"></video><video id="test_vid_id2"></video>';
|
||||
|
||||
var vid = document.querySelector('#test_vid_id');
|
||||
|
||||
var player = videojs(vid, {techOrder: ['techFaker']});
|
||||
ok(player, 'created player from tag');
|
||||
ok(player.id() === 'test_vid_id');
|
||||
ok(videojs.getPlayers()['test_vid_id'] === player, 'added player to global reference');
|
||||
|
||||
var playerAgain = videojs(vid);
|
||||
ok(player === playerAgain, 'did not create a second player from same tag');
|
||||
|
||||
equal(player, playerAgain, 'we did not make a new player');
|
||||
|
||||
var tag2 = document.getElementById('test_vid_id2');
|
||||
var player2 = videojs(tag2, { techOrder: ['techFaker'] });
|
||||
ok(player2.id() === 'test_vid_id2', 'created player from element');
|
||||
@@ -130,7 +86,6 @@ test('should expose DOM functions', function() {
|
||||
let methods = {
|
||||
isEl: 'isEl',
|
||||
isTextNode: 'isTextNode',
|
||||
createEl: 'createEl',
|
||||
hasClass: 'hasElClass',
|
||||
addClass: 'addElClass',
|
||||
removeClass: 'removeElClass',
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário