Comparar commits

..

19 Commits

Autor SHA1 Mensagem Data
Gary Katsevman 7ae2d89f49 v5.3.0 dist 2015-11-25 17:14:38 -05:00
Gary Katsevman a601fbb83f v5.3.0 2015-11-25 17:14:05 -05:00
jrivera 69b89e51f4 @imbcmdth added sourceOrder option for source-first ordering in selectSource. closes #2847 2015-11-25 17:11:36 -05:00
jforbes 8acd28c15a @forbesjo updated formatTime to not go negative. closes #2821 2015-11-25 16:46:41 -05:00
Matthew b188781fa9 v5.2.4 2015-11-25 21:31:49 +00:00
Matthew McClure 5ed0dc8adb @mmcc fixed vertical volume. closes #2859 2015-11-25 16:18:34 -05:00
Garrett Singer 72f77d77c9 @gesinger fixed handler explosion for cuechange events. closes #2849 2015-11-25 16:13:23 -05:00
Garrett Singer 7171ea8d42 @gesinger checked for track changes before tech started listening. closes #2835 2015-11-25 16:00:49 -05:00
Gary 3e19c91828 v5.2.3 2015-11-24 20:52:01 +00:00
Gary Katsevman 5f9095079e @gkatsev fixed clearing out errors. closes #2850 2015-11-24 15:37:34 -05:00
paladox 552d8cbda3 v5.2.2 2015-11-23 17:31:27 +00:00
paladox 8d0de0fa51 @paladox updated xhr from deprecated ver to v2.2. closes #2837 2015-11-23 12:22:07 -05:00
tomaspinho c4dbd2488b @tomaspinho added 'ended' event to API docs. closes #2836 2015-11-23 12:15:50 -05:00
Violeta Marculescu c0d5f471bc @bcvio fixed returning current source rather than blob url. closes #2833 2015-11-23 12:04:31 -05:00
Nathaniel Bibler 3a40b10fa6 @nbibler ensured classes begin with alpha characters. Fixes #2828. closes #2829 2015-11-20 17:38:05 -05:00
Dat Tran 7dff83b2a4 @DatTran fixed bower paths. Fixes #2740. closes #2775 2015-11-20 17:22:49 -05:00
Kay 6bbd6f1a65 v5.2.1 2015-11-16 16:43:29 +00:00
Kay J d9b5fbc60d @ksjun corrected the registerTech export. closes #2816 2015-11-16 10:42:35 -05:00
David LaPalomento 385266338a @dmlap Check a component is a function before new-ing. closes #2814 2015-11-16 10:18:09 -05:00
27 arquivos alterados com 860 adições e 436 exclusões
+23
Ver Arquivo
@@ -6,6 +6,29 @@ _(none)_
--------------------
## 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))
* @bcvio fixed returning current source rather than blob url ([view](https://github.com/videojs/video.js/pull/2833))
* @tomaspinho added ended event to API docs ([view](https://github.com/videojs/video.js/pull/2836))
* @paladox updated xhr from deprecated ver to v2.2 ([view](https://github.com/videojs/video.js/pull/2837))
## 5.2.1 (2015-11-16)
* @dmlap Check a component is a function before new-ing ([view](https://github.com/videojs/video.js/pull/2814))
* @ksjun corrected the registerTech export ([view](https://github.com/videojs/video.js/pull/2816))
## 5.2.0 (2015-11-10)
* @gkatsev made initListeners more general and added Tech.isTech. Fixes #2767 ([view](https://github.com/videojs/video.js/pull/2773))
* @dmlap updated swf to 5.0.1 ([view](https://github.com/videojs/video.js/pull/2795))
+2 -2
Ver Arquivo
@@ -2,8 +2,8 @@
"name": "video.js",
"description": "An HTML5 and Flash video player with a common API and skin for both.",
"main": [
"src/js/video.js",
"src/css/video-js.scss"
"dist/video.js",
"dist/video-js.css"
],
"moduleType": "es6",
"keywords": [
+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.2.0",
"version": "5.3.0",
"keywords": [
"videojs",
"html5",
+265 -149
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+9 -8
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
Arquivo binário não exibido.
+3 -2
Ver Arquivo
@@ -499,7 +499,7 @@ about what's required to play video. */
/* Same as ul background */ }
/* Button Pop-up Menu */
.vjs-menu-button-popup .vjs-menu ul {
.vjs-menu-button-popup .vjs-menu .vjs-menu-content {
background-color: #2B333F;
background-color: rgba(43, 51, 63, 0.7);
position: absolute;
@@ -911,7 +911,8 @@ width and height to zero. */
border-top-color: transparent; }
.vjs-menu-button-popup.vjs-volume-menu-button-vertical .vjs-menu {
left: 0.5em; }
left: 0.5em;
height: 8em; }
.vjs-menu-button-popup.vjs-volume-menu-button-horizontal .vjs-menu {
left: -2em; }
+1 -1
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+265 -149
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+12 -10
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
+34
Ver Arquivo
@@ -49,6 +49,40 @@ 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.
+2 -2
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.2.0",
"version": "5.3.0",
"copyright": "Copyright Brightcove, Inc. <https://www.brightcove.com/>",
"license": "Apache-2.0",
"keywords": [
@@ -32,7 +32,7 @@
"videojs-ie8": "1.1.0",
"videojs-swf": "5.0.1",
"vtt.js": "git+https://github.com/gkatsev/vtt.js.git#vjs-v0.12.1",
"xhr": "2.1.0"
"xhr": "~2.2.0"
},
"devDependencies": {
"babel": "^5.2.2",
+1
Ver Arquivo
@@ -96,6 +96,7 @@ width and height to zero. */
.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;
+1 -1
Ver Arquivo
@@ -10,7 +10,7 @@
}
/* Button Pop-up Menu */
.vjs-menu-button-popup .vjs-menu ul {
.vjs-menu-button-popup .vjs-menu .vjs-menu-content {
@include background-color-with-alpha($primary-background-color, $primary-background-transparency);
position: absolute;
+8
Ver Arquivo
@@ -373,6 +373,14 @@ class Component {
throw new Error(`Component ${componentClassName} does not exist`);
}
// data stored directly on the videojs object may be
// misidentified as a component to retain
// backwards-compatibility with 4.x. check to make sure the
// component class can be instantiated.
if (typeof ComponentClass !== 'function') {
return null;
}
component = new ComponentClass(this.player_ || this, options);
// child is a component instance
+77 -31
Ver Arquivo
@@ -415,6 +415,7 @@ class Player extends Component {
let width;
let height;
let aspectRatio;
let idClass;
// The aspect ratio is either used directly or to calculate width and height.
if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') {
@@ -451,7 +452,12 @@ class Player extends Component {
height = width * ratioMultiplier;
}
let idClass = this.id()+'-dimensions';
// Ensure the CSS class is valid by starting with an alpha character
if (/^[^a-zA-Z]/.test(this.id())) {
idClass = 'dimensions-'+this.id();
} else {
idClass = this.id()+'-dimensions';
}
// Ensure the right class is still on the player for the style element
this.addClass(idClass);
@@ -1687,43 +1693,75 @@ class Player extends Component {
}
/**
* Select source based on tech order
* Select source based on tech-order or source-order
* Uses source-order selection if `options.sourceOrder` is truthy. Otherwise,
* defaults to tech-order selection
*
* @param {Array} sources The sources for a media asset
* @return {Object|Boolean} Object of source and tech order, otherwise false
* @method selectSource
*/
selectSource(sources) {
// 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;
}
// 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 };
// 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};
}
};
// 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);
}
return false;
return foundSourceAndTech || false;
}
/**
@@ -2101,6 +2139,7 @@ class Player extends Component {
if (err === null) {
this.error_ = err;
this.removeClass('vjs-error');
this.errorDisplay.close();
return this;
}
@@ -2111,9 +2150,6 @@ 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');
@@ -2121,6 +2157,9 @@ 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;
}
@@ -2711,6 +2750,13 @@ Player.prototype.handleUserInactive_;
*/
Player.prototype.handleTimeUpdate_;
/**
* Fired when video playback ends
*
* @event ended
*/
Player.prototype.handleTechEnded_;
/**
* Fired when the volume changes
*
+7 -1
Ver Arquivo
@@ -492,7 +492,13 @@ class Html5 extends Tech {
* @return {Object}
* @method currentSrc
*/
currentSrc() { return this.el_.currentSrc; }
currentSrc() {
if (this.currentSource_) {
return this.currentSource_.src;
} else {
return this.el_.currentSrc;
}
}
/**
* Get poster
+4 -4
Ver Arquivo
@@ -321,9 +321,8 @@ class Tech extends Component {
window['WebVTT'] = true;
}
let textTracksChanges = Fn.bind(this, function() {
let updateDisplay = () => this.trigger('texttrackchange');
let updateDisplay = () => this.trigger('texttrackchange');
let textTracksChanges = () => {
updateDisplay();
for (let i = 0; i < tracks.length; i++) {
@@ -333,8 +332,9 @@ class Tech extends Component {
track.addEventListener('cuechange', updateDisplay);
}
}
});
};
textTracksChanges();
tracks.addEventListener('change', textTracksChanges);
this.on('dispose', function() {
+1
Ver Arquivo
@@ -12,6 +12,7 @@
* @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);
+1 -1
Ver Arquivo
@@ -246,7 +246,7 @@ videojs.getTech = Tech.getTech;
* @mixes videojs
* @method registerTech
*/
videojs.registerTech = Component.registerTech;
videojs.registerTech = Tech.registerTech;
/**
* A suite of browser and device tests
+66 -64
Ver Arquivo
@@ -7,6 +7,8 @@ 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 Tech from '../../src/js/tech/tech.js';
import TechFaker from './tech/tech-faker.js';
q.module('Player', {
'setup': function() {
@@ -17,36 +19,6 @@ 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();
@@ -199,6 +171,21 @@ test('should set the width, height, and aspect ratio via a css class', function(
ok(confirmSetting('padding-top', '25%'), 'aspect ratio percent should match the newly set aspect ratio');
});
test('should use an class name that begins with an alpha character', function(){
let alphaPlayer = TestHelpers.makePlayer({ id: 'alpha1' });
let numericPlayer = TestHelpers.makePlayer({ id: '1numeric' });
let getStyleText = function(styleEl){
return (styleEl.styleSheet && styleEl.styleSheet.cssText) || styleEl.innerHTML;
};
alphaPlayer.width(100);
numericPlayer.width(100);
ok(/\s*\.alpha1-dimensions\s*\{/.test(getStyleText(alphaPlayer.styleEl_)), 'appends -dimensions to an alpha player ID');
ok(/\s*\.dimensions-1numeric\s*\{/.test(getStyleText(numericPlayer.styleEl_)), 'prepends dimensions- to a numeric player ID');
});
test('should wrap the original tag in the player div', function(){
var tag = TestHelpers.makeTag();
var container = document.createElement('div');
@@ -324,24 +311,6 @@ 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({});
@@ -441,27 +410,42 @@ test('make sure that controls listeners do not get added too many times', functi
player.dispose();
});
// 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');
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>';
// var html =
// '<video id="example_1">' +
// '<source src="fake.foo" type="video/foo">' +
// '</video>';
// 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);
// fixture.innerHTML += html;
fixture.innerHTML += html;
let tag = document.getElementById('example_1');
// var tag = document.getElementById('example_1');
// var player = new Player(tag, { techOrder: ['techFaker'] });
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 incompatibilityMessage = player.el().getElementsByTagName('p')[0];
// // ie8 capitalizes tag names
// equal(incompatibilityMessage.innerHTML.toLowerCase(), 'video no go <a href="">link</a>');
fixture.innerHTML += html;
tag = document.getElementById('example_1');
// player.dispose();
// });
player = new Player(tag, { techOrder: ['techFaker', 'playsUnsupported']});
equal(player.techName_, 'TechFaker', 'selected the TechFaker tech when sourceOrder is falsey');
player.dispose();
});
test('should register players with generated ids', function(){
var fixture, video, player, id;
@@ -859,3 +843,21 @@ 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();
});
+6
Ver Arquivo
@@ -249,6 +249,12 @@ if (Html5.supportsNativeTextTracks()) {
equal(adds[2][0], rems[2][0], 'removetrack event handler removed');
});
}
test('should always return currentSource_ if set', function(){
let currentSrc = Html5.prototype.currentSrc;
equal(currentSrc.call({el_: {currentSrc:'test1'}}), 'test1', 'sould return source from element if nothing else set');
equal(currentSrc.call({currentSource_:{src: 'test2'}}), 'test2', 'sould return source from currentSource_, if nothing else set');
equal(currentSrc.call({currentSource_:{src: 'test2'}, el_:{currentSrc:'test1'}}), 'test2', 'sould return source from source set, not from element');
});
test('should fire makeup events when a video tag is initialized late', function(){
let lateInit = Html5.prototype.handleLateInit_;
+56
Ver Arquivo
@@ -2,6 +2,7 @@ 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';
@@ -342,3 +343,58 @@ 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');
});
+4
Ver Arquivo
@@ -20,6 +20,10 @@ 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(){