Comparar commits

..

22 Commits

Autor SHA1 Mensagem Data
Gary Katsevman b80ae36681 v5.8.2 dist 2016-03-09 14:28:27 -05:00
Gary Katsevman 3367b007a2 v5.8.2 2016-03-09 14:27:53 -05:00
Gary Katsevman feb7e26211 @gkatsev fixed chapters menu. Fixes #3062. closes #3163 2016-03-09 14:26:07 -05:00
Gary Katsevman 5a5b42f2a7 v5.8.1 2016-03-07 15:26:26 -05:00
Owen Edwards f82a3d148f @OwenEdwards fixed menu closing on ios, specifically ipad. closes #3158 2016-03-07 15:25:12 -05:00
Can Küçükyılmaz 21051534f3 @defli fixed typo and updated Turkish translations. closes #3156 2016-03-07 15:14:58 -05:00
Can Küçükyılmaz f4bc3c12b5 @defli added missing var to sandbox index.html example. closes #3155 2016-03-07 14:58:02 -05:00
brandonocasey c1112b74fe @BrandonOCasey updated text track unit tests to use full es6 syntax. closes #3148 2016-03-07 14:54:32 -05:00
Gary Katsevman f77bcc95d0 @gkatsev cleared waiting/spinner on timeupdate. Fixes #3124. closes #3138 2016-03-07 14:48:15 -05:00
brandonocasey cb3d709237 @BrandonOCasey converted remaining text-track modules to ES6. closes #3130 2016-02-29 11:08:38 -05:00
Gary Katsevman d9a0a4503c @gkatsev updated videojs badges in the README. closes #3134 2016-02-24 01:25:04 -05:00
Gary Katsevman 3ef88f8b80 v5.8.0 2016-02-19 14:18:37 -05:00
Pat O'Neill 80c6c16a2f @misteroneill added alt css as video-js-cdn.css. closes #3118 2016-02-19 14:17:47 -05:00
mister-ben e12ca69306 @mister-ben Added en.json as localization template. closes #3096 2016-02-19 12:18:27 -05:00
jforbes d8ba649549 @forbesjo updated track settings to not fail restoring settings when localStorage is not available. closes #3120 2016-02-19 12:15:41 -05:00
Quentin Burny 0490728321 @Naouak updated time display to not change if values do not change. closes #3101 2016-02-19 12:04:06 -05:00
jforbes dd1f2b5c25 @forbesjo updated travis to use latest firefox. closes #3112 2016-02-19 11:51:42 -05:00
Nima Saberi 47a307b773 @Nipoto added fa.json (farsi/persian lang file). closes #3116 2016-02-19 11:48:54 -05:00
Gary Katsevman 050f23d913 @gkatsev added issue and PR templates for github. closes #3117 2016-02-18 17:19:55 -05:00
Gary Katsevman b027603a6a v5.7.1 2016-02-11 17:13:33 -05:00
Gary Katsevman a2f5430a5d @gkatsev fixed minified videojs in IE8. Fixes #3064 and #3070. closes #3104 2016-02-11 17:04:30 -05:00
alex-phillips acd775f551 @alex-phillips fixed reference to videojs-vtt.js dependency. closes #3080 2016-02-11 16:59:38 -05:00
54 arquivos alterados com 3459 adições e 1672 exclusões
+2
Ver Arquivo
@@ -23,3 +23,5 @@ sudo: false
cache:
directories:
- node_modules
addons:
firefox: latest
+25
Ver Arquivo
@@ -6,6 +6,31 @@ _(none)_
--------------------
## 5.8.2 (2016-03-09)
* @gkatsev fixed chapters menu. Fixes #3062 ([view](https://github.com/videojs/video.js/pull/3163))
## 5.8.1 (2016-03-07)
* @gkatsev updated videojs badges in the README ([view](https://github.com/videojs/video.js/pull/3134))
* @BrandonOCasey converted remaining text-track modules to ES6 ([view](https://github.com/videojs/video.js/pull/3130))
* @gkatsev cleared waiting/spinner on timeupdate. Fixes #3124 ([view](https://github.com/videojs/video.js/pull/3138))
* @BrandonOCasey updated text track unit tests to use full es6 syntax ([view](https://github.com/videojs/video.js/pull/3148))
* @defli added missing var to sandbox index.html example ([view](https://github.com/videojs/video.js/pull/3155))
* @defli fixed typo and updated Turkish translations ([view](https://github.com/videojs/video.js/pull/3156))
* @OwenEdwards fixed menu closing on ios, specifically ipad ([view](https://github.com/videojs/video.js/pull/3158))
## 5.8.0 (2016-02-19)
* @gkatsev added issue and PR templates for github ([view](https://github.com/videojs/video.js/pull/3117))
* @Nipoto added fa.json (farsi/persian lang file) ([view](https://github.com/videojs/video.js/pull/3116))
* @forbesjo updated travis to use latest firefox ([view](https://github.com/videojs/video.js/pull/3112))
* @Naouak updated time display to not change if values do not change ([view](https://github.com/videojs/video.js/pull/3101))
* @forbesjo updated track settings to not fail restoring settings when localStorage is not available ([view](https://github.com/videojs/video.js/pull/3120))
* @mister-ben Added en.json as localization template ([view](https://github.com/videojs/video.js/pull/3096))
* @misteroneill added alt css as video-js-cdn.css ([view](https://github.com/videojs/video.js/pull/3118))
## 5.7.1 (2016-02-11)
* @alex-phillips fixed reference to videojs-vtt.js dependency ([view](https://github.com/videojs/video.js/pull/3080))
* @gkatsev fixed minified videojs in IE8. Fixes #3064 and #3070 ([view](https://github.com/videojs/video.js/pull/3104))
## 5.7.0 (2016-02-04)
* @forbesjo updated emulated tracks to have listeners removed when they are removed ([view](https://github.com/videojs/video.js/pull/3046))
* @incompl improved the UX of time tooltips ([view](https://github.com/videojs/video.js/pull/3060))
+32
Ver Arquivo
@@ -0,0 +1,32 @@
## Description
Briefly describe the issue.
Include a [reduced test case](https://css-tricks.com/reduced-test-cases/), we have a [starter template](http://jsbin.com/axedog/edit?html,output) on JSBin you can use.
## Steps to reproduce
Explain in detail the exact steps necessary to reproduce the issue.
1.
2.
3.
## Results
### Expected
Please describe what you expected to see.
### Actual
Please describe what actually happened.
### Error output
If there are any errors at all, please include them here.
## Additional Information
Please include any additional information necessary here. Including the following:
### versions
#### videojs
what version of videojs does this occur with?
#### browsers
what browser are affected?
#### OSes
what platforms (operating systems and devices) are affected?
### plugins
are any videojs plugins being used on the page? If so, please list them below.
+16
Ver Arquivo
@@ -0,0 +1,16 @@
## Description
Please describe the change as necessary.
If it's a feature or enhancement please be as detailed as possible.
If it's a bug fix, please link the issue that it fixes or describe the bug in as much detail.
## Specific Changes proposed
Please list the specific changes involved in this pull request.
## Requirements Checklist
- [ ] Feature implemented / Bug fixed
- [ ] If necessary, more likely in a feature request than a bug fix
- [ ] Unit Tests updated or fixed
- [ ] Docs/guides updated
- [ ] Example created ([starter template on JSBin](http://jsbin.com/axedog/edit?html,output))
- [ ] Reviewed by Two Core Contributors
+5 -1
Ver Arquivo
@@ -1,6 +1,10 @@
![Video.js logo](http://videojs.com/img/logo.png)
# [Video.js - HTML5 Video Player](http://videojs.com) [![Build Status](https://travis-ci.org/videojs/video.js.svg?branch=master)](https://travis-ci.org/videojs/video.js)
# [Video.js - HTML5 Video Player](http://videojs.com)
[![Build Status](https://travis-ci.org/videojs/video.js.svg?branch=master)](https://travis-ci.org/videojs/video.js)
[![Coverage Status](https://coveralls.io/repos/github/videojs/video.js/badge.svg?branch=master)](https://coveralls.io/github/videojs/video.js?branch=master)
[![NPM](https://nodei.co/npm/video.js.png?downloads=true&downloadRank=true)](https://nodei.co/npm/video.js/)
> Video.js is a web video player built from the ground up for an HTML5 world. It supports HTML5 and Flash video, as well as YouTube and Vimeo (through [plugins](https://github.com/videojs/video.js/wiki/Plugins)). It supports video playback on desktops and mobile devices. This project was started mid 2010, and the player is now used on over ~~50,000~~ ~~100,000~~ 200,000 websites.
+8 -3
Ver Arquivo
@@ -149,6 +149,10 @@ module.exports = function(grunt) {
},
dist: {},
watch: {
minify: {
files: ['build/temp/video.js'],
tasks: ['uglify']
},
skin: {
files: ['src/css/**/*'],
tasks: ['sass', 'wrapcodepoints']
@@ -188,7 +192,7 @@ module.exports = function(grunt) {
minify: {
expand: true,
cwd: 'build/temp/',
src: ['video-js.css'],
src: ['video-js.css', 'alt/video-js-cdn.css'],
dest: 'build/temp/',
ext: '.min.css'
}
@@ -196,7 +200,8 @@ module.exports = function(grunt) {
sass: {
build: {
files: {
'build/temp/video-js.css': 'src/css/vjs.scss'
'build/temp/video-js.css': 'src/css/vjs.scss',
'build/temp/alt/video-js-cdn.css': 'src/css/vjs-cdn.scss'
}
}
},
@@ -396,7 +401,7 @@ module.exports = function(grunt) {
options: {
separator: '\n',
},
src: ['build/temp/video.js', 'node_modules/vtt.js/dist/vtt.js'],
src: ['build/temp/video.js', 'node_modules/videojs-vtt.js/dist/vtt.js'],
dest: 'build/temp/video.js',
},
},
+1 -1
Ver Arquivo
@@ -1,7 +1,7 @@
{
"name": "video.js",
"description": "An HTML5 and Flash video player with a common API and skin for both.",
"version": "5.7.0",
"version": "5.8.2",
"keywords": [
"videojs",
"html5",
+1235
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+543 -429
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+8 -7
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+9 -1
Ver Arquivo
@@ -22,5 +22,13 @@ videojs.addLanguage("de",{
"A network error caused the media download to fail part-way.": "Der Videodownload ist aufgrund eines Netzwerkfehlers fehlgeschlagen.",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Das Video konnte nicht geladen werden, da entweder ein Server- oder Netzwerkfehler auftrat oder das Format nicht unterstützt wird.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Die Videowiedergabe wurde entweder wegen eines Problems mit einem beschädigten Video oder wegen verwendeten Funktionen, die vom Browser nicht unterstützt werden, abgebrochen.",
"No compatible source was found for this media.": "Für dieses Video wurde keine kompatible Quelle gefunden."
"No compatible source was found for this media.": "Für dieses Video wurde keine kompatible Quelle gefunden.",
"Play video": "Video abspielen",
"Close": "Schließen",
"Modal Window": "Modales Fenster",
"This is a modal window": "Dies ist ein modales Fenster",
"This modal can be closed by pressing the Escape key or activating the close button.": "Durch Drücken der Esc-Taste bzw. Betätigung der Schaltfläche \"Schließen\" wird dieses modale Fenster geschlossen.",
", opens captions settings dialog": ", öffnet Einstellungen für Untertitel",
", opens subtitles settings dialog": ", öffnet Einstellungen für Untertitel",
", selected": " (ausgewählt)"
});
+34
Ver Arquivo
@@ -0,0 +1,34 @@
videojs.addLanguage("en",{
"Play": "Play",
"Pause": "Pause",
"Current Time": "Current Time",
"Duration Time": "Duration Time",
"Remaining Time": "Remaining Time",
"Stream Type": "Stream Type",
"LIVE": "LIVE",
"Loaded": "Loaded",
"Progress": "Progress",
"Fullscreen": "Fullscreen",
"Non-Fullscreen": "Non-Fullscreen",
"Mute": "Mute",
"Unmute": "Unmute",
"Playback Rate": "Playback Rate",
"Subtitles": "Subtitles",
"subtitles off": "subtitles off",
"Captions": "Captions",
"captions off": "captions off",
"Chapters": "Chapters",
"You aborted the media playback": "You aborted the media playback",
"A network error caused the media download to fail part-way.": "A network error caused the media download to fail part-way.",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "The media could not be loaded, either because the server or network failed or because the format is not supported.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.",
"No compatible source was found for this media.": "No compatible source was found for this media.",
"Play video": "Play video",
"Close": "Close",
"Modal Window": "Modal Window",
"This is a modal window": "This is a modal window",
"This modal can be closed by pressing the Escape key or activating the close button.": "This modal can be closed by pressing the Escape key or activating the close button.",
", opens captions settings dialog": ", opens captions settings dialog",
", opens subtitles settings dialog": ", opens subtitles settings dialog",
", selected": ", selected"
});
+26
Ver Arquivo
@@ -0,0 +1,26 @@
videojs.addLanguage("fa",{
"Play": "پخش",
"Pause": "وقفه",
"Current Time": "زمان کنونی",
"Duration Time": "مدت زمان",
"Remaining Time": "زمان باقیمانده",
"Stream Type": "نوع استریم",
"LIVE": "زنده",
"Loaded": "فراخوانی شده",
"Progress": "پیشرفت",
"Fullscreen": "تمام صفحه",
"Non-Fullscreen": "نمایش عادی",
"Mute": "بی صدا",
"Unmute": "بهمراه صدا",
"Playback Rate": "سرعت پخش",
"Subtitles": "زیرنویس",
"subtitles off": "بدون زیرنویس",
"Captions": "عنوان",
"captions off": "بدون عنوان",
"Chapters": "فصل",
"You aborted the media playback": "شما پخش را متوقف کردید.",
"A network error caused the media download to fail part-way.": "مشکل در دریافت ویدئو ...",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "فرمت پشتیبانی نمیشود یا خطایی روی داده است.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "مشکل در دریافت ویدئو ...",
"No compatible source was found for this media.": "هیچ ورودی ای برای این رسانه شناسایی نشد."
});
+10 -2
Ver Arquivo
@@ -14,7 +14,7 @@ videojs.addLanguage("tr",{
"Unmute": "Ses Aç",
"Playback Rate": "Oynatma Hızı",
"Subtitles": "Altyazı",
"subtitles off": "Altyazı Kapat",
"subtitles off": "Altyazı Kapalı",
"Captions": "Ek Açıklamalar",
"captions off": "Ek Açıklamalar Kapalı",
"Chapters": "Bölümler",
@@ -22,5 +22,13 @@ videojs.addLanguage("tr",{
"A network error caused the media download to fail part-way.": "Video indirilirken bağlantı sorunu oluştu.",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video oynatılamadı, ağ ya da sunucu hatası veya belirtilen format desteklenmiyor.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Tarayıcınız desteklemediği için videoda hata oluştu.",
"No compatible source was found for this media.": "Video için kaynak bulunamadı."
"No compatible source was found for this media.": "Video için kaynak bulunamadı.",
"Play video": "Videoyu Oynat",
"Close": "Kapat",
"Modal Window": "Modal Penceresi",
"This is a modal window": "Bu bir modal penceresidir",
"This modal can be closed by pressing the Escape key or activating the close button.": "Bu modal ESC tuşuna basarak ya da kapata tıklanarak kapatılabilir.",
", opens captions settings dialog": ", ek açıklama ayarları menüsünü açar",
", opens subtitles settings dialog": ", altyazı ayarları menüsünü açar",
", selected": ", seçildi"
});
Arquivo binário não exibido.
+1 -5
Ver Arquivo
@@ -475,7 +475,7 @@ body.vjs-full-window {
bottom: 1.5em;
max-height: 15em; }
.vjs-menu-button-popup:hover .vjs-menu,
.vjs-workinghover .vjs-menu-button-popup:hover .vjs-menu,
.vjs-menu-button-popup .vjs-menu.vjs-lock-showing {
display: block; }
@@ -1128,10 +1128,6 @@ video::-webkit-media-text-track-display {
100% {
border-top-color: #73859f; } }
.vjs-chapters-button .vjs-menu {
left: -10em;
width: 0; }
.vjs-chapters-button .vjs-menu ul {
width: 24em; }
+1 -1
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+543 -429
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+12 -12
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+9 -8
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+1 -1
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+6 -2
Ver Arquivo
@@ -5,7 +5,11 @@ Multiple language support allows for users of non-English locales to natively in
Creating the Language File
--------------------------
Video.js uses key/value object dictionaries in JSON form. A sample dictionary for Spanish `['es']` would look as follows;
Video.js uses key/value object dictionaries in JSON form.
An English lang file is at [/lang/en.json](https://github.com/videojs/video.js/tree/master/lang/en.json) which should be used as a template for new files. This will be kept up to date with strings in the core player that need localizations.
A sample dictionary for Spanish `['es']` would look as follows:
```JSON
{
@@ -38,7 +42,7 @@ Video.js uses key/value object dictionaries in JSON form. A sample dictionary fo
Notes:
- The file name should always be in the format `XX.json`, where `XX` is the two letter value of the language reported to the browser (for options see the bottom of this document).
- The file name should always be in the format `XX.json`, where `XX` is the language code. This should be a two letter code (for options see the bottom of this document) except for cases where a more specific code with sub-code is appropriate, e.g. `zh-CN.lang`.
- For automatic inclusion at build time, add your language file to the `/lang` directory (see 'Adding Languages to Video.js below').
Adding Languages to Video.js
+9 -1
Ver Arquivo
@@ -22,5 +22,13 @@
"A network error caused the media download to fail part-way.": "Der Videodownload ist aufgrund eines Netzwerkfehlers fehlgeschlagen.",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Das Video konnte nicht geladen werden, da entweder ein Server- oder Netzwerkfehler auftrat oder das Format nicht unterstützt wird.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Die Videowiedergabe wurde entweder wegen eines Problems mit einem beschädigten Video oder wegen verwendeten Funktionen, die vom Browser nicht unterstützt werden, abgebrochen.",
"No compatible source was found for this media.": "Für dieses Video wurde keine kompatible Quelle gefunden."
"No compatible source was found for this media.": "Für dieses Video wurde keine kompatible Quelle gefunden.",
"Play video": "Video abspielen",
"Close": "Schließen",
"Modal Window": "Modales Fenster",
"This is a modal window": "Dies ist ein modales Fenster",
"This modal can be closed by pressing the Escape key or activating the close button.": "Durch Drücken der Esc-Taste bzw. Betätigung der Schaltfläche \"Schließen\" wird dieses modale Fenster geschlossen.",
", opens captions settings dialog": ", öffnet Einstellungen für Untertitel",
", opens subtitles settings dialog": ", öffnet Einstellungen für Untertitel",
", selected": " (ausgewählt)"
}
+34
Ver Arquivo
@@ -0,0 +1,34 @@
{
"Play": "Play",
"Pause": "Pause",
"Current Time": "Current Time",
"Duration Time": "Duration Time",
"Remaining Time": "Remaining Time",
"Stream Type": "Stream Type",
"LIVE": "LIVE",
"Loaded": "Loaded",
"Progress": "Progress",
"Fullscreen": "Fullscreen",
"Non-Fullscreen": "Non-Fullscreen",
"Mute": "Mute",
"Unmute": "Unmute",
"Playback Rate": "Playback Rate",
"Subtitles": "Subtitles",
"subtitles off": "subtitles off",
"Captions": "Captions",
"captions off": "captions off",
"Chapters": "Chapters",
"You aborted the media playback": "You aborted the media playback",
"A network error caused the media download to fail part-way.": "A network error caused the media download to fail part-way.",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "The media could not be loaded, either because the server or network failed or because the format is not supported.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.",
"No compatible source was found for this media.": "No compatible source was found for this media.",
"Play video": "Play video",
"Close": "Close",
"Modal Window": "Modal Window",
"This is a modal window": "This is a modal window",
"This modal can be closed by pressing the Escape key or activating the close button.": "This modal can be closed by pressing the Escape key or activating the close button.",
", opens captions settings dialog": ", opens captions settings dialog",
", opens subtitles settings dialog": ", opens subtitles settings dialog",
", selected": ", selected"
}
+26
Ver Arquivo
@@ -0,0 +1,26 @@
{
"Play": "پخش",
"Pause": "وقفه",
"Current Time": "زمان کنونی",
"Duration Time": "مدت زمان",
"Remaining Time": "زمان باقیمانده",
"Stream Type": "نوع استریم",
"LIVE": "زنده",
"Loaded": "فراخوانی شده",
"Progress": "پیشرفت",
"Fullscreen": "تمام صفحه",
"Non-Fullscreen": "نمایش عادی",
"Mute": "بی صدا",
"Unmute": "بهمراه صدا",
"Playback Rate": "سرعت پخش",
"Subtitles": "زیرنویس",
"subtitles off": "بدون زیرنویس",
"Captions": "عنوان",
"captions off": "بدون عنوان",
"Chapters": "فصل",
"You aborted the media playback": "شما پخش را متوقف کردید.",
"A network error caused the media download to fail part-way.": "مشکل در دریافت ویدئو ...",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "فرمت پشتیبانی نمیشود یا خطایی روی داده است.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "مشکل در دریافت ویدئو ...",
"No compatible source was found for this media.": "هیچ ورودی ای برای این رسانه شناسایی نشد."
}
+10 -2
Ver Arquivo
@@ -14,7 +14,7 @@
"Unmute": "Ses Aç",
"Playback Rate": "Oynatma Hızı",
"Subtitles": "Altyazı",
"subtitles off": "Altyazı Kapat",
"subtitles off": "Altyazı Kapalı",
"Captions": "Ek Açıklamalar",
"captions off": "Ek Açıklamalar Kapalı",
"Chapters": "Bölümler",
@@ -22,5 +22,13 @@
"A network error caused the media download to fail part-way.": "Video indirilirken bağlantı sorunu oluştu.",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video oynatılamadı, ağ ya da sunucu hatası veya belirtilen format desteklenmiyor.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Tarayıcınız desteklemediği için videoda hata oluştu.",
"No compatible source was found for this media.": "Video için kaynak bulunamadı."
"No compatible source was found for this media.": "Video için kaynak bulunamadı.",
"Play video": "Videoyu Oynat",
"Close": "Kapat",
"Modal Window": "Modal Penceresi",
"This is a modal window": "Bu bir modal penceresidir",
"This modal can be closed by pressing the Escape key or activating the close button.": "Bu modal ESC tuşuna basarak ya da kapata tıklanarak kapatılabilir.",
", opens captions settings dialog": ", ek açıklama ayarları menüsünü açar",
", opens subtitles settings dialog": ", altyazı ayarları menüsünü açar",
", selected": ", seçildi"
}
+1 -1
Ver Arquivo
@@ -1,7 +1,7 @@
{
"name": "video.js",
"description": "An HTML5 and Flash video player with a common API and skin for both.",
"version": "5.7.0",
"version": "5.8.2",
"copyright": "Copyright Brightcove, Inc. <https://www.brightcove.com/>",
"license": "Apache-2.0",
"keywords": [
+1 -1
Ver Arquivo
@@ -37,7 +37,7 @@
</video>
<script>
vid = document.getElementById("vid1");
var vid = document.getElementById("vid1");
</script>
</body>
-5
Ver Arquivo
@@ -2,11 +2,6 @@
@extend .vjs-icon-chapters;
}
.vjs-chapters-button .vjs-menu {
left: -10em; // (Width of vjs-menu - width of vjs-control) / 2
width: 0;
}
.vjs-chapters-button .vjs-menu ul {
width: 24em;
}
+1 -1
Ver Arquivo
@@ -19,7 +19,7 @@
max-height: 15em;
}
.vjs-menu-button-popup:hover .vjs-menu,
.vjs-workinghover .vjs-menu-button-popup:hover .vjs-menu,
.vjs-menu-button-popup .vjs-menu.vjs-lock-showing {
display: block;
}
+3
Ver Arquivo
@@ -0,0 +1,3 @@
$icon-font-path: '//vjs.zencdn.net/font/1.5.1';
@import 'video-js';
@@ -90,11 +90,13 @@ class ChaptersButton extends TextTrackButton {
let menu = this.menu;
if (menu === undefined) {
menu = new Menu(this.player_);
menu.contentEl().appendChild(Dom.createEl('li', {
let title = Dom.createEl('li', {
className: 'vjs-menu-title',
innerHTML: toTitleCase(this.kind_),
tabIndex: -1
}));
});
menu.children_.unshift(title);
Dom.insertElFirst(title, menu.contentEl());
}
if (chaptersTrack && chaptersTrack.cues == null) {
@@ -55,7 +55,10 @@ class CurrentTimeDisplay extends Component {
let time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
let localizedText = this.localize('Current Time');
let formattedTime = formatTime(time, this.player_.duration());
this.contentEl_.innerHTML = `<span class="vjs-control-text">${localizedText}</span> ${formattedTime}`;
if (formattedTime !== this.formattedTime_) {
this.formattedTime_ = formattedTime;
this.contentEl_.innerHTML = `<span class="vjs-control-text">${localizedText}</span> ${formattedTime}`;
}
}
}
@@ -58,7 +58,8 @@ class DurationDisplay extends Component {
*/
updateContent() {
let duration = this.player_.duration();
if (duration) {
if (duration && this.duration_ !== duration) {
this.duration_ = duration;
let localizedText = this.localize('Duration Time');
let formattedTime = formatTime(duration);
this.contentEl_.innerHTML = `<span class="vjs-control-text">${localizedText}</span> ${formattedTime}`; // label the duration time for screen reader users
@@ -54,7 +54,10 @@ class RemainingTimeDisplay extends Component {
if (this.player_.duration()) {
const localizedText = this.localize('Remaining Time');
const formattedTime = formatTime(this.player_.remainingTime());
this.contentEl_.innerHTML = `<span class="vjs-control-text">${localizedText}</span> -${formattedTime}`;
if (formattedTime !== this.formattedTime_) {
this.formattedTime_ = formattedTime;
this.contentEl_.innerHTML = `<span class="vjs-control-text">${localizedText}</span> -${formattedTime}`;
}
}
// Allows for smooth scrubbing, when player can't keep up.
+4 -2
Ver Arquivo
@@ -70,11 +70,13 @@ class MenuButton extends ClickableComponent {
// Add a title list item to the top
if (this.options_.title) {
menu.contentEl().appendChild(Dom.createEl('li', {
let title = Dom.createEl('li', {
className: 'vjs-menu-title',
innerHTML: toTitleCase(this.options_.title),
tabIndex: -1
}));
});
menu.children_.unshift(title);
Dom.insertElFirst(title, menu.contentEl());
}
this.items = this['createItems']();
+6
Ver Arquivo
@@ -196,6 +196,11 @@ class Player extends Component {
// this.addClass('vjs-touch-enabled');
// }
// iOS Safari has broken hover handling
if (!browser.IS_IOS) {
this.addClass('vjs-workinghover');
}
// Make player easily findable by ID
Player.players[this.id_] = this;
@@ -812,6 +817,7 @@ class Player extends Component {
handleTechWaiting_() {
this.addClass('vjs-waiting');
this.trigger('waiting');
this.one('timeupdate', () => this.removeClass('vjs-waiting'));
}
/**
+78 -56
Ver Arquivo
@@ -4,7 +4,8 @@
import * as browser from '../utils/browser.js';
import document from 'global/document';
/*
/**
* A List of text track cues as defined in:
* https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist
*
* interface TextTrackCueList {
@@ -12,72 +13,93 @@ import document from 'global/document';
* getter TextTrackCue (unsigned long index);
* TextTrackCue? getCueById(DOMString id);
* };
*
* @param {Array} cues A list of cues to be initialized with
* @class TextTrackCueList
*/
let TextTrackCueList = function(cues) {
let list = this;
class TextTrackCueList {
constructor(cues) {
let list = this;
if (browser.IS_IE8) {
list = document.createElement('custom');
if (browser.IS_IE8) {
list = document.createElement('custom');
for (let prop in TextTrackCueList.prototype) {
if (prop !== 'constructor') {
list[prop] = TextTrackCueList.prototype[prop];
for (let prop in TextTrackCueList.prototype) {
if (prop !== 'constructor') {
list[prop] = TextTrackCueList.prototype[prop];
}
}
}
TextTrackCueList.prototype.setCues_.call(list, cues);
Object.defineProperty(list, 'length', {
get() {
return this.length_;
}
});
if (browser.IS_IE8) {
return list;
}
}
/**
* A setter for cues in this list
*
* @param {Array} cues an array of cues
* @method setCues_
* @private
*/
setCues_(cues) {
let oldLength = this.length || 0;
let i = 0;
let l = cues.length;
this.cues_ = cues;
this.length_ = cues.length;
let defineProp = function(index) {
if (!('' + index in this)) {
Object.defineProperty(this, '' + index, {
get() {
return this.cues_[index];
}
});
}
};
if (oldLength < l) {
i = oldLength;
for (; i < l; i++) {
defineProp.call(this, i);
}
}
}
TextTrackCueList.prototype.setCues_.call(list, cues);
/**
* Get a cue that is currently in the Cue list by id
*
* @param {String} id
* @method getCueById
* @return {Object} a single cue
*/
getCueById(id) {
let result = null;
Object.defineProperty(list, 'length', {
get: function() {
return this.length_;
for (let i = 0, l = this.length; i < l; i++) {
let cue = this[i];
if (cue.id === id) {
result = cue;
break;
}
}
});
if (browser.IS_IE8) {
return list;
return result;
}
};
TextTrackCueList.prototype.setCues_ = function(cues) {
let oldLength = this.length || 0;
let i = 0;
let l = cues.length;
this.cues_ = cues;
this.length_ = cues.length;
let defineProp = function(i) {
if (!(''+i in this)) {
Object.defineProperty(this, '' + i, {
get: function() {
return this.cues_[i];
}
});
}
};
if (oldLength < l) {
i = oldLength;
for(; i < l; i++) {
defineProp.call(this, i);
}
}
};
TextTrackCueList.prototype.getCueById = function(id) {
let result = null;
for (let i = 0, l = this.length; i < l; i++) {
let cue = this[i];
if (cue.id === id) {
result = cue;
break;
}
}
return result;
};
}
export default TextTrackCueList;
+25 -13
Ver Arquivo
@@ -1,27 +1,39 @@
/**
* @file text-track-enums.js
*
*/
/**
* https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode
*
* enum TextTrackMode { "disabled", "hidden", "showing" };
*/
var TextTrackMode = {
'disabled': 'disabled',
'hidden': 'hidden',
'showing': 'showing'
const TextTrackMode = {
disabled: 'disabled',
hidden: 'hidden',
showing: 'showing'
};
/*
/**
* https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackkind
*
* enum TextTrackKind { "subtitles", "captions", "descriptions", "chapters", "metadata" };
* enum TextTrackKind {
* "subtitles",
* "captions",
* "descriptions",
* "chapters",
* "metadata"
* };
*/
var TextTrackKind = {
'subtitles': 'subtitles',
'captions': 'captions',
'descriptions': 'descriptions',
'chapters': 'chapters',
'metadata': 'metadata'
const TextTrackKind = {
subtitles: 'subtitles',
captions: 'captions',
descriptions: 'descriptions',
chapters: 'chapters',
metadata: 'metadata'
};
/* jshint ignore:start */
// we ignore jshint here because it does not see
// TextTrackMode or TextTrackKind as defined here somehow...
export { TextTrackMode, TextTrackKind };
/* jshint ignore:end */
+117 -102
Ver Arquivo
@@ -6,7 +6,8 @@ import * as Fn from '../utils/fn.js';
import * as browser from '../utils/browser.js';
import document from 'global/document';
/*
/**
* A text track list as defined in:
* https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist
*
* interface TextTrackList : EventTarget {
@@ -18,50 +19,140 @@ import document from 'global/document';
* attribute EventHandler onaddtrack;
* attribute EventHandler onremovetrack;
* };
*
* @param {Track[]} tracks A list of tracks to initialize the list with
* @extends EventTarget
* @class TextTrackList
*/
let TextTrackList = function(tracks) {
let list = this;
if (browser.IS_IE8) {
list = document.createElement('custom');
class TextTrackList extends EventTarget {
constructor(tracks = []) {
super();
let list = this;
for (let prop in TextTrackList.prototype) {
if (prop !== 'constructor') {
list[prop] = TextTrackList.prototype[prop];
if (browser.IS_IE8) {
list = document.createElement('custom');
for (let prop in TextTrackList.prototype) {
if (prop !== 'constructor') {
list[prop] = TextTrackList.prototype[prop];
}
}
}
}
tracks = tracks || [];
list.tracks_ = [];
list.tracks_ = [];
Object.defineProperty(list, 'length', {
get: function() {
return this.tracks_.length;
Object.defineProperty(list, 'length', {
get() {
return this.tracks_.length;
}
});
for (let i = 0; i < tracks.length; i++) {
list.addTrack_(tracks[i]);
}
});
for (let i = 0; i < tracks.length; i++) {
list.addTrack_(tracks[i]);
if (browser.IS_IE8) {
return list;
}
}
if (browser.IS_IE8) {
return list;
/**
* Add TextTrack from TextTrackList
*
* @param {TextTrack} track
* @method addTrack_
* @private
*/
addTrack_(track) {
let index = this.tracks_.length;
if (!('' + index in this)) {
Object.defineProperty(this, index, {
get() {
return this.tracks_[index];
}
});
}
track.addEventListener('modechange', Fn.bind(this, function() {
this.trigger('change');
}));
this.tracks_.push(track);
this.trigger({
track,
type: 'addtrack'
});
}
};
TextTrackList.prototype = Object.create(EventTarget.prototype);
TextTrackList.prototype.constructor = TextTrackList;
/**
* Remove TextTrack from TextTrackList
* NOTE: Be mindful of what is passed in as it may be a HTMLTrackElement
*
* @param {TextTrack} rtrack
* @method removeTrack_
* @private
*/
removeTrack_(rtrack) {
let track;
/*
for (let i = 0, l = this.length; i < l; i++) {
if (this[i] === rtrack) {
track = this[i];
if (track.off) {
track.off();
}
this.tracks_.splice(i, 1);
break;
}
}
if (!track) {
return;
}
this.trigger({
track,
type: 'removetrack'
});
}
/**
* Get a TextTrack from TextTrackList by a tracks id
*
* @param {String} id - the id of the track to get
* @method getTrackById
* @return {TextTrack}
* @private
*/
getTrackById(id) {
let result = null;
for (let i = 0, l = this.length; i < l; i++) {
let track = this[i];
if (track.id === id) {
result = track;
break;
}
}
return result;
}
}
/**
* change - One or more tracks in the track list have been enabled or disabled.
* addtrack - A track has been added to the track list.
* removetrack - A track has been removed from the track list.
*/
TextTrackList.prototype.allowedEvents_ = {
'change': 'change',
'addtrack': 'addtrack',
'removetrack': 'removetrack'
change: 'change',
addtrack: 'addtrack',
removetrack: 'removetrack'
};
// emulate attribute EventHandler support to allow for feature detection
@@ -69,80 +160,4 @@ 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)) {
Object.defineProperty(this, index, {
get: function() {
return this.tracks_[index];
}
});
}
track.addEventListener('modechange', Fn.bind(this, function() {
this.trigger('change');
}));
this.tracks_.push(track);
this.trigger({
type: 'addtrack',
track: 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 track;
for (let i = 0, l = this.length; i < l; i++) {
if (this[i] === rtrack) {
track = this[i];
if (track.off) {
track.off();
}
this.tracks_.splice(i, 1);
break;
}
}
if (!track) {
return;
}
this.trigger({
type: 'removetrack',
track: track
});
};
TextTrackList.prototype.getTrackById = function(id) {
let result = null;
for (let i = 0, l = this.length; i < l; i++) {
let track = this[i];
if (track.id === id) {
result = track;
break;
}
}
return result;
};
export default TextTrackList;
+12 -4
Ver Arquivo
@@ -158,10 +158,16 @@ class TextTrackSettings extends Component {
* @method restoreSettings
*/
restoreSettings() {
let [err, values] = safeParseTuple(window.localStorage.getItem('vjs-text-track-settings'));
let err, values;
if (err) {
log.error(err);
try {
[err, values] = safeParseTuple(window.localStorage.getItem('vjs-text-track-settings'));
if (err) {
log.error(err);
}
} catch (e) {
log.warn(e);
}
if (values) {
@@ -186,7 +192,9 @@ class TextTrackSettings extends Component {
} else {
window.localStorage.removeItem('vjs-text-track-settings');
}
} catch (e) {}
} catch (e) {
log.warn(e);
}
}
/**
+255 -254
Ver Arquivo
@@ -13,229 +13,16 @@ import window from 'global/window';
import { isCrossOrigin } from '../utils/url.js';
import XHR from 'xhr';
/*
* https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack
/**
* takes a webvtt file contents and parses it into cues
*
* interface TextTrack : EventTarget {
* readonly attribute TextTrackKind kind;
* readonly attribute DOMString label;
* readonly attribute DOMString language;
*
* readonly attribute DOMString id;
* readonly attribute DOMString inBandMetadataTrackDispatchType;
*
* attribute TextTrackMode mode;
*
* readonly attribute TextTrackCueList? cues;
* readonly attribute TextTrackCueList? activeCues;
*
* void addCue(TextTrackCue cue);
* void removeCue(TextTrackCue cue);
*
* attribute EventHandler oncuechange;
* };
* @param {String} srcContent webVTT file contents
* @param {Track} track track to addcues to
*/
let TextTrack = function(options={}) {
if (!options.tech) {
throw new Error('A tech was not provided.');
}
let tt = this;
if (browser.IS_IE8) {
tt = document.createElement('custom');
for (let prop in TextTrack.prototype) {
if (prop !== 'constructor') {
tt[prop] = TextTrack.prototype[prop];
}
}
}
tt.tech_ = options.tech;
let mode = TextTrackEnum.TextTrackMode[options['mode']] || 'disabled';
let kind = TextTrackEnum.TextTrackKind[options['kind']] || 'subtitles';
let label = options['label'] || '';
let language = options['language'] || options['srclang'] || '';
let id = options['id'] || 'vjs_text_track_' + Guid.newGUID();
if (kind === 'metadata' || kind === 'chapters') {
mode = 'hidden';
}
tt.cues_ = [];
tt.activeCues_ = [];
let cues = new TextTrackCueList(tt.cues_);
let activeCues = new TextTrackCueList(tt.activeCues_);
let changed = false;
let timeupdateHandler = Fn.bind(tt, function() {
this['activeCues'];
if (changed) {
this['trigger']('cuechange');
changed = false;
}
});
if (mode !== 'disabled') {
tt.tech_.on('timeupdate', timeupdateHandler);
}
Object.defineProperty(tt, 'kind', {
get: function() {
return kind;
},
set: Function.prototype
});
Object.defineProperty(tt, 'label', {
get: function() {
return label;
},
set: Function.prototype
});
Object.defineProperty(tt, 'language', {
get: function() {
return language;
},
set: Function.prototype
});
Object.defineProperty(tt, 'id', {
get: function() {
return id;
},
set: Function.prototype
});
Object.defineProperty(tt, 'mode', {
get: function() {
return mode;
},
set: function(newMode) {
if (!TextTrackEnum.TextTrackMode[newMode]) {
return;
}
mode = newMode;
if (mode === 'showing') {
this.tech_.on('timeupdate', timeupdateHandler);
}
this.trigger('modechange');
}
});
Object.defineProperty(tt, 'cues', {
get: function() {
if (!this.loaded_) {
return null;
}
return cues;
},
set: Function.prototype
});
Object.defineProperty(tt, 'activeCues', {
get: function() {
if (!this.loaded_) {
return null;
}
if (this['cues'].length === 0) {
return activeCues; // nothing to do
}
let ct = this.tech_.currentTime();
let active = [];
for (let i = 0, l = this['cues'].length; i < l; i++) {
let cue = this['cues'][i];
if (cue['startTime'] <= ct && cue['endTime'] >= ct) {
active.push(cue);
} else if (cue['startTime'] === cue['endTime'] && cue['startTime'] <= ct && cue['startTime'] + 0.5 >= ct) {
active.push(cue);
}
}
changed = false;
if (active.length !== this.activeCues_.length) {
changed = true;
} else {
for (let i = 0; i < active.length; i++) {
if (indexOf.call(this.activeCues_, active[i]) === -1) {
changed = true;
}
}
}
this.activeCues_ = active;
activeCues.setCues_(this.activeCues_);
return activeCues;
},
set: Function.prototype
});
if (options.src) {
tt.src = options.src;
loadTrack(options.src, tt);
} else {
tt.loaded_ = true;
}
if (browser.IS_IE8) {
return tt;
}
};
TextTrack.prototype = Object.create(EventTarget.prototype);
TextTrack.prototype.constructor = TextTrack;
/*
* cuechange - One or more cues in the track have become active or stopped being active.
*/
TextTrack.prototype.allowedEvents_ = {
'cuechange': 'cuechange'
};
TextTrack.prototype.addCue = function(cue) {
let tracks = this.tech_.textTracks();
if (tracks) {
for (let i = 0; i < tracks.length; i++) {
if (tracks[i] !== this) {
tracks[i].removeCue(cue);
}
}
}
this.cues_.push(cue);
this['cues'].setCues_(this.cues_);
};
TextTrack.prototype.removeCue = function(removeCue) {
let removed = false;
for (let i = 0, l = this.cues_.length; i < l; i++) {
let cue = this.cues_[i];
if (cue === removeCue) {
this.cues_.splice(i, 1);
removed = true;
}
}
if (removed) {
this.cues.setCues_(this.cues_);
}
};
/*
* Downloading stuff happens below this point
*/
var parseCues = function(srcContent, track) {
let parser = new window.WebVTT.Parser(window, window.vttjs, window.WebVTT.StringDecoder());
const parseCues = function(srcContent, track) {
let parser = new window.WebVTT.Parser(window,
window.vttjs,
window.WebVTT.StringDecoder());
parser.oncue = function(cue) {
track.addCue(cue);
@@ -256,17 +43,24 @@ var parseCues = function(srcContent, track) {
parser.flush();
};
var loadTrack = function(src, track) {
/**
* load a track from a specifed url
*
* @param {String} src url to load track from
* @param {Track} track track to addcues to
*/
const loadTrack = function(src, track) {
let opts = {
uri: src
};
let crossOrigin = isCrossOrigin(src);
if (crossOrigin) {
opts.cors = crossOrigin;
}
XHR(opts, Fn.bind(this, function(err, response, responseBody){
XHR(opts, Fn.bind(this, function(err, response, responseBody) {
if (err) {
return log.error(err, response);
}
@@ -284,38 +78,245 @@ var loadTrack = function(src, track) {
}));
};
var indexOf = function(searchElement, fromIndex) {
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
let O = Object(this);
let len = O.length >>> 0;
if (len === 0) {
return -1;
}
let n = +fromIndex || 0;
if (Math.abs(n) === Infinity) {
n = 0;
}
if (n >= len) {
return -1;
}
let k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
while (k < len) {
if (k in O && O[k] === searchElement) {
return k;
/**
* A single text track as defined in:
* https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack
*
* interface TextTrack : EventTarget {
* readonly attribute TextTrackKind kind;
* readonly attribute DOMString label;
* readonly attribute DOMString language;
*
* readonly attribute DOMString id;
* readonly attribute DOMString inBandMetadataTrackDispatchType;
*
* attribute TextTrackMode mode;
*
* readonly attribute TextTrackCueList? cues;
* readonly attribute TextTrackCueList? activeCues;
*
* void addCue(TextTrackCue cue);
* void removeCue(TextTrackCue cue);
*
* attribute EventHandler oncuechange;
* };
*
* @param {Object=} options Object of option names and values
* @extends EventTarget
* @class TextTrack
*/
class TextTrack extends EventTarget {
constructor(options = {}) {
super();
if (!options.tech) {
throw new Error('A tech was not provided.');
}
let tt = this;
if (browser.IS_IE8) {
tt = document.createElement('custom');
for (let prop in TextTrack.prototype) {
if (prop !== 'constructor') {
tt[prop] = TextTrack.prototype[prop];
}
}
}
tt.tech_ = options.tech;
let mode = TextTrackEnum.TextTrackMode[options.mode] || 'disabled';
let kind = TextTrackEnum.TextTrackKind[options.kind] || 'subtitles';
let label = options.label || '';
let language = options.language || options.srclang || '';
let id = options.id || 'vjs_text_track_' + Guid.newGUID();
if (kind === 'metadata' || kind === 'chapters') {
mode = 'hidden';
}
tt.cues_ = [];
tt.activeCues_ = [];
let cues = new TextTrackCueList(tt.cues_);
let activeCues = new TextTrackCueList(tt.activeCues_);
let changed = false;
let timeupdateHandler = Fn.bind(tt, function() {
this.activeCues;
if (changed) {
this.trigger('cuechange');
changed = false;
}
});
if (mode !== 'disabled') {
tt.tech_.on('timeupdate', timeupdateHandler);
}
Object.defineProperty(tt, 'kind', {
get() {
return kind;
},
set() {}
});
Object.defineProperty(tt, 'label', {
get() {
return label;
},
set() {}
});
Object.defineProperty(tt, 'language', {
get() {
return language;
},
set() {}
});
Object.defineProperty(tt, 'id', {
get() {
return id;
},
set() {}
});
Object.defineProperty(tt, 'mode', {
get() {
return mode;
},
set(newMode) {
if (!TextTrackEnum.TextTrackMode[newMode]) {
return;
}
mode = newMode;
if (mode === 'showing') {
this.tech_.on('timeupdate', timeupdateHandler);
}
this.trigger('modechange');
}
});
Object.defineProperty(tt, 'cues', {
get() {
if (!this.loaded_) {
return null;
}
return cues;
},
set() {}
});
Object.defineProperty(tt, 'activeCues', {
get() {
if (!this.loaded_) {
return null;
}
// nothing to do
if (this.cues.length === 0) {
return activeCues;
}
let ct = this.tech_.currentTime();
let active = [];
for (let i = 0, l = this.cues.length; i < l; i++) {
let cue = this.cues[i];
if (cue.startTime <= ct && cue.endTime >= ct) {
active.push(cue);
} else if (cue.startTime === cue.endTime &&
cue.startTime <= ct &&
cue.startTime + 0.5 >= ct) {
active.push(cue);
}
}
changed = false;
if (active.length !== this.activeCues_.length) {
changed = true;
} else {
for (let i = 0; i < active.length; i++) {
if (this.activeCues_.indexOf(active[i]) === -1) {
changed = true;
}
}
}
this.activeCues_ = active;
activeCues.setCues_(this.activeCues_);
return activeCues;
},
set() {}
});
if (options.src) {
tt.src = options.src;
loadTrack(options.src, tt);
} else {
tt.loaded_ = true;
}
if (browser.IS_IE8) {
return tt;
}
k++;
}
return -1;
/**
* add a cue to the internal list of cues
*
* @param {Object} cue the cue to add to our internal list
* @method addCue
*/
addCue(cue) {
let tracks = this.tech_.textTracks();
if (tracks) {
for (let i = 0; i < tracks.length; i++) {
if (tracks[i] !== this) {
tracks[i].removeCue(cue);
}
}
}
this.cues_.push(cue);
this.cues.setCues_(this.cues_);
}
/**
* remvoe a cue from our internal list
*
* @param {Object} removeCue the cue to remove from our internal list
* @method removeCue
*/
removeCue(removeCue) {
let removed = false;
for (let i = 0, l = this.cues_.length; i < l; i++) {
let cue = this.cues_[i];
if (cue === removeCue) {
this.cues_.splice(i, 1);
removed = true;
}
}
if (removed) {
this.cues.setCues_(this.cues_);
}
}
}
/**
* cuechange - One or more cues in the track have become active or stopped being active.
*/
TextTrack.prototype.allowedEvents_ = {
cuechange: 'cuechange'
};
export default TextTrack;
+8
Ver Arquivo
@@ -943,3 +943,11 @@ test('player#reset loads the first item in the techOrder and then techCalls rese
equal(loadedSource, null, 'with a null source');
equal(techCallMethod, 'reset', 'we then reset the tech');
});
test('Remove waiting class on timeupdate after tech waiting', function() {
let player = TestHelpers.makePlayer();
player.tech_.trigger('waiting');
ok(/vjs-waiting/.test(player.el().className), 'vjs-waiting is added to the player el on tech waiting');
player.trigger('timeupdate');
ok(!/vjs-waiting/.test(player.el().className), 'vjs-waiting is removed from the player el on timeupdate');
});
+12 -13
Ver Arquivo
@@ -2,30 +2,29 @@ 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
const defaultTech = {
textTracks() {},
on() {},
off() {},
currentTime() {}
};
let track1 = new TextTrack({
const track1 = new TextTrack({
id: 1,
tech: defaultTech
});
let track2 = new TextTrack({
const track2 = new TextTrack({
id: 2,
tech: defaultTech
});
var genericHtmlTrackElements = [{
const genericHtmlTrackElements = [{
tech() {},
kind: 'captions',
tech: noop,
track: track1
}, {
tech() {},
kind: 'chapters',
tech: noop,
track: track2
}];
@@ -47,9 +46,9 @@ test('can get html track element by track', function() {
test('length is updated when new tracks are added or removed', function() {
let htmlTrackElementList = new HTMLTrackElementList(genericHtmlTrackElements);
htmlTrackElementList.addTrackElement_({tech: noop});
htmlTrackElementList.addTrackElement_({tech() {}});
equal(htmlTrackElementList.length, genericHtmlTrackElements.length + 1, `the length is ${genericHtmlTrackElements.length + 1}`);
htmlTrackElementList.addTrackElement_({tech: noop});
htmlTrackElementList.addTrackElement_({tech() {}});
equal(htmlTrackElementList.length, genericHtmlTrackElements.length + 2, `the length is ${genericHtmlTrackElements.length + 2}`);
htmlTrackElementList.removeTrackElement_(htmlTrackElementList.getTrackElementByTrack_(track1));
+17 -18
Ver Arquivo
@@ -2,12 +2,11 @@ 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
const defaultTech = {
textTracks() {},
on() {},
off() {},
currentTime() {}
};
q.module('HTML Track Element');
@@ -23,12 +22,12 @@ test('html track element requires a tech', function() {
});
test('can create a html track element with various properties', function() {
let kind = 'chapters',
label = 'English',
language = 'en',
src = 'http://www.example.com';
let kind = 'chapters';
let label = 'English';
let language = 'en';
let src = 'http://www.example.com';
let htmlTrackElement = new HTMLTrackElement({
let htmlTrackElement = new HTMLTrackElement({
kind,
label,
language,
@@ -36,7 +35,7 @@ test('can create a html track element with various properties', function() {
tech: defaultTech
});
equal(htmlTrackElement.default, undefined, 'we have a default');
equal(typeof 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');
@@ -46,29 +45,29 @@ test('can create a html track element with various properties', function() {
});
test('defaults when items not provided', function() {
let htmlTrackElement = new HTMLTrackElement({
let htmlTrackElement = new HTMLTrackElement({
tech: defaultTech
});
equal(htmlTrackElement.default, undefined, 'we have a default');
equal(typeof 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(typeof 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;
let changes = 0;
let loadHandler;
loadHandler = function() {
changes++;
};
let htmlTrackElement = new HTMLTrackElement({
tech: noop
tech() {}
});
htmlTrackElement.addEventListener('load', loadHandler);
+16 -16
Ver Arquivo
@@ -3,15 +3,15 @@ import TestHelpers from '../test-helpers.js';
import * as browser from '../../../src/js/utils/browser.js';
q.module('Text Track Controls', {
'setup': function() {
setup() {
this.clock = sinon.useFakeTimers();
},
'teardown': function() {
teardown() {
this.clock.restore();
}
});
var track = {
const track = {
kind: 'captions',
label: 'test'
};
@@ -30,7 +30,7 @@ test('should be displayed when text tracks list is not empty', function() {
});
test('should be displayed when a text track is added to an empty track list', function() {
var player = TestHelpers.makePlayer();
let player = TestHelpers.makePlayer();
player.addRemoteTextTrack(track);
@@ -41,7 +41,7 @@ test('should be displayed when a text track is added to an empty track list', fu
});
test('should not be displayed when text tracks list is empty', function() {
var player = TestHelpers.makePlayer();
let player = TestHelpers.makePlayer();
ok(player.controlBar.captionsButton.hasClass('vjs-hidden'), 'control is not displayed');
equal(player.textTracks().length, 0, 'textTracks is empty');
@@ -50,7 +50,7 @@ test('should not be displayed when text tracks list is empty', function() {
});
test('should not be displayed when last text track is removed', function() {
var player = TestHelpers.makePlayer({
let player = TestHelpers.makePlayer({
tracks: [track]
});
@@ -63,10 +63,10 @@ test('should not be displayed when last text track is removed', function() {
});
test('menu should contain "Settings", "Off" and one track', function() {
var player = TestHelpers.makePlayer({
tracks: [track]
}),
menuItems;
let player = TestHelpers.makePlayer({
tracks: [track]
});
let menuItems;
this.clock.tick(1000);
@@ -81,7 +81,7 @@ test('menu should contain "Settings", "Off" and one track', function() {
});
test('menu should update with addRemoteTextTrack', function() {
var player = TestHelpers.makePlayer({
let player = TestHelpers.makePlayer({
tracks: [track]
});
@@ -96,7 +96,7 @@ test('menu should update with addRemoteTextTrack', function() {
});
test('menu should update with removeRemoteTextTrack', function() {
var player = TestHelpers.makePlayer({
let player = TestHelpers.makePlayer({
tracks: [track, track]
});
@@ -115,15 +115,15 @@ if (!browser.IS_IE8) {
// However, this test tests a specific with iOS7 where the TextTrackList doesn't report track mode changes.
// TODO: figure out why this test doens't work on IE8. https://github.com/videojs/video.js/issues/1861
test('menu items should polyfill mode change events', function() {
var player = TestHelpers.makePlayer({}),
changes,
trackMenuItem;
let player = TestHelpers.makePlayer({});
let changes;
let trackMenuItem;
// emulate a TextTrackList that doesn't report track mode changes,
// like iOS7
player.textTracks().onchange = undefined;
trackMenuItem = new TextTrackMenuItem(player, {
track: track
track
});
player.textTracks().on('change', function() {
+10 -10
Ver Arquivo
@@ -1,6 +1,6 @@
import TextTrackCueList from '../../../src/js/tracks/text-track-cue-list.js';
let genericTracks = [
const genericTracks = [
{
id: '1'
}, {
@@ -13,13 +13,13 @@ let genericTracks = [
q.module('Text Track Cue List');
test('TextTrackCueList\'s length is set correctly', function() {
var ttcl = new TextTrackCueList(genericTracks);
let ttcl = new TextTrackCueList(genericTracks);
equal(ttcl.length, genericTracks.length, 'the length is ' + genericTracks.length);
});
test('can get cues by id', function() {
var ttcl = new TextTrackCueList(genericTracks);
let ttcl = new TextTrackCueList(genericTracks);
equal(ttcl.getCueById('1').id, 1, 'id "1" has id of "1"');
equal(ttcl.getCueById('2').id, 2, 'id "2" has id of "2"');
@@ -28,7 +28,7 @@ test('can get cues by id', function() {
});
test('length is updated when new tracks are added or removed', function() {
var ttcl = new TextTrackCueList(genericTracks);
let ttcl = new TextTrackCueList(genericTracks);
ttcl.setCues_(genericTracks.concat([{id: '100'}]));
equal(ttcl.length, genericTracks.length + 1, 'the length is ' + (genericTracks.length + 1));
@@ -42,9 +42,9 @@ test('length is updated when new tracks are added or removed', function() {
});
test('can access items by index', function() {
var ttcl = new TextTrackCueList(genericTracks),
i = 0,
length = ttcl.length;
let ttcl = new TextTrackCueList(genericTracks);
let i = 0;
let length = ttcl.length;
expect(length);
@@ -54,7 +54,7 @@ test('can access items by index', function() {
});
test('can access new items by index', function() {
var ttcl = new TextTrackCueList(genericTracks);
let ttcl = new TextTrackCueList(genericTracks);
ttcl.setCues_(genericTracks.concat([{id: '100'}]));
@@ -64,7 +64,7 @@ test('can access new items by index', function() {
});
test('cannot access removed items by index', function() {
var ttcl = new TextTrackCueList(genericTracks);
let ttcl = new TextTrackCueList(genericTracks);
ttcl.setCues_(genericTracks.concat([{id: '100'}, {id: '101'}]));
equal(ttcl[3].id, '100', 'id of item at index 3 is 100');
@@ -77,7 +77,7 @@ test('cannot access removed items by index', function() {
});
test('new item available at old index', function() {
var ttcl = new TextTrackCueList(genericTracks);
let ttcl = new TextTrackCueList(genericTracks);
ttcl.setCues_(genericTracks.concat([{id: '100'}]));
equal(ttcl[3].id, '100', 'id of item at index 3 is 100');
@@ -3,7 +3,6 @@ import TextTrack from '../../../src/js/tracks/text-track.js';
import TextTrackList from '../../../src/js/tracks/text-track-list.js';
import Html5 from '../../../src/js/tech/html5.js';
import document from 'global/document';
import window from 'global/window';
q.module('Text Track List Converter', {});
@@ -26,6 +25,7 @@ let cleanup = (item) => {
if (Html5.supportsNativeTextTracks()) {
q.test('trackToJson_ produces correct representation for native track object', function(a) {
let track = document.createElement('track');
track.src = 'example.com/english.vtt';
track.kind = 'captions';
track.srclang = 'en';
@@ -48,11 +48,13 @@ if (Html5.supportsNativeTextTracks()) {
});
let nativeTrack = document.createElement('track');
nativeTrack.kind = 'captions';
nativeTrack.srclang = 'es';
nativeTrack.label = 'Spanish';
let tt = new TextTrackList();
tt.addTrack_(nativeTrack.track);
tt.addTrack_(emulatedTrack);
@@ -96,12 +98,14 @@ if (Html5.supportsNativeTextTracks()) {
});
let nativeTrack = document.createElement('track');
nativeTrack.src = 'example.com/spanish.vtt';
nativeTrack.kind = 'captions';
nativeTrack.srclang = 'es';
nativeTrack.label = 'Spanish';
let tt = new TextTrackList();
tt.addTrack_(nativeTrack.track);
tt.addTrack_(emulatedTrack);
@@ -171,6 +175,7 @@ q.test('textTracksToJson produces good json output for emulated only', function(
});
let tt = new TextTrackList();
tt.addTrack_(anotherTrack);
tt.addTrack_(emulatedTrack);
@@ -224,6 +229,7 @@ q.test('jsonToTextTracks calls addRemoteTextTrack on the tech with emulated trac
});
let tt = new TextTrackList();
tt.addTrack_(anotherTrack);
tt.addTrack_(emulatedTrack);
+62 -59
Ver Arquivo
@@ -2,33 +2,32 @@ import TextTrackList from '../../../src/js/tracks/text-track-list.js';
import TextTrack from '../../../src/js/tracks/text-track.js';
import EventTarget from '../../../src/js/event-target.js';
var noop = Function.prototype;
var genericTracks = [
const genericTracks = [
{
id: '1',
addEventListener: noop,
off: noop
addEventListener() {},
off() {}
}, {
id: '2',
addEventListener: noop,
off: noop
addEventListener() {},
off() {}
}, {
id: '3',
addEventListener: noop,
off: noop
addEventListener() {},
off() {}
}
];
q.module('Text Track List');
test('TextTrackList\'s length is set correctly', function() {
var ttl = new TextTrackList(genericTracks);
let ttl = new TextTrackList(genericTracks);
equal(ttl.length, genericTracks.length, 'the length is ' + genericTracks.length);
});
test('can get text tracks by id', function() {
var ttl = new TextTrackList(genericTracks);
let ttl = new TextTrackList(genericTracks);
equal(ttl.getTrackById('1').id, 1, 'id "1" has id of "1"');
equal(ttl.getTrackById('2').id, 2, 'id "2" has id of "2"');
@@ -37,11 +36,11 @@ test('can get text tracks by id', function() {
});
test('length is updated when new tracks are added or removed', function() {
var ttl = new TextTrackList(genericTracks);
let ttl = new TextTrackList(genericTracks);
ttl.addTrack_({id: '100', addEventListener: noop, off: noop});
ttl.addTrack_({id: '100', addEventListener() {}, off() {}});
equal(ttl.length, genericTracks.length + 1, 'the length is ' + (genericTracks.length + 1));
ttl.addTrack_({id: '101', addEventListener: noop, off: noop});
ttl.addTrack_({id: '101', addEventListener() {}, off() {}});
equal(ttl.length, genericTracks.length + 2, 'the length is ' + (genericTracks.length + 2));
ttl.removeTrack_(ttl.getTrackById('101'));
@@ -51,9 +50,9 @@ test('length is updated when new tracks are added or removed', function() {
});
test('can access items by index', function() {
var ttl = new TextTrackList(genericTracks),
i = 0,
length = ttl.length;
let ttl = new TextTrackList(genericTracks);
let i = 0;
let length = ttl.length;
expect(length);
@@ -63,19 +62,19 @@ test('can access items by index', function() {
});
test('can access new items by index', function() {
var ttl = new TextTrackList(genericTracks);
let ttl = new TextTrackList(genericTracks);
ttl.addTrack_({id: '100', addEventListener: noop});
ttl.addTrack_({id: '100', addEventListener() {}});
equal(ttl[3].id, '100', 'id of item at index 3 is 100');
ttl.addTrack_({id: '101', addEventListener: noop});
ttl.addTrack_({id: '101', addEventListener() {}});
equal(ttl[4].id, '101', 'id of item at index 4 is 101');
});
test('cannot access removed items by index', function() {
var ttl = new TextTrackList(genericTracks);
let ttl = new TextTrackList(genericTracks);
ttl.addTrack_({id: '100', addEventListener: noop, off: noop});
ttl.addTrack_({id: '101', addEventListener: noop, off: noop});
ttl.addTrack_({id: '100', addEventListener() {}, off() {}});
ttl.addTrack_({id: '101', addEventListener() {}, off() {}});
equal(ttl[3].id, '100', 'id of item at index 3 is 100');
equal(ttl[4].id, '101', 'id of item at index 4 is 101');
@@ -87,51 +86,55 @@ test('cannot access removed items by index', function() {
});
test('new item available at old index', function() {
var ttl = new TextTrackList(genericTracks);
let ttl = new TextTrackList(genericTracks);
ttl.addTrack_({id: '100', addEventListener: noop, off: noop});
ttl.addTrack_({id: '100', addEventListener() {}, off() {}});
equal(ttl[3].id, '100', 'id of item at index 3 is 100');
ttl.removeTrack_(ttl.getTrackById('100'));
ok(!ttl[3], 'nothing at index 3');
ttl.addTrack_({id: '101', addEventListener: noop});
ttl.addTrack_({id: '101', addEventListener() {}});
equal(ttl[3].id, '101', 'id of new item at index 3 is now 101');
});
test('a "addtrack" event is triggered when new tracks are added', function() {
var ttl = new TextTrackList(genericTracks),
tracks = 0,
adds = 0,
addHandler = function(e) {
e.track && tracks++;
adds++;
};
let ttl = new TextTrackList(genericTracks);
let tracks = 0;
let adds = 0;
let addHandler = function(e) {
if (e.track) {
tracks++;
}
adds++;
};
ttl.on('addtrack', addHandler);
ttl.addTrack_({id: '100', addEventListener: noop});
ttl.addTrack_({id: '101', addEventListener: noop});
ttl.addTrack_({id: '100', addEventListener() {}});
ttl.addTrack_({id: '101', addEventListener() {}});
ttl.off('addtrack', addHandler);
ttl.onaddtrack = addHandler;
ttl.addTrack_({id: '102', addEventListener: noop});
ttl.addTrack_({id: '103', addEventListener: noop});
ttl.addTrack_({id: '102', addEventListener() {}});
ttl.addTrack_({id: '103', addEventListener() {}});
equal(adds, 4, 'we got ' + adds + ' "addtrack" events');
equal(tracks, 4, 'we got a track with every event');
});
test('a "removetrack" event is triggered when tracks are removed', function() {
var ttl = new TextTrackList(genericTracks),
tracks = 0,
rms = 0,
rmHandler = function(e) {
e.track && tracks++;
rms++;
};
let ttl = new TextTrackList(genericTracks);
let tracks = 0;
let rms = 0;
let rmHandler = function(e) {
if (e.track) {
tracks++;
}
rms++;
};
ttl.on('removetrack', rmHandler);
@@ -149,12 +152,12 @@ test('a "removetrack" event is triggered when tracks are removed', function() {
});
test('trigger "change" event when "modechange" is fired on a track', function() {
var tt = new EventTarget(),
ttl = new TextTrackList([tt]),
changes = 0,
changeHandler = function() {
changes++;
};
let tt = new EventTarget();
let ttl = new TextTrackList([tt]);
let changes = 0;
let changeHandler = function() {
changes++;
};
ttl.on('change', changeHandler);
@@ -170,16 +173,16 @@ test('trigger "change" event when "modechange" is fired on a track', function()
});
test('trigger "change" event when mode changes on a TextTrack', function() {
var tt = new TextTrack({
tech: {
on: noop
}
}),
ttl = new TextTrackList([tt]),
changes = 0,
changeHandler = function() {
changes++;
};
let tt = new TextTrack({
tech: {
on() {}
}
});
let ttl = new TextTrackList([tt]);
let changes = 0;
let changeHandler = function() {
changes++;
};
ttl.on('change', changeHandler);
+67 -65
Ver Arquivo
@@ -4,33 +4,33 @@ import * as Events from '../../../src/js/utils/events.js';
import safeParseTuple from 'safe-json-parse/tuple';
import window from 'global/window';
var tracks = [{
const tracks = [{
kind: 'captions',
label: 'test'
}];
q.module('Text Track Settings', {
beforeEach: function() {
beforeEach() {
window.localStorage.clear();
}
});
test('should update settings', function() {
var player = TestHelpers.makePlayer({
tracks: tracks,
persistTextTrackSettings: true
}),
newSettings = {
'backgroundOpacity': '1',
'textOpacity': '1',
'windowOpacity': '1',
'edgeStyle': 'raised',
'fontFamily': 'monospaceSerif',
'color': '#FFF',
'backgroundColor': '#FFF',
'windowColor': '#FFF',
'fontPercent': 1.25
};
let player = TestHelpers.makePlayer({
tracks,
persistTextTrackSettings: true
});
let newSettings = {
backgroundOpacity: '1',
textOpacity: '1',
windowOpacity: '1',
edgeStyle: 'raised',
fontFamily: 'monospaceSerif',
color: '#FFF',
backgroundColor: '#FFF',
windowColor: '#FFF',
fontPercent: 1.25
};
player.textTrackSettings.setValues(newSettings);
deepEqual(player.textTrackSettings.getValues(), newSettings, 'values are updated');
@@ -52,8 +52,8 @@ test('should update settings', function() {
});
test('should restore default settings', function() {
var player = TestHelpers.makePlayer({
tracks: tracks,
let player = TestHelpers.makePlayer({
tracks,
persistTextTrackSettings: true
});
@@ -88,9 +88,10 @@ test('should restore default settings', function() {
});
test('should open on click', function() {
var player = TestHelpers.makePlayer({
tracks: tracks
let player = TestHelpers.makePlayer({
tracks
});
Events.trigger(player.$('.vjs-texttrack-settings'), 'click');
ok(!player.textTrackSettings.hasClass('vjs-hidden'), 'settings open');
@@ -98,9 +99,10 @@ test('should open on click', function() {
});
test('should close on done click', function() {
var player = TestHelpers.makePlayer({
tracks: tracks
let player = TestHelpers.makePlayer({
tracks
});
Events.trigger(player.$('.vjs-texttrack-settings'), 'click');
Events.trigger(player.$('.vjs-done-button'), 'click');
ok(player.textTrackSettings.hasClass('vjs-hidden'), 'settings closed');
@@ -109,16 +111,16 @@ test('should close on done click', function() {
});
test('if persist option is set, restore settings on init', function() {
var player,
oldRestoreSettings = TextTrackSettings.prototype.restoreSettings,
restore = 0;
let player;
let oldRestoreSettings = TextTrackSettings.prototype.restoreSettings;
let restore = 0;
TextTrackSettings.prototype.restoreSettings = function() {
restore++;
};
player = TestHelpers.makePlayer({
tracks: tracks,
tracks,
persistTextTrackSettings: true
});
@@ -130,12 +132,12 @@ test('if persist option is set, restore settings on init', function() {
});
test('if persist option is set, save settings when "done"', function() {
var player = TestHelpers.makePlayer({
tracks: tracks,
persistTextTrackSettings: true
}),
oldSaveSettings = TextTrackSettings.prototype.saveSettings,
save = 0;
let player = TestHelpers.makePlayer({
tracks,
persistTextTrackSettings: true
});
let oldSaveSettings = TextTrackSettings.prototype.saveSettings;
let save = 0;
TextTrackSettings.prototype.saveSettings = function() {
save++;
@@ -151,11 +153,11 @@ test('if persist option is set, save settings when "done"', function() {
});
test('do not try to restore or save settings if persist option is not set', function() {
var player,
oldRestoreSettings = TextTrackSettings.prototype.restoreSettings,
oldSaveSettings = TextTrackSettings.prototype.saveSettings,
save = 0,
restore = 0;
let player;
let oldRestoreSettings = TextTrackSettings.prototype.restoreSettings;
let oldSaveSettings = TextTrackSettings.prototype.saveSettings;
let save = 0;
let restore = 0;
TextTrackSettings.prototype.restoreSettings = function() {
restore++;
@@ -165,7 +167,7 @@ test('do not try to restore or save settings if persist option is not set', func
};
player = TestHelpers.makePlayer({
tracks: tracks,
tracks,
persistTextTrackSettings: false
});
@@ -183,23 +185,23 @@ test('do not try to restore or save settings if persist option is not set', func
});
test('should restore saved settings', function() {
var player,
newSettings = {
'backgroundOpacity': '1',
'textOpacity': '1',
'windowOpacity': '1',
'edgeStyle': 'raised',
'fontFamily': 'monospaceSerif',
'color': '#FFF',
'backgroundColor': '#FFF',
'windowColor': '#FFF',
'fontPercent': 1.25
};
let player;
let newSettings = {
backgroundOpacity: '1',
textOpacity: '1',
windowOpacity: '1',
edgeStyle: 'raised',
fontFamily: 'monospaceSerif',
color: '#FFF',
backgroundColor: '#FFF',
windowColor: '#FFF',
fontPercent: 1.25
};
window.localStorage.setItem('vjs-text-track-settings', JSON.stringify(newSettings));
player = TestHelpers.makePlayer({
tracks: tracks,
tracks,
persistTextTrackSettings: true
});
@@ -209,23 +211,23 @@ test('should restore saved settings', function() {
});
test('should not restore saved settings', function() {
var player,
newSettings = {
'backgroundOpacity': '1',
'textOpacity': '1',
'windowOpacity': '1',
'edgeStyle': 'raised',
'fontFamily': 'monospaceSerif',
'color': '#FFF',
'backgroundColor': '#FFF',
'windowColor': '#FFF',
'fontPercent': 1.25
};
let player;
let newSettings = {
backgroundOpacity: '1',
textOpacity: '1',
windowOpacity: '1',
edgeStyle: 'raised',
fontFamily: 'monospaceSerif',
color: '#FFF',
backgroundColor: '#FFF',
windowColor: '#FFF',
fontPercent: 1.25
};
window.localStorage.setItem('vjs-text-track-settings', JSON.stringify(newSettings));
player = TestHelpers.makePlayer({
tracks: tracks,
tracks,
persistTextTrackSettings: false
});
+52 -57
Ver Arquivo
@@ -1,39 +1,35 @@
import TextTrack from '../../../src/js/tracks/text-track.js';
import window from 'global/window';
import TestHelpers from '../test-helpers.js';
var noop = Function.prototype;
var defaultTech = {
textTracks: noop,
on: noop,
off: noop,
currentTime: noop
const defaultTech = {
textTracks() {},
on() {},
off() {},
currentTime() {}
};
q.module('Text Track');
test('text-track requires a tech', function() {
window.throws(function() {
new TextTrack();
},
new Error('A tech was not provided.'),
'a tech is required for text track');
let error = new Error('A tech was not provided.');
q.throws(() => new TextTrack(), error, 'a tech is required for text track');
});
test('can create a TextTrack with various properties', function() {
var kind = 'captions',
label = 'English',
language = 'en',
id = '1',
mode = 'disabled',
tt = new TextTrack({
tech: defaultTech,
kind: kind,
label: label,
language: language,
id: id,
mode: mode
});
let kind = 'captions';
let label = 'English';
let language = 'en';
let id = '1';
let mode = 'disabled';
let tt = new TextTrack({
kind,
label,
language,
id,
mode,
tech: defaultTech
});
equal(tt.kind, kind, 'we have a kind');
equal(tt.label, label, 'we have a label');
@@ -43,7 +39,7 @@ test('can create a TextTrack with various properties', function() {
});
test('defaults when items not provided', function() {
var tt = new TextTrack({
let tt = new TextTrack({
tech: defaultTech
});
@@ -54,7 +50,7 @@ test('defaults when items not provided', function() {
});
test('kind can only be one of several options, defaults to subtitles', function() {
var tt = new TextTrack({
let tt = new TextTrack({
tech: defaultTech,
kind: 'foo'
});
@@ -99,7 +95,7 @@ test('kind can only be one of several options, defaults to subtitles', function(
});
test('mode can only be one of several options, defaults to disabled', function() {
var tt = new TextTrack({
let tt = new TextTrack({
tech: defaultTech,
mode: 'foo'
});
@@ -130,19 +126,19 @@ test('mode can only be one of several options, defaults to disabled', function()
});
test('kind, label, language, id, cue, and activeCues are read only', function() {
var kind = 'captions',
label = 'English',
language = 'en',
id = '1',
mode = 'disabled',
tt = new TextTrack({
tech: defaultTech,
kind: kind,
label: label,
language: language,
id: id,
mode: mode
});
let kind = 'captions';
let label = 'English';
let language = 'en';
let id = '1';
let mode = 'disabled';
let tt = new TextTrack({
kind,
label,
language,
id,
mode,
tech: defaultTech
});
tt.kind = 'subtitles';
tt.label = 'Spanish';
@@ -160,8 +156,8 @@ test('kind, label, language, id, cue, and activeCues are read only', function()
});
test('mode can only be set to a few options', function() {
var tt = new TextTrack({
tech: defaultTech,
let tt = new TextTrack({
tech: defaultTech
});
tt.mode = 'foo';
@@ -185,8 +181,8 @@ test('mode can only be set to a few options', function() {
});
test('cues and activeCues return a TextTrackCueList', function() {
var tt = new TextTrack({
tech: defaultTech,
let tt = new TextTrack({
tech: defaultTech
});
ok(tt.cues.getCueById, 'cues are a TextTrackCueList');
@@ -194,14 +190,13 @@ test('cues and activeCues return a TextTrackCueList', function() {
});
test('cues can be added and removed from a TextTrack', function() {
var tt = new TextTrack({
tech: defaultTech,
}),
cues;
let tt = new TextTrack({
tech: defaultTech
});
let cues;
cues = tt.cues;
equal(cues.length, 0, 'start with zero cues');
tt.addCue({id: '1'});
@@ -220,13 +215,13 @@ test('cues can be added and removed from a TextTrack', function() {
});
test('fires cuechange when cues become active and inactive', function() {
var player = TestHelpers.makePlayer(),
changes = 0,
cuechangeHandler,
tt = new TextTrack({
tech: player.tech_,
mode: 'showing'
});
let player = TestHelpers.makePlayer();
let changes = 0;
let cuechangeHandler;
let tt = new TextTrack({
tech: player.tech_,
mode: 'showing'
});
cuechangeHandler = function() {
changes++;
+83 -83
Ver Arquivo
@@ -5,34 +5,32 @@ import CaptionsButton from '../../../src/js/control-bar/text-track-controls/capt
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';
import Tech from '../../../src/js/tech/tech.js';
import Component from '../../../src/js/component.js';
import * as browser from '../../../src/js/utils/browser.js';
import TestHelpers from '../test-helpers.js';
import document from 'global/document';
import window from 'global/window';
import TechFaker from '../tech/tech-faker.js';
q.module('Tracks', {
'setup': function() {
setup() {
this.clock = sinon.useFakeTimers();
},
'teardown': function() {
teardown() {
this.clock.restore();
}
});
test('should place title list item into ul', function() {
var player, chaptersButton;
let player;
let chaptersButton;
player = TestHelpers.makePlayer();
chaptersButton = new ChaptersButton(player);
var menuContentElement = chaptersButton.el().getElementsByTagName('UL')[0];
var titleElement = menuContentElement.children[0];
let menuContentElement = chaptersButton.el().getElementsByTagName('UL')[0];
let titleElement = menuContentElement.children[0];
ok(titleElement.innerHTML === 'Chapters', 'title element placed in ul');
@@ -40,8 +38,8 @@ test('should place title list item into ul', function() {
});
test('Player track methods call the tech', function() {
var player,
calls = 0;
let player;
let calls = 0;
player = TestHelpers.makePlayer();
@@ -61,35 +59,34 @@ test('Player track methods call the tech', function() {
});
test('TextTrackDisplay initializes tracks on player ready', function() {
var calls = 0,
ttd = new TextTrackDisplay({
on: Function.prototype,
addTextTracks: function() {
calls--;
},
getChild: function() {
calls--;
},
ready: function() {
calls++;
}
}, {});
let calls = 0;
let ttd = new TextTrackDisplay({
on() {},
addTextTracks() {
calls--;
},
getChild() {
calls--;
},
ready() {
calls++;
}
}, {});
equal(calls, 1, 'only a player.ready call was made');
});
test('listen to remove and add track events in native text tracks', function() {
var oldTestVid = Html5.TEST_VID,
player,
options,
oldTextTracks,
events = {},
html;
let oldTestVid = Html5.TEST_VID;
let player;
let options;
let oldTextTracks = Html5.prototype.textTracks;
let events = {};
let html;
oldTextTracks = Html5.prototype.textTracks;
Html5.prototype.textTracks = function() {
return {
addEventListener: function(type, handler) {
addEventListener(type, handler) {
events[type] = true;
}
};
@@ -101,17 +98,17 @@ test('listen to remove and add track events in native text tracks', function() {
player = {
// Function.prototype is a built-in no-op function.
controls: Function.prototype,
ready: Function.prototype,
options: function() {
controls() {},
ready() {},
options() {
return {};
},
addChild: Function.prototype,
id: Function.prototype,
el: function() {
addChild() {},
id() {},
el() {
return {
insertBefore: Function.prototype,
appendChild: Function.prototype
insertBefore() {},
appendChild() {}
};
}
};
@@ -120,24 +117,24 @@ test('listen to remove and add track events in native text tracks', function() {
html = new Html5(options);
ok(events['removetrack'], 'removetrack listener was added');
ok(events['addtrack'], 'addtrack listener was added');
ok(events.removetrack, 'removetrack listener was added');
ok(events.addtrack, 'addtrack listener was added');
Html5.TEST_VID = oldTestVid;
Html5.prototype.textTracks = oldTextTracks;
});
test('update texttrack buttons on removetrack or addtrack', function() {
var update = 0,
i,
player,
tag,
track,
oldTextTracks,
events = {},
oldCaptionsUpdate,
oldSubsUpdate,
oldChaptersUpdate;
let update = 0;
let i;
let player;
let tag;
let track;
let oldTextTracks;
let events = {};
let oldCaptionsUpdate;
let oldSubsUpdate;
let oldChaptersUpdate;
oldCaptionsUpdate = CaptionsButton.prototype.update;
oldSubsUpdate = SubtitlesButton.prototype.update;
@@ -155,19 +152,19 @@ test('update texttrack buttons on removetrack or addtrack', function() {
oldChaptersUpdate.call(this);
};
Tech.prototype['featuresNativeTextTracks'] = true;
Tech.prototype.featuresNativeTextTracks = true;
oldTextTracks = Tech.prototype.textTracks;
Tech.prototype.textTracks = function() {
return {
length: 0,
addEventListener: function(type, handler) {
addEventListener(type, handler) {
if (!events[type]) {
events[type] = [];
}
events[type].push(handler);
},
// Requrired in player.dispose()
removeEventListener: function(){}
removeEventListener() {}
};
};
@@ -185,26 +182,26 @@ test('update texttrack buttons on removetrack or addtrack', function() {
track.src = '#es.vtt';
tag.appendChild(track);
player = TestHelpers.makePlayer({}, tag);
player = TestHelpers.makePlayer({}, tag);
player.player_ = player;
equal(update, 3, 'update was called on the three buttons during init');
for (i = 0; i < events['removetrack'].length; i++) {
events['removetrack'][i]();
for (i = 0; i < events.removetrack.length; i++) {
events.removetrack[i]();
}
equal(update, 6, 'update was called on the three buttons for remove track');
for (i = 0; i < events['addtrack'].length; i++) {
events['addtrack'][i]();
for (i = 0; i < events.addtrack.length; i++) {
events.addtrack[i]();
}
equal(update, 9, 'update was called on the three buttons for remove track');
Tech.prototype.textTracks = oldTextTracks;
Tech.prototype['featuresNativeTextTracks'] = false;
Tech.prototype.featuresNativeTextTracks = false;
CaptionsButton.prototype.update = oldCaptionsUpdate;
SubtitlesButton.prototype.update = oldSubsUpdate;
ChaptersButton.prototype.update = oldChaptersUpdate;
@@ -213,15 +210,13 @@ test('update texttrack buttons on removetrack or addtrack', function() {
});
test('if native text tracks are not supported, create a texttrackdisplay', function() {
var oldTestVid = Html5.TEST_VID,
oldIsFirefox = browser.IS_FIREFOX,
oldTextTrackDisplay = Component.getComponent('TextTrackDisplay'),
called = false,
player,
tag,
track,
options,
html;
let oldTestVid = Html5.TEST_VID;
let oldIsFirefox = browser.IS_FIREFOX;
let oldTextTrackDisplay = Component.getComponent('TextTrackDisplay');
let called = false;
let player;
let tag;
let track;
tag = document.createElement('video');
track = document.createElement('track');
@@ -258,7 +253,7 @@ test('if native text tracks are not supported, create a texttrackdisplay', funct
});
test('html5 tech supports native text tracks if the video supports it, unless mode is a number', function() {
var oldTestVid = Html5.TEST_VID;
let oldTestVid = Html5.TEST_VID;
Html5.TEST_VID = {
textTracks: [{
@@ -272,8 +267,8 @@ test('html5 tech supports native text tracks if the video supports it, unless mo
});
test('html5 tech supports native text tracks if the video supports it, unless it is firefox', function() {
var oldTestVid = Html5.TEST_VID,
oldIsFirefox = browser.IS_FIREFOX;
let oldTestVid = Html5.TEST_VID;
let oldIsFirefox = browser.IS_FIREFOX;
Html5.TEST_VID = {
textTracks: []
@@ -308,6 +303,7 @@ if (Html5.supportsNativeTextTracks()) {
let tt = el.textTracks;
let emulatedTt = html.textTracks();
let track = document.createElement('track');
el.appendChild(track);
let addtrack = function() {
@@ -317,6 +313,7 @@ if (Html5.supportsNativeTextTracks()) {
emulatedTt.off('addtrack', addtrack);
el.removeChild(track);
};
emulatedTt.on('addtrack', addtrack);
emulatedTt.on('removetrack', function() {
equal(emulatedTt.length, tt.length, 'we have matching tracks length');
@@ -333,6 +330,7 @@ if (Html5.supportsNativeTextTracks()) {
let tt = el.textTracks;
let emulatedTt = html.textTracks();
let track = document.createElement('track');
el.appendChild(track);
let addtrack = function() {
@@ -347,6 +345,7 @@ if (Html5.supportsNativeTextTracks()) {
done();
};
emulatedTt.on('addtrack', addtrack);
});
}
@@ -354,6 +353,7 @@ if (Html5.supportsNativeTextTracks()) {
test('should check for text track changes when emulating text tracks', function() {
let tech = new Tech();
let numTextTrackChanges = 0;
tech.on('texttrackchange', function() {
numTextTrackChanges++;
});
@@ -367,6 +367,7 @@ test('removes cuechange event when text track is hidden for emulated tracks', fu
tech: player.tech_,
mode: 'showing'
});
tt.addCue({
id: '1',
startTime: 2,
@@ -376,6 +377,7 @@ test('removes cuechange event when text track is hidden for emulated tracks', fu
player.tech_.emulateTextTracks();
let numTextTrackChanges = 0;
player.tech_.on('texttrackchange', function() {
numTextTrackChanges++;
});
@@ -406,19 +408,18 @@ test('removes cuechange event when text track is hidden for emulated tracks', fu
'texttrackchange should be not be called since mode is hidden');
});
test('should return correct remote text track values', function () {
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>';
let html = `
<video id="example_1" class="video-js" autoplay preload="none">
<source src="http://google.com" type="video/mp4">
<source src="http://google.com" type="video/webm">
<track kind="captions" label="label">
</video>
`;
fixture.innerHTML += html;
let tag = document.getElementById('example_1');
let player = TestHelpers.makePlayer({}, tag);
this.clock.tick(1);
@@ -442,9 +443,8 @@ test('should return correct remote text track values', function () {
player.dispose();
});
test('should uniformly create html track element when adding text track', function () {
test('should uniformly create html track element when adding text track', function() {
let player = TestHelpers.makePlayer();
let track = {
kind: 'kind',
src: 'src',