Commit 6ba5d472 by Anton Stupak Committed by Alexander Kryklia

Fix with sequence switching and more.

Studio: adds in new Sass file for Studio-specific
xmodule presentation and removes full screen control
from video alpha display UI.
Adds jasmine test for subtitles scroll.
Adds tests for caption change height functionality.
Uses gettext wrapper.
Fixes caption change height functionality.
Removes IS_CMS, isCms flags.
parent 65aa7d4f
......@@ -31,8 +31,6 @@ from path import path
############################ FEATURE CONFIGURATION #############################
MITX_FEATURES = {
'IS_CMS': True,
'USE_DJANGO_PIPELINE': True,
'GITHUB_PUSH': False,
......
......@@ -66,6 +66,7 @@
// xmodule
@import 'xmodule/modules/css/module-styles.scss';
@import 'xmodule/descriptors/css/module-styles.scss';
@import 'elements/xmodules'; // styling for Studio-specific contexts
@import 'shame'; // shame file - used for any bad-form/orphaned scss that knowingly violate edX FED architecture/standards (see - http://csswizardry.com/2013/04/shame-css/)
// studio - elements - xmodules
// ====================
// Video Alpha
.xmodule_VideoAlphaModule {
// display mode
&.xmodule_display {
// full screen
.video-controls .add-fullscreen {
display: none !important; // nasty, but needed to override the bad specificity of the xmodule css selectors
}
}
}
......@@ -8,6 +8,7 @@
videoPlayer = state.videoPlayer;
videoCaption = state.videoCaption;
videoSpeedControl = state.videoSpeedControl;
videoControl = state.videoControl;
}
beforeEach(function() {
......@@ -72,6 +73,11 @@
expect($('.subtitles')).toHandleWith('mousewheel', videoCaption.onMovement);
expect($('.subtitles')).toHandleWith('DOMMouseScroll', videoCaption.onMovement);
});
it('bind the scroll', function() {
expect($('.subtitles')).toHandleWith('scroll', videoCaption.autoShowCaptions);
expect($('.subtitles')).toHandleWith('scroll', videoControl.showControls);
});
});
describe('when on a non touch-based device', function() {
......@@ -352,8 +358,28 @@
videoCaption.resize();
});
it('set the height of caption container', function() {
expect(parseInt($('.subtitles').css('maxHeight'), 10)).toBeCloseTo($('.video-wrapper').height(), 2);
describe('set the height of caption container', function(){
it('when CC button is enabled', function() {
var realHeight = parseInt($('.subtitles').css('maxHeight'), 10),
shouldBeHeight = $('.video-wrapper').height();
// Because of some problems with rounding on different enviroments:
// Linux * Mac * FF * Chrome
expect(realHeight).toBeCloseTo(shouldBeHeight, 2);
});
it('when CC button is disabled ', function() {
var realHeight = parseInt($('.subtitles').css('maxHeight'), 10),
videoWrapperHeight = $('.video-wrapper').height(),
controlsHeight = videoControl.el.height(),
progressSliderHeight = videoControl.sliderEl.height(),
shouldBeHeight = videoWrapperHeight - controlsHeight \
- 0.5 * controlsHeight;
state.captionsHidden = true;
videoCaption.setSubtitlesHeight();
expect(realHeight).toBeCloseTo($('.video-wrapper').height(shouldBeHeight, 2));
});
});
it('set the height of caption spacing', function() {
......
......@@ -87,6 +87,9 @@ class @Sequence
modx_full_url = @modx_url + '/' + @id + '/goto_position'
$.postWithPrefix modx_full_url, position: new_position
# On Sequence change, fire custom event "sequence:change" on element.
# Added for aborting video bufferization, see ../videoalpha/10_main.js
@el.trigger "sequence:change"
@mark_active new_position
@$('#seq_content').html @contents.eq(new_position - 1).text()
XModule.loadModules(@$('#seq_content'))
......@@ -140,7 +143,7 @@ class @Sequence
analytics.track "Accessed Next Sequential",
sequence_id: @id
current_sequential: @position
target_sequential: new_position
target_sequential: new_position
@render new_position
......
......@@ -16,6 +16,10 @@ define(
['videoalpha/03_video_player.js'],
function (VideoPlayer) {
if (typeof(window.gettext) == "undefined") {
window.gettext = function(s){return s;};
}
/**
* @function
*
......@@ -47,6 +51,7 @@ function (VideoPlayer) {
state.youtubeId = _.bind(youtubeId, state);
state.getDuration = _.bind(getDuration, state);
state.trigger = _.bind(trigger, state);
state.stopBuffering = _.bind(stopBuffering, state);
// Old private functions. Now also public so that can be
// tested by Jasmine.
......@@ -95,9 +100,7 @@ function (VideoPlayer) {
my: 'top right',
at: 'top center'
}
},
inCms: state.el.data('in-studio')
}
};
if (!(_parseYouTubeIDs(state))) {
......@@ -333,6 +336,18 @@ function (VideoPlayer) {
}
}
function stopBuffering() {
var video;
if (this.videoType === 'html5'){
// HTML5 player haven't default way to abort bufferization.
// In this case we simply resetting source and call load().
video = this.videoPlayer.player.video;
video.src = '';
video.load();
}
}
function youtubeId(speed) {
return this.videos[speed || this.speed];
}
......
......@@ -51,10 +51,6 @@ function () {
state.videoControl.fullScreenState = false;
if (state.config.inCms === 'True') {
state.videoControl.fullScreenEl.hide();
}
if (!onTouchBasedDevice()) {
state.videoControl.pause();
......@@ -133,12 +129,12 @@ function () {
}
function play() {
this.videoControl.playPauseEl.removeClass('play').addClass('pause').attr('title', 'Pause');
this.videoControl.playPauseEl.removeClass('play').addClass('pause').attr('title', gettext('Pause'));
this.videoControl.isPlaying = true;
}
function pause() {
this.videoControl.playPauseEl.removeClass('pause').addClass('play').attr('title', 'Play');
this.videoControl.playPauseEl.removeClass('pause').addClass('play').attr('title', gettext('Play'));
this.videoControl.isPlaying = false;
}
......@@ -160,12 +156,12 @@ function () {
this.videoControl.fullScreenState = false;
fullScreenClassNameEl.removeClass('video-fullscreen');
this.isFullScreen = false;
this.videoControl.fullScreenEl.attr('title', 'Fullscreen');
this.videoControl.fullScreenEl.attr('title', gettext('Fullscreen'));
} else {
this.videoControl.fullScreenState = true;
fullScreenClassNameEl.addClass('video-fullscreen');
this.isFullScreen = true;
this.videoControl.fullScreenEl.attr('title', 'Exit fullscreen');
this.videoControl.fullScreenEl.attr('title', gettext('Exit fullscreen'));
}
this.trigger('videoCaption.resize', null);
......
......@@ -43,7 +43,7 @@ function () {
state.videoCaption.hideCaptions = _.bind(hideCaptions, state);
state.videoCaption.calculateOffset = _.bind(calculateOffset, state);
state.videoCaption.updatePlayTime = _.bind(updatePlayTime, state);
state.videoCaption.setSubtitlesHeight = _.bind(setSubtitlesHeight, state);
state.videoCaption.setSubtitlesHeight = _.bind(setSubtitlesHeight, state);
state.videoCaption.renderElements = _.bind(renderElements, state);
state.videoCaption.bindHandlers = _.bind(bindHandlers, state);
......@@ -71,9 +71,8 @@ function () {
this.el.find('.video-wrapper').after(this.videoCaption.subtitlesEl);
this.el.find('.video-controls .secondary-controls').append(this.videoCaption.hideSubtitlesEl);
this.videoCaption.setSubtitlesHeight();
this.videoCaption.fetchCaption();
this.videoCaption.setSubtitlesHeight();
if (this.videoType === 'html5') {
this.videoCaption.fadeOutTimeout = this.config.fadeOutTimeout;
......@@ -133,7 +132,7 @@ function () {
if (onTouchBasedDevice()) {
_this.videoCaption.subtitlesEl.find('li').html(
'Caption will be displayed when you start playing the video.'
gettext('Caption will be displayed when you start playing the video.')
);
} else {
_this.videoCaption.renderCaption();
......@@ -189,14 +188,13 @@ function () {
}
function resize() {
this.videoCaption.setSubtitlesHeight();
this.videoCaption.subtitlesEl
.find('.spacing:first').height(this.videoCaption.topSpacingHeight())
.find('.spacing:last').height(this.videoCaption.bottomSpacingHeight());
this.videoCaption.scrollCaption();
this.videoCaption.setSubtitlesHeight();
}
function onMouseEnter() {
......@@ -363,12 +361,12 @@ function () {
if (hide_captions) {
type = 'hide_transcript';
this.captionsHidden = true;
this.videoCaption.hideSubtitlesEl.attr('title', 'Turn on captions');
this.videoCaption.hideSubtitlesEl.attr('title', gettext('Turn on captions'));
this.el.addClass('closed');
} else {
type = 'show_transcript';
this.captionsHidden = false;
this.videoCaption.hideSubtitlesEl.attr('title', 'Turn off captions');
this.videoCaption.hideSubtitlesEl.attr('title', gettext('Turn off captions'));
this.el.removeClass('closed');
this.videoCaption.scrollCaption();
}
......@@ -379,6 +377,8 @@ function () {
});
}
this.videoCaption.setSubtitlesHeight();
$.cookie('hide_captions', hide_captions, {
expires: 3650,
path: '/'
......@@ -387,7 +387,9 @@ function () {
function captionHeight() {
if (this.isFullScreen) {
return $(window).height() - this.el.find('.video-controls').height();
return $(window).height() - this.el.find('.video-controls').height() -
0.5 * this.videoControl.sliderEl.height() -
2 * parseInt(this.videoCaption.subtitlesEl.css('padding-top'), 10);
} else {
return this.el.find('.video-wrapper').height();
}
......@@ -395,15 +397,18 @@ function () {
function setSubtitlesHeight() {
var height = 0;
if (this.videoType === 'html5')
if ( (this.captionsHidden === undefined && this.hide_captions === true ) ||
(this.captionsHidden === true) ) {
// In case of html5 autoshowing subtitles,
// we ajdust height of subs, by height of scrollbar
height = this.videoControl.el.height() + this.videoControl.sliderEl.height() / 2;
// height of videoControl does not contain height of slider.
// (css is set to absolute, to avoid yanking when slider autochanges its height)
}
if (this.videoType === 'html5'){
// on page load captionHidden = undefined
if (
(this.captionsHidden === undefined && this.hide_captions === true ) ||
(this.captionsHidden === true) ) {
// In case of html5 autoshowing subtitles,
// we ajdust height of subs, by height of scrollbar
height = this.videoControl.el.height() + 0.5 * this.videoControl.sliderEl.height();
// height of videoControl does not contain height of slider.
// (css is set to absolute, to avoid yanking when slider autochanges its height)
}
}
this.videoCaption.subtitlesEl.css({
maxHeight: this.videoCaption.captionHeight() - height
});
......
......@@ -34,6 +34,17 @@ function (
window.VideoAlpha = function (element) {
var state;
// Stop bufferization of previous video on sequence change.
// Problem: multiple video tags with the same src cannot
// play together. The second tag waiting when first video will be fully loaded.
// That's why we abort bufferization forcibly.
$(element).closest('.sequence').bind('sequence:change', function(e){
if (previousState !== null && typeof previousState.videoPlayer !== 'undefined') {
previousState.stopBuffering();
$(e.currentTarget).unbind('sequence:change');
}
});
// Check for existance of previous state, uninitialize it if necessary, and create a new state.
// Store new state for future invocation of this module consturctor function.
if (previousState !== null && typeof previousState.videoPlayer !== 'undefined') {
......
......@@ -14,12 +14,12 @@ class PollModuleTest(LogicTest):
}
def test_bad_ajax_request(self):
"Make sure that answer for incorrect request is error json"
# Make sure that answer for incorrect request is error json.
response = self.ajax_request('bad_answer', {})
self.assertDictEqual(response, {'error': 'Unknown Command!'})
def test_good_ajax_request(self):
"Make shure that ajax request works correctly"
# Make sure that ajax request works correctly.
response = self.ajax_request('No', {})
poll_answers = response['poll_answers']
......
......@@ -141,11 +141,11 @@ class VideoAlphaModule(VideoAlphaFields, XModule):
if str_time is None:
return ''
else:
x = time.strptime(str_time, '%H:%M:%S')
obj_time = time.strptime(str_time, '%H:%M:%S')
return datetime.timedelta(
hours=x.tm_hour,
minutes=x.tm_min,
seconds=x.tm_sec
hours=obj_time.tm_hour,
minutes=obj_time.tm_min,
seconds=obj_time.tm_sec
).total_seconds()
return parse_time(xmltree.get('start_time')), parse_time(xmltree.get('end_time'))
......
......@@ -46,7 +46,6 @@ DISCUSSION_SETTINGS = {
# Features
MITX_FEATURES = {
'IS_CMS': False,
'SAMPLE': False,
'USE_DJANGO_PIPELINE': True,
'DISPLAY_HISTOGRAMS_TO_STAFF': True,
......
......@@ -12,8 +12,6 @@
data-streams="${youtube_streams}"
% endif
data-in-studio="${settings.MITX_FEATURES['IS_CMS']}"
${'data-sub="{}"'.format(sub) if sub else ''}
${'data-autoplay="{}"'.format(autoplay) if autoplay else ''}
% if not settings.MITX_FEATURES['STUB_VIDEO_FOR_TESTING']:
......@@ -40,13 +38,13 @@
<div class="slider"></div>
<div>
<ul class="vcr">
<li><a class="video_control" href="#" title="Play"></a></li>
<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>
<h3>${_('Speed')}</h3>
<p class="active"></p>
</a>
<ol class="video_speeds"></ol>
......@@ -57,11 +55,11 @@
<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="add-fullscreen" title="${_('Fill browser')}">${_('Fill browser')}</a>
<a href="#" class="quality_control" title="${_('HD')}">${_('HD')}</a>
% if show_captions == 'true':
<a href="#" class="hide-subtitles" title="Turn off captions">Captions</a>
<a href="#" class="hide-subtitles" title="${_('Turn off captions')}">${_('Captions')}</a>
% endif
</div>
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment