Broken initialize.js. First try at making all submodules functions public (available via state object).

More work on making modules completely visible via state object.
All tests pass in video_volume_control_spec.js
Cleanup of initial CoffeeScript generated video_speed_control_spec.js
Some cleaning up in volume_control. Most tests pass in speed_control
Cleanup of CoffeeScript generated video_progress_slider_spec.js
Most tests in video_progress_slider_spec.js pass (except for those having an issue with subtitles). progressSlider functions again in Chrome
Cleanup of CoffeeScript generated video_control_spec.js
All tests pass in video_control_spec.js
Cleanup of CoffeeScript generated video_caption_spec.js
Some progress in video_caption_spec.js
Fix bug with video progress slider. Now browser doesnt freeze any more. ^_^
Some cleaning up.
This commit is contained in:
Valera Rozuvan
2013-07-05 15:26:53 +03:00
committed by Vasyl Nakvasiuk
parent 52fa6591c2
commit c49ad095d5
12 changed files with 733 additions and 542 deletions

View File

@@ -0,0 +1,55 @@
<div class="course-content">
<div id="video_example">
<div id="example">
<div
id="video_id"
class="videoalpha"
data-show-captions="true"
data-start=""
data-end=""
data-caption-asset-path="/static/subs/"
data-sub=""
data-mp4-source="test.mp4"
data-webm-source="test.webm"
data-ogg-source="test.ogv"
>
<div class="tc-wrapper">
<article class="video-wrapper">
<div class="video-player-pre"></div>
<section class="video-player">
<div id="id"></div>
</section>
<div class="video-player-post"></div>
<section class="video-controls">
<div class="slider"></div>
<div>
<ul class="vcr">
<li><a class="video_control" href="#" title="Play"></a></li>
<li><div class="vidtime">0:00 / 0:00</div></li>
</ul>
<div class="secondary-controls">
<div class="speeds">
<a href="#">
<h3>Speed</h3>
<p class="active"></p>
</a>
<ol class="video_speeds"></ol>
</div>
<div class="volume">
<a href="#"></a>
<div class="volume-slider-container">
<div class="volume-slider"></div>
</div>
</div>
<a href="#" class="add-fullscreen" title="Fill browser">Fill Browser</a>
<a href="#" class="quality_control" title="HD">HD</a>
<a href="#" class="hide-subtitles" title="Turn off captions">Captions</a>
</div>
</div>
</section>
</article>
</div>
</div>
</div>
</div>
</div>

View File

@@ -2,11 +2,14 @@
describe('VideoAlpha HTML5Video', function () {
var state, player, playbackRates = [0.75, 1.0, 1.25, 1.5];
beforeEach(function () {
function initialize() {
loadFixtures('videoalpha_html5.html');
state = new VideoAlpha('#example');
player = state.videoPlayer.player;
}
beforeEach(function () {
initialize();
player.config.events.onReady = jasmine.createSpy('onReady');
});

View File

@@ -1,414 +1,491 @@
// Generated by CoffeeScript 1.6.3
(function() {
xdescribe('VideoCaptionAlpha', function() {
var state, videoPlayer, videoCaption, videoSpeedControl;
function initialize() {
loadFixtures('videoalpha_all.html');
state = new VideoAlpha('#example');
videoPlayer = state.videoPlayer;
videoCaption = state.videoCaption;
videoSpeedControl = state.videoSpeedControl;
}
beforeEach(function() {
spyOn(VideoCaptionAlpha.prototype, 'fetchCaption').andCallThrough();
initialize();
spyOn(videoCaption, 'fetchCaption').andCallThrough();
spyOn($, 'ajaxWithPrefix').andCallThrough();
return window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice').andReturn(false);
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice').andReturn(false);
});
afterEach(function() {
YT.Player = void 0;
$.fn.scrollTo.reset();
return $('.subtitles').remove();
$('.subtitles').remove();
});
describe('constructor', function() {
describe('always', function() {
beforeEach(function() {
this.player = jasmine.stubVideoPlayerAlpha(this);
return this.caption = this.player.caption;
initialize();
});
it('set the youtube id', function() {
return expect(this.caption.youtubeId).toEqual('normalSpeedYoutubeId');
expect(videoCaption.youtubeId).toEqual('normalSpeedYoutubeId');
});
it('create the caption element', function() {
return expect($('.video')).toContain('ol.subtitles');
expect($('.video')).toContain('ol.subtitles');
});
it('add caption control to video player', function() {
return expect($('.video')).toContain('a.hide-subtitles');
expect($('.video')).toContain('a.hide-subtitles');
});
it('fetch the caption', function() {
expect(this.caption.loaded).toBeTruthy();
expect(this.caption.fetchCaption).toHaveBeenCalled();
return expect($.ajaxWithPrefix).toHaveBeenCalledWith({
url: this.caption.captionURL(),
expect(videoCaption.loaded).toBeTruthy();
expect(videoCaption.fetchCaption).toHaveBeenCalled();
expect($.ajaxWithPrefix).toHaveBeenCalledWith({
url: videoCaption.captionURL(),
notifyOnError: false,
success: jasmine.any(Function)
});
});
it('bind window resize event', function() {
return expect($(window)).toHandleWith('resize', this.caption.resize);
expect($(window)).toHandleWith('resize', videoCaption.resize);
});
it('bind the hide caption button', function() {
return expect($('.hide-subtitles')).toHandleWith('click', this.caption.toggle);
expect($('.hide-subtitles')).toHandleWith('click', videoCaption.toggle);
});
return it('bind the mouse movement', function() {
expect($('.subtitles')).toHandleWith('mouseover', this.caption.onMouseEnter);
expect($('.subtitles')).toHandleWith('mouseout', this.caption.onMouseLeave);
expect($('.subtitles')).toHandleWith('mousemove', this.caption.onMovement);
expect($('.subtitles')).toHandleWith('mousewheel', this.caption.onMovement);
return expect($('.subtitles')).toHandleWith('DOMMouseScroll', this.caption.onMovement);
it('bind the mouse movement', function() {
expect($('.subtitles')).toHandleWith('mouseover', videoCaption.onMouseEnter);
expect($('.subtitles')).toHandleWith('mouseout', videoCaption.onMouseLeave);
expect($('.subtitles')).toHandleWith('mousemove', videoCaption.onMovement);
expect($('.subtitles')).toHandleWith('mousewheel', videoCaption.onMovement);
expect($('.subtitles')).toHandleWith('DOMMouseScroll', videoCaption.onMovement);
});
});
describe('when on a non touch-based device', function() {
beforeEach(function() {
this.player = jasmine.stubVideoPlayerAlpha(this);
return this.caption = this.player.caption;
initialize();
});
it('render the caption', function() {
var captionsData,
_this = this;
var captionsData;
captionsData = jasmine.stubbedCaption;
return $('.subtitles li[data-index]').each(function(index, link) {
$('.subtitles li[data-index]').each(function(index, link) {
expect($(link)).toHaveData('index', index);
expect($(link)).toHaveData('start', captionsData.start[index]);
return expect($(link)).toHaveText(captionsData.text[index]);
expect($(link)).toHaveText(captionsData.text[index]);
});
});
it('add a padding element to caption', function() {
expect($('.subtitles li:first')).toBe('.spacing');
return expect($('.subtitles li:last')).toBe('.spacing');
expect($('.subtitles li:last')).toBe('.spacing');
});
it('bind all the caption link', function() {
var _this = this;
return $('.subtitles li[data-index]').each(function(index, link) {
return expect($(link)).toHandleWith('click', _this.caption.seekPlayer);
$('.subtitles li[data-index]').each(function(index, link) {
expect($(link)).toHandleWith('click', videoCaption.seekPlayer);
});
});
return it('set rendered to true', function() {
return expect(this.caption.rendered).toBeTruthy();
it('set rendered to true', function() {
expect(videoCaption.rendered).toBeTruthy();
});
});
return describe('when on a touch-based device', function() {
describe('when on a touch-based device', function() {
beforeEach(function() {
window.onTouchBasedDevice.andReturn(true);
this.player = jasmine.stubVideoPlayerAlpha(this);
return this.caption = this.player.caption;
initialize();
});
it('show explaination message', function() {
return expect($('.subtitles li')).toHaveHtml("Caption will be displayed when you start playing the video.");
expect($('.subtitles li')).toHaveHtml("Caption will be displayed when you start playing the video.");
});
return it('does not set rendered to true', function() {
return expect(this.caption.rendered).toBeFalsy();
it('does not set rendered to true', function() {
expect(videoCaption.rendered).toBeFalsy();
});
});
});
describe('mouse movement', function() {
beforeEach(function() {
this.player = jasmine.stubVideoPlayerAlpha(this);
this.caption = this.player.caption;
initialize();
window.setTimeout.andReturn(100);
return spyOn(window, 'clearTimeout');
spyOn(window, 'clearTimeout');
});
describe('when cursor is outside of the caption box', function() {
beforeEach(function() {
return $(window).trigger(jQuery.Event('mousemove'));
$(window).trigger(jQuery.Event('mousemove'));
});
return it('does not set freezing timeout', function() {
return expect(this.caption.frozen).toBeFalsy();
it('does not set freezing timeout', function() {
expect(videoCaption.frozen).toBeFalsy();
});
});
describe('when cursor is in the caption box', function() {
beforeEach(function() {
return $('.subtitles').trigger(jQuery.Event('mouseenter'));
$('.subtitles').trigger(jQuery.Event('mouseenter'));
});
it('set the freezing timeout', function() {
return expect(this.caption.frozen).toEqual(100);
expect(videoCaption.frozen).toEqual(100);
});
describe('when the cursor is moving', function() {
beforeEach(function() {
return $('.subtitles').trigger(jQuery.Event('mousemove'));
$('.subtitles').trigger(jQuery.Event('mousemove'));
});
return it('reset the freezing timeout', function() {
return expect(window.clearTimeout).toHaveBeenCalledWith(100);
it('reset the freezing timeout', function() {
expect(window.clearTimeout).toHaveBeenCalledWith(100);
});
});
return describe('when the mouse is scrolling', function() {
describe('when the mouse is scrolling', function() {
beforeEach(function() {
return $('.subtitles').trigger(jQuery.Event('mousewheel'));
$('.subtitles').trigger(jQuery.Event('mousewheel'));
});
return it('reset the freezing timeout', function() {
return expect(window.clearTimeout).toHaveBeenCalledWith(100);
it('reset the freezing timeout', function() {
expect(window.clearTimeout).toHaveBeenCalledWith(100);
});
});
});
return describe('when cursor is moving out of the caption box', function() {
describe('when cursor is moving out of the caption box', function() {
beforeEach(function() {
this.caption.frozen = 100;
return $.fn.scrollTo.reset();
videoCaption.frozen = 100;
$.fn.scrollTo.reset();
});
describe('always', function() {
beforeEach(function() {
return $('.subtitles').trigger(jQuery.Event('mouseout'));
$('.subtitles').trigger(jQuery.Event('mouseout'));
});
it('reset the freezing timeout', function() {
return expect(window.clearTimeout).toHaveBeenCalledWith(100);
expect(window.clearTimeout).toHaveBeenCalledWith(100);
});
return it('unfreeze the caption', function() {
return expect(this.caption.frozen).toBeNull();
it('unfreeze the caption', function() {
expect(videoCaption.frozen).toBeNull();
});
});
describe('when the player is playing', function() {
beforeEach(function() {
this.caption.playing = true;
videoCaption.playing = true;
$('.subtitles li[data-index]:first').addClass('current');
return $('.subtitles').trigger(jQuery.Event('mouseout'));
$('.subtitles').trigger(jQuery.Event('mouseout'));
});
return it('scroll the caption', function() {
return expect($.fn.scrollTo).toHaveBeenCalled();
it('scroll the caption', function() {
expect($.fn.scrollTo).toHaveBeenCalled();
});
});
return describe('when the player is not playing', function() {
describe('when the player is not playing', function() {
beforeEach(function() {
this.caption.playing = false;
return $('.subtitles').trigger(jQuery.Event('mouseout'));
videoCaption.playing = false;
$('.subtitles').trigger(jQuery.Event('mouseout'));
});
return it('does not scroll the caption', function() {
return expect($.fn.scrollTo).not.toHaveBeenCalled();
it('does not scroll the caption', function() {
expect($.fn.scrollTo).not.toHaveBeenCalled();
});
});
});
});
describe('search', function() {
beforeEach(function() {
this.player = jasmine.stubVideoPlayerAlpha(this);
return this.caption = this.player.caption;
initialize();
});
return it('return a correct caption index', function() {
expect(this.caption.search(0)).toEqual(0);
expect(this.caption.search(9999)).toEqual(0);
expect(this.caption.search(10000)).toEqual(1);
expect(this.caption.search(15000)).toEqual(1);
expect(this.caption.search(30000)).toEqual(3);
return expect(this.caption.search(30001)).toEqual(3);
it('return a correct caption index', function() {
expect(videoCaption.search(0)).toEqual(0);
expect(videoCaption.search(9999)).toEqual(0);
expect(videoCaption.search(10000)).toEqual(1);
expect(videoCaption.search(15000)).toEqual(1);
expect(videoCaption.search(30000)).toEqual(3);
expect(videoCaption.search(30001)).toEqual(3);
});
});
describe('play', function() {
return describe('when the caption was not rendered', function() {
describe('when the caption was not rendered', function() {
beforeEach(function() {
window.onTouchBasedDevice.andReturn(true);
this.player = jasmine.stubVideoPlayerAlpha(this);
this.caption = this.player.caption;
return this.caption.play();
initialize();
videoCaption.play();
});
it('render the caption', function() {
var captionsData,
_this = this;
var captionsData;
captionsData = jasmine.stubbedCaption;
return $('.subtitles li[data-index]').each(function(index, link) {
$('.subtitles li[data-index]').each(function(index, link) {
expect($(link)).toHaveData('index', index);
expect($(link)).toHaveData('start', captionsData.start[index]);
return expect($(link)).toHaveText(captionsData.text[index]);
expect($(link)).toHaveText(captionsData.text[index]);
});
});
it('add a padding element to caption', function() {
expect($('.subtitles li:first')).toBe('.spacing');
return expect($('.subtitles li:last')).toBe('.spacing');
expect($('.subtitles li:last')).toBe('.spacing');
});
it('bind all the caption link', function() {
var _this = this;
return $('.subtitles li[data-index]').each(function(index, link) {
return expect($(link)).toHandleWith('click', _this.caption.seekPlayer);
$('.subtitles li[data-index]').each(function(index, link) {
expect($(link)).toHandleWith('click', videoCaption.seekPlayer);
});
});
it('set rendered to true', function() {
return expect(this.caption.rendered).toBeTruthy();
expect(videoCaption.rendered).toBeTruthy();
});
return it('set playing to true', function() {
return expect(this.caption.playing).toBeTruthy();
it('set playing to true', function() {
expect(videoCaption.playing).toBeTruthy();
});
});
});
describe('pause', function() {
beforeEach(function() {
this.player = jasmine.stubVideoPlayerAlpha(this);
this.caption = this.player.caption;
this.caption.playing = true;
return this.caption.pause();
initialize();
videoCaption.playing = true;
videoCaption.pause();
});
return it('set playing to false', function() {
return expect(this.caption.playing).toBeFalsy();
it('set playing to false', function() {
expect(videoCaption.playing).toBeFalsy();
});
});
describe('updatePlayTime', function() {
beforeEach(function() {
this.player = jasmine.stubVideoPlayerAlpha(this);
return this.caption = this.player.caption;
initialize();
});
describe('when the video speed is 1.0x', function() {
beforeEach(function() {
this.caption.currentSpeed = '1.0';
return this.caption.updatePlayTime(25.000);
videoSpeedControl.currentSpeed = '1.0';
videoCaption.updatePlayTime(25.000);
});
return it('search the caption based on time', function() {
return expect(this.caption.currentIndex).toEqual(2);
it('search the caption based on time', function() {
expect(this.caption.currentIndex).toEqual(2);
});
});
describe('when the video speed is not 1.0x', function() {
beforeEach(function() {
this.caption.currentSpeed = '0.75';
return this.caption.updatePlayTime(25.000);
videoSpeedControl.currentSpeed = '0.75';
videoSpeedControl.updatePlayTime(25.000);
});
return it('search the caption based on 1.0x speed', function() {
return expect(this.caption.currentIndex).toEqual(1);
it('search the caption based on 1.0x speed', function() {
expect(videoCaption.currentIndex).toEqual(1);
});
});
describe('when the index is not the same', function() {
beforeEach(function() {
this.caption.currentIndex = 1;
videoCaption.currentIndex = 1;
$('.subtitles li[data-index=1]').addClass('current');
return this.caption.updatePlayTime(25.000);
videoCaption.updatePlayTime(25.000);
});
it('deactivate the previous caption', function() {
return expect($('.subtitles li[data-index=1]')).not.toHaveClass('current');
expect($('.subtitles li[data-index=1]')).not.toHaveClass('current');
});
it('activate new caption', function() {
return expect($('.subtitles li[data-index=2]')).toHaveClass('current');
expect($('.subtitles li[data-index=2]')).toHaveClass('current');
});
it('save new index', function() {
return expect(this.caption.currentIndex).toEqual(2);
expect(videoCaption.currentIndex).toEqual(2);
});
return it('scroll caption to new position', function() {
return expect($.fn.scrollTo).toHaveBeenCalled();
it('scroll caption to new position', function() {
expect($.fn.scrollTo).toHaveBeenCalled();
});
});
return describe('when the index is the same', function() {
describe('when the index is the same', function() {
beforeEach(function() {
this.caption.currentIndex = 1;
videoCaption.currentIndex = 1;
$('.subtitles li[data-index=1]').addClass('current');
return this.caption.updatePlayTime(15.000);
videoCaption.updatePlayTime(15.000);
});
return it('does not change current subtitle', function() {
return expect($('.subtitles li[data-index=1]')).toHaveClass('current');
it('does not change current subtitle', function() {
expect($('.subtitles li[data-index=1]')).toHaveClass('current');
});
});
});
describe('resize', function() {
beforeEach(function() {
this.player = jasmine.stubVideoPlayerAlpha(this);
this.caption = this.player.caption;
initialize();
$('.subtitles li[data-index=1]').addClass('current');
return this.caption.resize();
videoCaption.resize();
});
it('set the height of caption container', function() {
return expect(parseInt($('.subtitles').css('maxHeight'))).toBeCloseTo($('.video-wrapper').height(), 2);
expect(parseInt($('.subtitles').css('maxHeight'))).toBeCloseTo($('.video-wrapper').height(), 2);
});
it('set the height of caption spacing', function() {
var firstSpacing, lastSpacing;
firstSpacing = Math.abs(parseInt($('.subtitles .spacing:first').css('height')));
lastSpacing = Math.abs(parseInt($('.subtitles .spacing:last').css('height')));
expect(firstSpacing - this.caption.topSpacingHeight()).toBeLessThan(1);
return expect(lastSpacing - this.caption.bottomSpacingHeight()).toBeLessThan(1);
expect(firstSpacing - videoCaption.topSpacingHeight()).toBeLessThan(1);
expect(lastSpacing - videoCaption.bottomSpacingHeight()).toBeLessThan(1);
});
return it('scroll caption to new position', function() {
return expect($.fn.scrollTo).toHaveBeenCalled();
it('scroll caption to new position', function() {
expect($.fn.scrollTo).toHaveBeenCalled();
});
});
describe('scrollCaption', function() {
beforeEach(function() {
this.player = jasmine.stubVideoPlayerAlpha(this);
return this.caption = this.player.caption;
initialize();
});
describe('when frozen', function() {
beforeEach(function() {
this.caption.frozen = true;
videoCaption.frozen = true;
$('.subtitles li[data-index=1]').addClass('current');
return this.caption.scrollCaption();
videoCaption.scrollCaption();
});
return it('does not scroll the caption', function() {
return expect($.fn.scrollTo).not.toHaveBeenCalled();
it('does not scroll the caption', function() {
expect($.fn.scrollTo).not.toHaveBeenCalled();
});
});
return describe('when not frozen', function() {
describe('when not frozen', function() {
beforeEach(function() {
return this.caption.frozen = false;
videoCaption.frozen = false;
});
describe('when there is no current caption', function() {
beforeEach(function() {
return this.caption.scrollCaption();
videoCaption.scrollCaption();
});
return it('does not scroll the caption', function() {
return expect($.fn.scrollTo).not.toHaveBeenCalled();
it('does not scroll the caption', function() {
expect($.fn.scrollTo).not.toHaveBeenCalled();
});
});
return describe('when there is a current caption', function() {
describe('when there is a current caption', function() {
beforeEach(function() {
$('.subtitles li[data-index=1]').addClass('current');
return this.caption.scrollCaption();
videoCaption.scrollCaption();
});
return it('scroll to current caption', function() {
it('scroll to current caption', function() {
var offset;
offset = -0.5 * ($('.video-wrapper').height() - $('.subtitles .current:first').height());
return expect($.fn.scrollTo).toHaveBeenCalledWith($('.subtitles .current:first', this.caption.el), {
expect($.fn.scrollTo).toHaveBeenCalledWith($('.subtitles .current:first', videoCaption.el), { //Somewhere else
offset: offset
});
});
});
});
});
describe('seekPlayer', function() {
beforeEach(function() {
var _this = this;
this.player = jasmine.stubVideoPlayerAlpha(this);
this.caption = this.player.caption;
return $(this.caption).bind('seek', function(event, time) {
return _this.time = time;
initialize();
$(videoCaption).bind('seek', function(event, time) {
_this.time = time;
});
});
describe('when the video speed is 1.0x', function() {
beforeEach(function() {
this.caption.currentSpeed = '1.0';
return $('.subtitles li[data-start="30000"]').trigger('click');
videoSpeedControl.currentSpeed = '1.0';
$('.subtitles li[data-start="30000"]').trigger('click');
});
return it('trigger seek event with the correct time', function() {
return expect(this.player.currentTime).toEqual(30.000);
it('trigger seek event with the correct time', function() {
expect(videoPlayer.currentTime).toEqual(30.000);
});
});
return describe('when the video speed is not 1.0x', function() {
describe('when the video speed is not 1.0x', function() {
beforeEach(function() {
this.caption.currentSpeed = '0.75';
return $('.subtitles li[data-start="30000"]').trigger('click');
videoSpeedControl.currentSpeed = '0.75';
$('.subtitles li[data-start="30000"]').trigger('click');
});
return it('trigger seek event with the correct time', function() {
return expect(this.player.currentTime).toEqual(40.000);
it('trigger seek event with the correct time', function() {
expect(videoPlayer.currentTime).toEqual(40.000);
});
});
});
return describe('toggle', function() {
describe('toggle', function() {
beforeEach(function() {
this.player = jasmine.stubVideoPlayerAlpha(this);
spyOn(this.video, 'log');
this.caption = this.player.caption;
return $('.subtitles li[data-index=1]').addClass('current');
initialize();
spyOn(videoPlayer, 'log');
$('.subtitles li[data-index=1]').addClass('current');
});
describe('when the caption is visible', function() {
beforeEach(function() {
this.caption.el.removeClass('closed');
return this.caption.toggle(jQuery.Event('click'));
videoCaption.el.removeClass('closed');
videoCaption.toggle(jQuery.Event('click'));
});
it('log the hide_transcript event', function() {
return expect(this.video.log).toHaveBeenCalledWith('hide_transcript', {
currentTime: this.player.currentTime
expect(videoPlayer.log).toHaveBeenCalledWith('hide_transcript', {
currentTime: videoPlayer.currentTime
});
});
return it('hide the caption', function() {
return expect(this.caption.el).toHaveClass('closed');
it('hide the caption', function() {
expect(videoCaption.el).toHaveClass('closed');
});
});
return describe('when the caption is hidden', function() {
describe('when the caption is hidden', function() {
beforeEach(function() {
this.caption.el.addClass('closed');
return this.caption.toggle(jQuery.Event('click'));
videoCaption.el.addClass('closed');
videoCaption.toggle(jQuery.Event('click'));
});
it('log the show_transcript event', function() {
return expect(this.video.log).toHaveBeenCalledWith('show_transcript', {
currentTime: this.player.currentTime
expect(videoPlayer.log).toHaveBeenCalledWith('show_transcript', {
currentTime: videoPlayer.currentTime
});
});
it('show the caption', function() {
return expect(this.caption.el).not.toHaveClass('closed');
expect(videoCaption.el).not.toHaveClass('closed');
});
return it('scroll the caption', function() {
return expect($.fn.scrollTo).toHaveBeenCalled();
it('scroll the caption', function() {
expect($.fn.scrollTo).toHaveBeenCalled();
});
});
});

View File

@@ -1,124 +1,111 @@
// Generated by CoffeeScript 1.6.3
(function() {
xdescribe('VideoControlAlpha', function() {
beforeEach(function() {
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice').andReturn(false);
loadFixtures('videoalpha.html');
return $('.video-controls').html('');
});
describe('VideoControlAlpha', function() {
var state, videoControl;
function initialize() {
loadFixtures('videoalpha_all.html');
state = new VideoAlpha('#example');
videoControl = state.videoControl;
}
describe('constructor', function() {
beforeEach(function() {
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice').andReturn(false);
initialize();
});
it('render the video controls', function() {
this.control = new window.VideoControlAlpha({
el: $('.video-controls')
});
expect($('.video-controls')).toContain;
['.slider', 'ul.vcr', 'a.play', '.vidtime', '.add-fullscreen'].join(',');
return expect($('.video-controls').find('.vidtime')).toHaveText('0:00 / 0:00');
expect($('.video-controls')).toContain(
['.slider', 'ul.vcr', 'a.play', '.vidtime', '.add-fullscreen'].join(',')
); //Should we add '.quality_control' and '.hide-subtitles'?
expect($('.video-controls').find('.vidtime')).toHaveText('0:00 / 0:00');
});
it('bind the playback button', function() {
this.control = new window.VideoControlAlpha({
el: $('.video-controls')
});
return expect($('.video_control')).toHandleWith('click', this.control.togglePlayback);
expect($('.video_control')).toHandleWith('click', videoControl.togglePlayback);
});
describe('when on a non-touch based device', function() {
beforeEach(function() {
initialize();
});
it('add the play class to video control', function() {
expect($('.video_control')).toHaveClass('play');
expect($('.video_control')).toHaveAttr('title', 'Play');
});
});
describe('when on a touch based device', function() {
beforeEach(function() {
window.onTouchBasedDevice.andReturn(true);
return this.control = new window.VideoControlAlpha({
el: $('.video-controls')
});
initialize();
});
return it('does not add the play class to video control', function() {
it('does not add the play class to video control', function() {
expect($('.video_control')).not.toHaveClass('play');
return expect($('.video_control')).not.toHaveHtml('Play');
});
});
return describe('when on a non-touch based device', function() {
beforeEach(function() {
return this.control = new window.VideoControlAlpha({
el: $('.video-controls')
});
});
return it('add the play class to video control', function() {
expect($('.video_control')).toHaveClass('play');
return expect($('.video_control')).toHaveHtml('Play');
expect($('.video_control')).not.toHaveAttr('title', 'Play');
});
});
});
describe('play', function() {
beforeEach(function() {
this.control = new window.VideoControlAlpha({
el: $('.video-controls')
});
return this.control.play();
initialize();
videoControl.play();
});
return it('switch playback button to play state', function() {
it('switch playback button to play state', function() {
expect($('.video_control')).not.toHaveClass('play');
expect($('.video_control')).toHaveClass('pause');
return expect($('.video_control')).toHaveHtml('Pause');
expect($('.video_control')).toHaveAttr('title', 'Pause');
});
});
describe('pause', function() {
beforeEach(function() {
this.control = new window.VideoControlAlpha({
el: $('.video-controls')
});
return this.control.pause();
initialize();
videoControl.pause();
});
return it('switch playback button to pause state', function() {
it('switch playback button to pause state', function() {
expect($('.video_control')).not.toHaveClass('pause');
expect($('.video_control')).toHaveClass('play');
return expect($('.video_control')).toHaveHtml('Play');
expect($('.video_control')).toHaveAttr('title', 'Play');
});
});
return describe('togglePlayback', function() {
describe('togglePlayback', function() {
beforeEach(function() {
return this.control = new window.VideoControlAlpha({
el: $('.video-controls')
});
initialize();
});
return describe('when the control does not have play or pause class', function() {
describe('when the control does not have play or pause class', function() {
beforeEach(function() {
return $('.video_control').removeClass('play').removeClass('pause');
$('.video_control').removeClass('play').removeClass('pause');
});
describe('when the video is playing', function() {
beforeEach(function() {
$('.video_control').addClass('play');
spyOnEvent(this.control, 'pause');
return this.control.togglePlayback(jQuery.Event('click'));
spyOnEvent(videoControl, 'pause');
videoControl.togglePlayback(jQuery.Event('click'));
});
return it('does not trigger the pause event', function() {
return expect('pause').not.toHaveBeenTriggeredOn(this.control);
it('does not trigger the pause event', function() {
expect('pause').not.toHaveBeenTriggeredOn(videoControl);
});
});
describe('when the video is paused', function() {
beforeEach(function() {
$('.video_control').addClass('pause');
spyOnEvent(this.control, 'play');
return this.control.togglePlayback(jQuery.Event('click'));
spyOnEvent(videoControl, 'play');
videoControl.togglePlayback(jQuery.Event('click'));
});
return it('does not trigger the play event', function() {
return expect('play').not.toHaveBeenTriggeredOn(this.control);
});
});
describe('when the video is playing', function() {
beforeEach(function() {
spyOnEvent(this.control, 'pause');
$('.video_control').addClass('pause');
return this.control.togglePlayback(jQuery.Event('click'));
});
return it('trigger the pause event', function() {
return expect('pause').toHaveBeenTriggeredOn(this.control);
});
});
return describe('when the video is paused', function() {
beforeEach(function() {
spyOnEvent(this.control, 'play');
$('.video_control').addClass('play');
return this.control.togglePlayback(jQuery.Event('click'));
});
return it('trigger the play event', function() {
return expect('play').toHaveBeenTriggeredOn(this.control);
it('does not trigger the play event', function() {
expect('play').not.toHaveBeenTriggeredOn(videoControl);
});
});
});

View File

@@ -1,33 +1,43 @@
// Generated by CoffeeScript 1.6.3
(function() {
xdescribe('VideoProgressSliderAlpha', function() {
describe('VideoProgressSliderAlpha', function() {
var state, videoPlayer, videoProgressSlider;
function initialize() {
loadFixtures('videoalpha_all.html');
state = new VideoAlpha('#example');
videoPlayer = state.videoPlayer;
videoProgressSlider = state.videoProgressSlider;
}
beforeEach(function() {
return window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice').andReturn(false);
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice').andReturn(false);
});
describe('constructor', function() {
describe('on a non-touch based device', function() {
beforeEach(function() {
spyOn($.fn, 'slider').andCallThrough();
this.player = jasmine.stubVideoPlayerAlpha(this);
return this.progressSlider = this.player.progressSlider;
initialize();
});
it('build the slider', function() {
expect(this.progressSlider.slider).toBe('.slider');
return expect($.fn.slider).toHaveBeenCalledWith({
expect(videoProgressSlider.slider).toBe('.slider');
expect($.fn.slider).toHaveBeenCalledWith({
range: 'min',
change: this.progressSlider.onChange,
slide: this.progressSlider.onSlide,
stop: this.progressSlider.onStop
change: videoProgressSlider.onChange,
slide: videoProgressSlider.onSlide,
stop: videoProgressSlider.onStop
});
});
return it('build the seek handle', function() {
expect(this.progressSlider.handle).toBe('.slider .ui-slider-handle');
return expect($.fn.qtip).toHaveBeenCalledWith({
it('build the seek handle', function() {
expect(videoProgressSlider.handle).toBe('.slider .ui-slider-handle');
expect($.fn.qtip).toHaveBeenCalledWith({
content: "0:00",
position: {
my: 'bottom center',
at: 'top center',
container: this.progressSlider.handle
container: videoProgressSlider.handle
},
hide: {
delay: 700
@@ -39,56 +49,69 @@
});
});
});
return describe('on a touch-based device', function() {
describe('on a touch-based device', function() {
beforeEach(function() {
window.onTouchBasedDevice.andReturn(true);
spyOn($.fn, 'slider').andCallThrough();
this.player = jasmine.stubVideoPlayerAlpha(this);
return this.progressSlider = this.player.progressSlider;
initialize();
});
return it('does not build the slider', function() {
expect(this.progressSlider.slider).toBeUndefined;
return expect($.fn.slider).not.toHaveBeenCalled();
it('does not build the slider', function() {
expect(videoProgressSlider.slider).toBeUndefined;
//TODO: Fails
expect($.fn.slider).not.toHaveBeenCalled();
});
});
});
describe('play', function() {
beforeEach(function() {
spyOn(VideoProgressSliderAlpha.prototype, 'buildSlider').andCallThrough();
this.player = jasmine.stubVideoPlayerAlpha(this);
return this.progressSlider = this.player.progressSlider;
initialize();
});
describe('when the slider was already built', function() {
var spy;
beforeEach(function() {
return this.progressSlider.play();
spy = spyOn(videoProgressSlider, 'buildSlider');
spy.andCallThrough();
videoPlayer.play();
});
return it('does not build the slider', function() {
return expect(this.progressSlider.buildSlider.calls.length).toEqual(1);
it('does not build the slider', function() {
expect(spy.callCount).toEqual(0);
});
});
return describe('when the slider was not already built', function() {
// Does it make sense to keep this test?
describe('when the slider was not already built', function() {
beforeEach(function() {
spyOn($.fn, 'slider').andCallThrough();
this.progressSlider.slider = null;
return this.progressSlider.play();
videoProgressSlider.slider = null;
videoPlayer.play();
});
it('build the slider', function() {
expect(this.progressSlider.slider).toBe('.slider');
return expect($.fn.slider).toHaveBeenCalledWith({
// TO DO: Fails
expect(videoProgressSlider.slider).toBe('.slider');
// TO DO: Fails
expect($.fn.slider).toHaveBeenCalledWith({
range: 'min',
change: this.progressSlider.onChange,
slide: this.progressSlider.onSlide,
stop: this.progressSlider.onStop
change: videoProgressSlider.onChange,
slide: videoProgressSlider.onSlide,
stop: videoProgressSlider.onStop
});
});
return it('build the seek handle', function() {
expect(this.progressSlider.handle).toBe('.ui-slider-handle');
return expect($.fn.qtip).toHaveBeenCalledWith({
it('build the seek handle', function() {
expect(videoProgressSlider.handle).toBe('.ui-slider-handle');
expect($.fn.qtip).toHaveBeenCalledWith({
content: "0:00",
position: {
my: 'bottom center',
at: 'top center',
container: this.progressSlider.handle
container: videoProgressSlider.handle
},
hide: {
delay: 700
@@ -101,97 +124,116 @@
});
});
});
describe('updatePlayTime', function() {
beforeEach(function() {
this.player = jasmine.stubVideoPlayerAlpha(this);
return this.progressSlider = this.player.progressSlider;
initialize();
});
describe('when frozen', function() {
beforeEach(function() {
spyOn($.fn, 'slider').andCallThrough();
this.progressSlider.frozen = true;
return this.progressSlider.updatePlayTime(20, 120);
videoProgressSlider.frozen = true;
videoProgressSlider.updatePlayTime(20, 120);
});
return it('does not update the slider', function() {
return expect($.fn.slider).not.toHaveBeenCalled();
it('does not update the slider', function() {
expect($.fn.slider).not.toHaveBeenCalled();
});
});
return describe('when not frozen', function() {
describe('when not frozen', function() {
beforeEach(function() {
spyOn($.fn, 'slider').andCallThrough();
this.progressSlider.frozen = false;
return this.progressSlider.updatePlayTime(20, 120);
videoProgressSlider.frozen = false;
videoProgressSlider.updatePlayTime({time:20, duration:120});
});
it('update the max value of the slider', function() {
return expect($.fn.slider).toHaveBeenCalledWith('option', 'max', 120);
expect($.fn.slider).toHaveBeenCalledWith('option', 'max', 120);
});
return it('update current value of the slider', function() {
return expect($.fn.slider).toHaveBeenCalledWith('value', 20);
it('update current value of the slider', function() {
expect($.fn.slider).toHaveBeenCalledWith('option', 'value', 20);
});
});
});
//TODO Fails: Problem with data-sub
describe('onSlide', function() {
beforeEach(function() {
this.player = jasmine.stubVideoPlayerAlpha(this);
this.progressSlider = this.player.progressSlider;
spyOnEvent(this.progressSlider, 'slide_seek');
return this.progressSlider.onSlide({}, {
initialize();
spyOn($.fn, 'slider').andCallThrough();
spyOnEvent(videoPlayer, 'onSlideSeek');
videoProgressSlider.onSlide({}, {
value: 20
});
});
it('freeze the slider', function() {
return expect(this.progressSlider.frozen).toBeTruthy();
expect(videoProgressSlider.frozen).toBeTruthy();
});
it('update the tooltip', function() {
return expect($.fn.qtip).toHaveBeenCalled();
expect($.fn.qtip).toHaveBeenCalled();
});
return it('trigger seek event', function() {
expect('slide_seek').toHaveBeenTriggeredOn(this.progressSlider);
return expect(this.player.currentTime).toEqual(20);
it('trigger seek event', function() {
expect('onSlideSeek').toHaveBeenTriggeredOn(videoPlayer);
expect(videoPlayer.currentTime).toEqual(20);
});
});
//End Fails
describe('onChange', function() {
beforeEach(function() {
this.player = jasmine.stubVideoPlayerAlpha(this);
this.progressSlider = this.player.progressSlider;
return this.progressSlider.onChange({}, {
initialize();
spyOn($.fn, 'slider').andCallThrough();
videoProgressSlider.onChange({}, {
value: 20
});
});
return it('update the tooltip', function() {
return expect($.fn.qtip).toHaveBeenCalled();
it('update the tooltip', function() {
expect($.fn.qtip).toHaveBeenCalled();
});
});
//TODO Fails: Problem with data-sub
describe('onStop', function() {
beforeEach(function() {
this.player = jasmine.stubVideoPlayerAlpha(this);
this.progressSlider = this.player.progressSlider;
spyOnEvent(this.progressSlider, 'slide_seek');
return this.progressSlider.onStop({}, {
initialize();
spyOnEvent(videoPlayer, 'onSlideSeek');
videoProgressSlider.onStop({}, {
value: 20
});
});
it('freeze the slider', function() {
return expect(this.progressSlider.frozen).toBeTruthy();
expect(videoProgressSlider.frozen).toBeTruthy();
});
it('trigger seek event', function() {
expect('slide_seek').toHaveBeenTriggeredOn(this.progressSlider);
return expect(this.player.currentTime).toEqual(20);
expect('onSlideSeek').toHaveBeenTriggeredOn(videoProgressSlider);
expect(videoPlayer.currentTime).toEqual(20);
});
return it('set timeout to unfreeze the slider', function() {
it('set timeout to unfreeze the slider', function() {
expect(window.setTimeout).toHaveBeenCalledWith(jasmine.any(Function), 200);
window.setTimeout.mostRecentCall.args[0]();
return expect(this.progressSlider.frozen).toBeFalsy();
expect(videoProgressSlider.frozen).toBeFalsy();
});
});
return describe('updateTooltip', function() {
//End Fails
describe('updateTooltip', function() {
beforeEach(function() {
this.player = jasmine.stubVideoPlayerAlpha(this);
this.progressSlider = this.player.progressSlider;
return this.progressSlider.updateTooltip(90);
initialize();
spyOn($.fn, 'slider').andCallThrough();
videoProgressSlider.updateTooltip(90);
});
return it('set the tooltip value', function() {
return expect($.fn.qtip).toHaveBeenCalledWith('option', 'content.text', '1:30');
it('set the tooltip value', function() {
expect($.fn.qtip).toHaveBeenCalledWith('option', 'content.text', '1:30');
});
});
});

View File

@@ -1,129 +1,128 @@
// Generated by CoffeeScript 1.6.3
(function() {
xdescribe('VideoSpeedControlAlpha', function() {
describe('VideoSpeedControlAlpha', function() {
var state, videoPlayer, videoControl, videoSpeedControl;
function initialize() {
loadFixtures('videoalpha_all.html');
state = new VideoAlpha('#example');
videoPlayer = state.videoPlayer;
videoControl = state.videoControl;
videoSpeedControl = state.videoSpeedControl;
}
beforeEach(function() {
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice').andReturn(false);
jasmine.stubVideoPlayerAlpha(this);
return $('.speeds').remove();
});
describe('constructor', function() {
describe('always', function() {
beforeEach(function() {
return this.speedControl = new VideoSpeedControlAlpha({
el: $('.secondary-controls'),
speeds: this.video.speeds,
currentSpeed: '1.0'
});
initialize();
});
it('add the video speed control to player', function() {
var li, secondaryControls,
_this = this;
var li, secondaryControls;
secondaryControls = $('.secondary-controls');
li = secondaryControls.find('.video_speeds li');
expect(secondaryControls).toContain('.speeds');
expect(secondaryControls).toContain('.video_speeds');
expect(secondaryControls.find('p.active').text()).toBe('1.0x');
expect(li.filter('.active')).toHaveData('speed', this.speedControl.currentSpeed);
expect(li.length).toBe(this.speedControl.speeds.length);
return $.each(li.toArray().reverse(), function(index, link) {
expect($(link)).toHaveData('speed', _this.speedControl.speeds[index]);
return expect($(link).find('a').text()).toBe(_this.speedControl.speeds[index] + 'x');
expect(li.filter('.active')).toHaveData('speed', videoSpeedControl.currentSpeed);
expect(li.length).toBe(videoSpeedControl.speeds.length);
$.each(li.toArray().reverse(), function(index, link) {
expect($(link)).toHaveData('speed', videoSpeedControl.speeds[index]);
// TODO: Fails
expect($(link).find('a').text()).toBe(videoSpeedControl.speeds[index] + 'x');
});
});
return it('bind to change video speed link', function() {
return expect($('.video_speeds a')).toHandleWith('click', this.speedControl.changeVideoSpeed);
it('bind to change video speed link', function() {
// TODO: Fails
expect($('.video_speeds a')).toHandleWith('click', videoSpeedControl.changeVideoSpeed);
});
});
describe('when running on touch based device', function() {
beforeEach(function() {
window.onTouchBasedDevice.andReturn(true);
$('.speeds').removeClass('open');
return this.speedControl = new VideoSpeedControlAlpha({
el: $('.secondary-controls'),
speeds: this.video.speeds,
currentSpeed: '1.0'
});
initialize();
});
return it('open the speed toggle on click', function() {
it('open the speed toggle on click', function() {
$('.speeds').click();
expect($('.speeds')).toHaveClass('open');
$('.speeds').click();
return expect($('.speeds')).not.toHaveClass('open');
expect($('.speeds')).not.toHaveClass('open');
});
});
return describe('when running on non-touch based device', function() {
describe('when running on non-touch based device', function() {
beforeEach(function() {
$('.speeds').removeClass('open');
return this.speedControl = new VideoSpeedControlAlpha({
el: $('.secondary-controls'),
speeds: this.video.speeds,
currentSpeed: '1.0'
});
initialize();
});
it('open the speed toggle on hover', function() {
$('.speeds').mouseenter();
expect($('.speeds')).toHaveClass('open');
$('.speeds').mouseleave();
return expect($('.speeds')).not.toHaveClass('open');
expect($('.speeds')).not.toHaveClass('open');
});
it('close the speed toggle on mouse out', function() {
$('.speeds').mouseenter().mouseleave();
return expect($('.speeds')).not.toHaveClass('open');
expect($('.speeds')).not.toHaveClass('open');
});
return it('close the speed toggle on click', function() {
it('close the speed toggle on click', function() {
$('.speeds').mouseenter().click();
return expect($('.speeds')).not.toHaveClass('open');
expect($('.speeds')).not.toHaveClass('open');
});
});
});
describe('changeVideoSpeed', function() {
beforeEach(function() {
this.speedControl = new VideoSpeedControlAlpha({
el: $('.secondary-controls'),
speeds: this.video.speeds,
currentSpeed: '1.0'
});
return this.video.setSpeed('1.0');
initialize();
videoSpeedControl.setSpeed(1.0);
});
describe('when new speed is the same', function() {
beforeEach(function() {
spyOnEvent(this.speedControl, 'speedChange');
return $('li[data-speed="1.0"] a').click();
spyOnEvent(videoPlayer, 'onSpeedChange');
$('li[data-speed="1.0"] a').click();
});
return it('does not trigger speedChange event', function() {
return expect('speedChange').not.toHaveBeenTriggeredOn(this.speedControl);
it('does not trigger speedChange event', function() {
expect('onSpeedChange').not.toHaveBeenTriggeredOn(videoPlayer);
});
});
return describe('when new speed is not the same', function() {
describe('when new speed is not the same', function() {
beforeEach(function() {
var _this = this;
this.newSpeed = null;
$(this.speedControl).bind('speedChange', function(event, newSpeed) {
return _this.newSpeed = newSpeed;
});
spyOnEvent(this.speedControl, 'speedChange');
return $('li[data-speed="0.75"] a').click();
spyOnEvent(videoPlayer, 'onSpeedChange');
$('li[data-speed="0.75"] a').click();
});
return it('trigger speedChange event', function() {
expect('speedChange').toHaveBeenTriggeredOn(this.speedControl);
return expect(this.newSpeed).toEqual(0.75);
it('trigger speedChange event', function() {
// TODO: Fails
expect('onSpeedChange').toHaveBeenTriggeredOn(videoPlayer);
// TODO: Fails
expect(videoSpeedControl.currentSpeed).toEqual(0.75);
});
});
});
return describe('onSpeedChange', function() {
describe('onSpeedChange', function() {
beforeEach(function() {
this.speedControl = new VideoSpeedControlAlpha({
el: $('.secondary-controls'),
speeds: this.video.speeds,
currentSpeed: '1.0'
});
initialize();
$('li[data-speed="1.0"] a').addClass('active');
return this.speedControl.setSpeed('0.75');
videoSpeedControl.setSpeed(0.75);
});
return it('set the new speed as active', function() {
it('set the new speed as active', function() {
expect($('.video_speeds li[data-speed="1.0"]')).not.toHaveClass('active');
expect($('.video_speeds li[data-speed="0.75"]')).toHaveClass('active');
return expect($('.speeds p.active')).toHaveHtml('0.75x');
expect($('.speeds p.active')).toHaveHtml('0.75x');
});
});
});

View File

@@ -1,110 +1,118 @@
(function() {
describe('VideoVolumeControlAlpha', function() {
var state, player;
var state, videoControl, videoVolumeControl;
function initialize() {
loadFixtures('videoalpha_all.html');
state = new VideoAlpha('#example');
videoControl = state.videoControl;
videoVolumeControl = state.videoVolumeControl;
}
describe('constructor', function() {
beforeEach(function() {
// spyOn($.fn, 'slider');
state = jasmine.stubVideoPlayerAlpha(this);
player = state.videoPlayer.player;
spyOn($.fn, 'slider').andCallThrough();
initialize();
});
it('initialize currentVolume to 100', function() {
return expect(state.videoVolumeControl.currentVolume).toEqual(1);
expect(state.videoVolumeControl.currentVolume).toEqual(1);
});
it('render the volume control', function() {
return expect($('.secondary-controls').html()).toContain("<div class=\"volume\">\n <a href=\"#\"></a>\n <div class=\"volume-slider-container\">\n <div class=\"volume-slider\"></div>\n </div>\n</div>");
expect(videoControl.secondaryControlsEl.html()).toContain("<div class=\"volume\">\n"); //toContain("<div class=\"volume\">\n <a href=\"#\"></a>\n <div class=\"volume-slider-container\">\n <div class=\"volume-slider\"></div>\n </div>\n</div>");
});
it('create the slider', function() {
return expect($.fn.slider).toHaveBeenCalledWith({
expect($.fn.slider).toHaveBeenCalledWith({
orientation: "vertical",
range: "min",
min: 0,
max: 100,
value: 100,
change: this.volumeControl.onChange,
slide: this.volumeControl.onChange
value: videoVolumeControl.currentVolume,
change: videoVolumeControl.onChange,
slide: videoVolumeControl.onChange
});
});
return it('bind the volume control', function() {
expect($('.volume>a')).toHandleWith('click', this.volumeControl.toggleMute);
it('bind the volume control', function() {
expect($('.volume>a')).toHandleWith('click', videoVolumeControl.toggleMute);
expect($('.volume')).not.toHaveClass('open');
$('.volume').mouseenter();
expect($('.volume')).toHaveClass('open');
$('.volume').mouseleave();
return expect($('.volume')).not.toHaveClass('open');
expect($('.volume')).not.toHaveClass('open');
});
});
describe('onChange', function() {
beforeEach(function() {
var _this = this;
spyOnEvent(this.volumeControl, 'volumeChange');
this.newVolume = void 0;
this.volumeControl = new VideoVolumeControlAlpha({
el: $('.secondary-controls')
});
return $(this.volumeControl).bind('volumeChange', function(event, volume) {
return _this.newVolume = volume;
});
initialize();
});
describe('when the new volume is more than 0', function() {
beforeEach(function() {
return this.volumeControl.onChange(void 0, {
videoVolumeControl.onChange(void 0, {
value: 60
});
});
it('set the player volume', function() {
return expect(this.newVolume).toEqual(60);
expect(videoVolumeControl.currentVolume).toEqual(60);
});
return it('remote muted class', function() {
return expect($('.volume')).not.toHaveClass('muted');
it('remote muted class', function() {
expect($('.volume')).not.toHaveClass('muted');
});
});
return describe('when the new volume is 0', function() {
describe('when the new volume is 0', function() {
beforeEach(function() {
return this.volumeControl.onChange(void 0, {
videoVolumeControl.onChange(void 0, {
value: 0
});
});
it('set the player volume', function() {
return expect(this.newVolume).toEqual(0);
expect(videoVolumeControl.currentVolume).toEqual(0);
});
return it('add muted class', function() {
return expect($('.volume')).toHaveClass('muted');
it('add muted class', function() {
expect($('.volume')).toHaveClass('muted');
});
});
});
return describe('toggleMute', function() {
describe('toggleMute', function() {
beforeEach(function() {
var _this = this;
this.newVolume = void 0;
this.volumeControl = new VideoVolumeControlAlpha({
el: $('.secondary-controls')
});
return $(this.volumeControl).bind('volumeChange', function(event, volume) {
return _this.newVolume = volume;
});
initialize();
});
describe('when the current volume is more than 0', function() {
beforeEach(function() {
this.volumeControl.currentVolume = 60;
return this.volumeControl.toggleMute();
videoVolumeControl.currentVolume = 60;
videoVolumeControl.buttonEl.trigger('click');
});
it('save the previous volume', function() {
return expect(this.volumeControl.previousVolume).toEqual(60);
expect(videoVolumeControl.previousVolume).toEqual(60);
});
return it('set the player volume', function() {
return expect(this.newVolume).toEqual(0);
it('set the player volume', function() {
expect(videoVolumeControl.currentVolume).toEqual(0);
});
});
return describe('when the current volume is 0', function() {
describe('when the current volume is 0', function() {
beforeEach(function() {
this.volumeControl.currentVolume = 0;
this.volumeControl.previousVolume = 60;
return this.volumeControl.toggleMute();
videoVolumeControl.currentVolume = 0;
videoVolumeControl.previousVolume = 60;
videoVolumeControl.buttonEl.trigger('click');
});
return it('set the player volume to previous volume', function() {
return expect(this.newVolume).toEqual(60);
it('set the player volume to previous volume', function() {
expect(videoVolumeControl.currentVolume).toEqual(60);
});
});
});

View File

@@ -30,7 +30,6 @@
describe('YT', function () {
beforeEach(function () {
loadFixtures('videoalpha.html');
// TO DO??? this.stubbedVideoPlayer = jasmine.createSpy('StubbedVideoPlayer');
$.cookie.andReturn('0.75');
});

View File

@@ -26,7 +26,7 @@ function (VideoPlayer) {
*/
return function (state, element) {
makeFunctionsPublic(state);
renderElements(state, element);
state.renderElements(element);
};
// ***************************************************************
@@ -46,6 +46,14 @@ function (VideoPlayer) {
state.youtubeId = youtubeId.bind(state);
state.getDuration = getDuration.bind(state);
state.trigger = trigger.bind(state);
// Old private functions. Now also public so that can be
// tested by Jasmine.
state.renderElements = renderElements.bind(state);
state.parseSpeed = parseSpeed.bind(state);
state.fetchMetadata = fetchMetadata.bind(state);
state.parseYoutubeStreams = parseYoutubeStreams.bind(state);
state.parseVideoSources = parseVideoSources.bind(state);
}
// function renderElements(state)
@@ -53,33 +61,34 @@ function (VideoPlayer) {
// Create any necessary DOM elements, attach them, and set their initial configuration. Also
// make the created DOM elements available via the 'state' object. Much easier to work this
// way - you don't have to do repeated jQuery element selects.
function renderElements(state, element) {
var onPlayerReadyFunc;
function renderElements(element) {
var onPlayerReadyFunc,
_this = this;
// This is used in places where we instead would have to check if an element has a CSS class 'fullscreen'.
state.isFullScreen = false;
this.isFullScreen = false;
// The parent element of the video, and the ID.
state.el = $(element).find('.videoalpha');
state.id = state.el.attr('id').replace(/video_/, '');
this.el = $(element).find('.videoalpha');
this.id = this.el.attr('id').replace(/video_/, '');
// We store all settings passed to us by the server in one place. These are "read only", so don't
// modify them. All variable content lives in 'state' object.
state.config = {
this.config = {
element: element,
start: state.el.data('start'),
end: state.el.data('end'),
start: this.el.data('start'),
end: this.el.data('end'),
caption_data_dir: state.el.data('caption-data-dir'),
caption_asset_path: state.el.data('caption-asset-path'),
show_captions: (state.el.data('show-captions').toString().toLowerCase() === 'true'),
youtubeStreams: state.el.data('streams'),
caption_data_dir: this.el.data('caption-data-dir'),
caption_asset_path: this.el.data('caption-asset-path'),
show_captions: (this.el.data('show-captions').toString().toLowerCase() === 'true'),
youtubeStreams: this.el.data('streams'),
sub: state.el.data('sub'),
mp4Source: state.el.data('mp4-source'),
webmSource: state.el.data('webm-source'),
oggSource: state.el.data('ogg-source'),
sub: this.el.data('sub'),
mp4Source: this.el.data('mp4-source'),
webmSource: this.el.data('webm-source'),
oggSource: this.el.data('ogg-source'),
fadeOutTimeout: 1400,
@@ -94,66 +103,65 @@ function (VideoPlayer) {
};
// Try to parse YouTube stream ID's. If
if (parseYoutubeStreams(state, state.config.youtubeStreams)) {
state.videoType = 'youtube';
if (this.parseYoutubeStreams(this.config.youtubeStreams)) {
this.videoType = 'youtube';
fetchMetadata(state);
parseSpeed(state);
this.fetchMetadata();
this.parseSpeed();
}
// If we do not have YouTube ID's, try parsing HTML5 video sources.
else {
state.videoType = 'html5';
this.videoType = 'html5';
parseVideoSources(
state,
this.parseVideoSources(
{
mp4: state.config.mp4Source,
webm: state.config.webmSource,
ogg: state.config.oggSource
mp4: this.config.mp4Source,
webm: this.config.webmSource,
ogg: this.config.oggSource
}
);
if (!state.config.sub || !state.config.sub.length) {
state.config.sub = '';
state.config.show_captions = false;
if (!this.config.sub || !this.config.sub.length) {
this.config.sub = '';
this.config.show_captions = false;
}
state.speeds = ['0.75', '1.0', '1.25', '1.50'];
state.videos = {
'0.75': state.config.sub,
'1.0': state.config.sub,
'1.25': state.config.sub,
'1.5': state.config.sub
this.speeds = ['0.75', '1.0', '1.25', '1.50'];
this.videos = {
'0.75': this.config.sub,
'1.0': this.config.sub,
'1.25': this.config.sub,
'1.5': this.config.sub
};
state.setSpeed($.cookie('video_speed'));
this.setSpeed($.cookie('video_speed'));
}
// Configure displaying of captions.
//
// Option
//
// state.config.show_captions = true | false
// this.config.show_captions = true | false
//
// defines whether to turn off/on the captions altogether. User will not have the ability to turn them on/off.
//
// Option
//
// state.hide_captions = true | false
// this.hide_captions = true | false
//
// represents the user's choice of having the subtitles shown or hidden. This choice is stored in cookies.
if (state.config.show_captions) {
state.hide_captions = ($.cookie('hide_captions') === 'true');
if (this.config.show_captions) {
this.hide_captions = ($.cookie('hide_captions') === 'true');
} else {
state.hide_captions = true;
this.hide_captions = true;
$.cookie('hide_captions', state.hide_captions, {
$.cookie('hide_captions', this.hide_captions, {
expires: 3650,
path: '/'
});
state.el.addClass('closed');
this.el.addClass('closed');
}
// By default we will be forcing HTML5 player mode. Only in the case when, after initializtion, we will
@@ -163,21 +171,21 @@ function (VideoPlayer) {
// the proper mode from the start (not having to change mode later on).
(function (currentPlayerMode) {
if ((currentPlayerMode === 'html5') || (currentPlayerMode === 'flash')) {
state.currentPlayerMode = currentPlayerMode;
_this.currentPlayerMode = currentPlayerMode;
} else {
$.cookie('current_player_mode', 'html5', {
expires: 3650,
path: '/'
});
state.currentPlayerMode = 'html5';
_this.currentPlayerMode = 'html5';
}
}($.cookie('current_player_mode')));
// Possible value are: 'visible', 'hiding', and 'invisible'.
state.controlState = 'visible';
state.controlHideTimeout = null;
state.captionState = 'visible';
state.captionHideTimeout = null;
this.controlState = 'visible';
this.controlHideTimeout = null;
this.captionState = 'visible';
this.captionHideTimeout = null;
// Launch embedding of actual video content, or set it up so that it will be done as soon as the
// appropriate video player (YouTube or stand alone HTML5) is loaded, and can handle embedding.
@@ -186,13 +194,13 @@ function (VideoPlayer) {
// when we reach this code, the stand alone HTML5 player is already loaded, so no further testing
// in that case is required.
if (
((state.videoType === 'youtube') && (window.YT) && (window.YT.Player)) ||
(state.videoType === 'html5')
((this.videoType === 'youtube') && (window.YT) && (window.YT.Player)) ||
(this.videoType === 'html5')
) {
VideoPlayer(state);
VideoPlayer(this);
} else {
onPlayerReadyFunc = (state.videoType === 'youtube') ? 'onYouTubePlayerAPIReady' : 'onHTML5PlayerAPIReady';
window[onPlayerReadyFunc] = VideoPlayer.bind(window, state);
onPlayerReadyFunc = (this.videoType === 'youtube') ? 'onYouTubePlayerAPIReady' : 'onHTML5PlayerAPIReady';
window[onPlayerReadyFunc] = VideoPlayer.bind(window, this);
}
}
@@ -206,14 +214,15 @@ function (VideoPlayer) {
// @return
// false: We don't have YouTube video IDs to work with; most likely we have HTML5 video sources.
// true: Parsing of YouTube video IDs went OK, and we can proceed onwards to play YouTube videos.
function parseYoutubeStreams(youtubeStreams) {
var _this;
function parseYoutubeStreams(state, youtubeStreams) {
if (typeof youtubeStreams === 'undefined' || youtubeStreams.length === 0) {
return false;
}
state.videos = {};
_this = this;
this.videos = {};
$.each(youtubeStreams.split(/,/), function(index, video) {
var speed;
@@ -221,18 +230,20 @@ function (VideoPlayer) {
video = video.split(/:/);
speed = parseFloat(video[0]).toFixed(2).replace(/\.00$/, '.0');
state.videos[speed] = video[1];
_this.videos[speed] = video[1];
});
return true;
}
// function parseVideoSources(state, mp4Source, webmSource, oggSource)
// function parseVideoSources(, mp4Source, webmSource, oggSource)
//
// Take the HTML5 sources (URLs of videos), and make them available explictly for each type
// of video format (mp4, webm, ogg).
function parseVideoSources(state, sources) {
state.html5Sources = {
function parseVideoSources(sources) {
var _this = this;
this.html5Sources = {
mp4: null,
webm: null,
ogg: null
@@ -240,35 +251,37 @@ function (VideoPlayer) {
$.each(sources, function (name, source) {
if (source && source.length) {
state.html5Sources[name] = source;
_this.html5Sources[name] = source;
}
});
}
// function fetchMetadata(state)
// function fetchMetadata()
//
// When dealing with YouTube videos, we must fetch meta data that has certain key facts
// not available while the video is loading. For example the length of the video can be
// determined from the meta data.
function fetchMetadata(state) {
state.metadata = {};
function fetchMetadata() {
var _this = this;
$.each(state.videos, function (speed, url) {
this.metadata = {};
$.each(this.videos, function (speed, url) {
$.get('https://gdata.youtube.com/feeds/api/videos/' + url + '?v=2&alt=jsonc', (function(data) {
state.metadata[data.data.id] = data.data;
_this.metadata[data.data.id] = data.data;
}), 'jsonp');
});
}
// function parseSpeed(state)
// function parseSpeed()
//
// Create a separate array of available speeds.
function parseSpeed(state) {
state.speeds = ($.map(state.videos, function(url, speed) {
function parseSpeed() {
this.speeds = ($.map(this.videos, function(url, speed) {
return speed;
})).sort();
state.setSpeed($.cookie('video_speed'));
this.setSpeed($.cookie('video_speed'));
}
// ***************************************************************

View File

@@ -43,6 +43,8 @@ function () {
state.videoCaption.hideCaptions = hideCaptions.bind(state);
state.videoCaption.calculateOffset = calculateOffset.bind(state);
state.videoCaption.updatePlayTime = updatePlayTime.bind(state);
//Added for tests --> JM
state.videoCaption.fetchCaption = fetchCaption.bind(state);
}
// function renderElements(state)
@@ -315,7 +317,7 @@ function () {
event.preventDefault();
time = Math.round(Time.convert($(event.target).data('start'), '1.0', this.speed) / 1000);
this.trigger(['videoPlayer', 'onCaptionSeek'], time);
this.trigger(['videoPlayer', 'onCaptionSeek'], {'type': 'onCaptionSeek', 'time': time});
}
function calculateOffset(element) {

View File

@@ -226,26 +226,26 @@ function (HTML5Video) {
}
}
function onSeek(event, time) {
function onSeek(params) {
this.videoPlayer.log(
'seek_video',
{
old_time: this.videoPlayer.currentTime,
new_time: time,
type: event.type
new_time: params.time,
type: params.type
}
);
this.videoPlayer.player.seekTo(time, true);
this.videoPlayer.player.seekTo(params.time, true);
if (this.videoPlayer.isPlaying()) {
clearInterval(this.videoPlayer.updateInterval);
this.videoPlayer.updateInterval = setInterval(this.videoPlayer.update, 200);
} else {
this.videoPlayer.currentTime = time;
this.videoPlayer.currentTime = params.time;
}
this.videoPlayer.updatePlayTime(time);
this.videoPlayer.updatePlayTime(params.time);
}
function onEnded() {
@@ -368,14 +368,14 @@ function (HTML5Video) {
}
function duration() {
var duration;
var dur;
duration = this.videoPlayer.player.getDuration();
if (!isFinite(duration)) {
duration = this.getDuration();
dur = this.videoPlayer.player.getDuration();
if (!isFinite(dur)) {
dur = this.getDuration();
}
return duration;
return dur;
}
function log(eventName, data) {

View File

@@ -36,6 +36,8 @@ function () {
state.videoProgressSlider.onStop = onStop.bind(state);
state.videoProgressSlider.updateTooltip = updateTooltip.bind(state);
state.videoProgressSlider.updatePlayTime = updatePlayTime.bind(state);
//Added for tests -- JM
state.videoProgressSlider.buildSlider = buildSlider.bind(state);
}
// function renderElements(state)
@@ -97,7 +99,8 @@ function () {
function onSlide(event, ui) {
this.videoProgressSlider.frozen = true;
this.videoProgressSlider.updateTooltip(ui.value);
this.trigger(['videoPlayer', 'onSlideSeek'], ui.value);
this.trigger(['videoPlayer', 'onSlideSeek'], {'type': 'onSlideSeek', 'time': ui.value});
}
function onChange(event, ui) {
@@ -109,7 +112,7 @@ function () {
this.videoProgressSlider.frozen = true;
this.trigger(['videoPlayer', 'onSlideSeek'], ui.value);
this.trigger(['videoPlayer', 'onSlideSeek'], {'type': 'onSlideSeek', 'time': ui.value});
setTimeout(function() {
_this.videoProgressSlider.frozen = false;
@@ -120,11 +123,14 @@ function () {
this.videoProgressSlider.handle.qtip('option', 'content.text', '' + Time.format(value));
}
//Changed for tests -- JM: Check if it is the cause of Chrome Bug Valera noticed
function updatePlayTime(params) {
if ((this.videoProgressSlider.slider) && (!this.videoProgressSlider.frozen)) {
this.videoProgressSlider.slider
/*this.videoProgressSlider.slider
.slider('option', 'max', params.duration)
.slider('value', params.time);
.slider('value', params.time);*/
this.videoProgressSlider.slider.slider('option', 'max', params.duration);
this.videoProgressSlider.slider.slider('option', 'value', params.time);
}
}