Commit 2997a80a by polesye Committed by jmclaus

Video link obfuscation. [BLD-1230]

parent 7593ad3a
......@@ -17,11 +17,6 @@
.xmodule_VideoModule {
// display mode
&.xblock-student_view {
// full screen
.video-controls .add-fullscreen {
display: none !important; // nasty, but needed to override the bad specificity of the xmodule css selectors
}
.video-tracks {
.a11y-menu-container {
.a11y-menu-list {
......
......@@ -131,3 +131,96 @@ $a11y--blue-s1: saturate($blue,15%);
}
}
}
.contextmenu, .submenu {
border: 1px solid #333;
background: #fff;
color: #333;
padding: 0;
margin: 0;
list-style: none;
position: absolute;
top: 0;
display: none;
z-index: 999999;
outline: none;
cursor: default;
white-space: nowrap;
&.is-opened {
display: block;
}
.menu-item, .submenu-item {
border-top: 1px solid #ccc;
padding: 5px 10px;
outline: none;
& > span {
color: #333;
}
&:first-child {
border-top: none;
}
&:focus {
background: #333;
color: #fff;
& > span {
color: #fff;
}
}
}
.submenu-item {
position: relative;
padding: 5px 20px 5px 10px;
&:after {
content: '\25B6';
position: absolute;
right: 5px;
line-height: 25px;
font-size: 10px;
}
.submenu {
display: none;
}
&.is-opened {
background: #333;
color: #fff;
& > span {
color: #fff;
}
& > .submenu {
display: block;
}
}
.is-selected {
font-weight: bold;
}
}
.is-disabled {
pointer-events: none;
color: #ccc;
}
}
.overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 900000;
background-color: transparent;
}
......@@ -689,8 +689,9 @@ div.video {
position: fixed;
top: 0;
width: 100%;
z-index: 999;
z-index: 9999;
vertical-align: middle;
border-radius: 0;
&.closed {
div.tc-wrapper {
......
(function (define) {
'use strict';
define('video/00_component.js', [],
function () {
/**
* Creates a new object with the specified prototype object and properties.
* @param {Object} o The object which should be the prototype of the
* newly-created object.
* @private
* @throws {TypeError, Error}
* @return {Object}
*/
var inherit = Object.create || (function () {
var F = function () {};
return function (o) {
if (arguments.length > 1) {
throw Error('Second argument not supported');
}
if (_.isNull(o) || _.isUndefined(o)) {
throw Error('Cannot set a null [[Prototype]]');
}
if (!_.isObject(o)) {
throw TypeError('Argument must be an object');
}
F.prototype = o;
return new F();
};
})();
/**
* Component module.
* @exports video/00_component.js
* @constructor
* @return {jquery Promise}
*/
var Component = function () {
if ($.isFunction(this.initialize)) {
return this.initialize.apply(this, arguments);
}
};
/**
* Returns new constructor that inherits form the current constructor.
* @static
* @param {Object} protoProps The object containing which will be added to
* the prototype.
* @return {Object}
*/
Component.extend = function (protoProps, staticProps) {
var Parent = this,
Child = function () {
if ($.isFunction(this.initialize)) {
return this.initialize.apply(this, arguments);
}
};
// Inherit methods and properties from the Parent prototype.
Child.prototype = inherit(Parent.prototype);
Child.constructor = Parent;
// Provide access to parent's methods and properties
Child.__super__ = Parent.prototype;
// Extends inherited methods and properties by methods/properties
// passed as argument.
if (protoProps) {
$.extend(Child.prototype, protoProps);
}
// Inherit static methods and properties
$.extend(Child, Parent, staticProps);
return Child;
};
return Component;
});
}(RequireJS.define));
......@@ -11,6 +11,13 @@ function() {
*/
return {
'Play': gettext('Play'),
'Pause': gettext('Pause'),
'Mute': gettext('Mute'),
'Unmute': gettext('Unmute'),
'Exit full browser': gettext('Exit full browser'),
'Fill browser': gettext('Fill browser'),
'Speed': gettext('Speed'),
'Volume': gettext('Volume'),
// Translators: Volume level equals 0%.
'Muted': gettext('Muted'),
......
......@@ -30,7 +30,7 @@ function () {
// get the 'state' object as a context.
function _makeFunctionsPublic(state) {
var methodsDict = {
exitFullScreen: exitFullScreen,
exitFullScreenHandler: exitFullScreenHandler,
hideControls: hideControls,
hidePlayPlaceholder: hidePlayPlaceholder,
pause: pause,
......@@ -39,6 +39,7 @@ function () {
showControls: showControls,
showPlayPlaceholder: showPlayPlaceholder,
toggleFullScreen: toggleFullScreen,
toggleFullScreenHandler: toggleFullScreenHandler,
togglePlayback: togglePlayback,
updateControlsHeight: updateControlsHeight,
updateVcrVidTime: updateVcrVidTime
......@@ -93,7 +94,7 @@ function () {
// Bind any necessary function callbacks to DOM events (click, mousemove, etc.).
function _bindHandlers(state) {
state.videoControl.playPauseEl.on('click', state.videoControl.togglePlayback);
state.videoControl.fullScreenEl.on('click', state.videoControl.toggleFullScreen);
state.videoControl.fullScreenEl.on('click', state.videoControl.toggleFullScreenHandler);
state.el.on('fullscreen', function (event, isFullScreen) {
var height = state.videoControl.updateControlsHeight();
......@@ -111,7 +112,7 @@ function () {
}
});
$(document).on('keyup', state.videoControl.exitFullScreen);
$(document).on('keyup', state.videoControl.exitFullScreenHandler);
if ((state.videoType === 'html5') && (state.config.autohideHtml5)) {
state.el.on('mousemove', state.videoControl.showControls);
......@@ -246,19 +247,22 @@ function () {
function togglePlayback(event) {
event.preventDefault();
if (this.videoControl.isPlaying) {
this.trigger('videoPlayer.pause', null);
} else {
this.trigger('videoPlayer.play', null);
}
this.videoCommands.execute('togglePlayback');
}
function toggleFullScreen(event) {
/**
* Event handler to toggle fullscreen mode.
* @param {jquery Event} event
*/
function toggleFullScreenHandler(event) {
event.preventDefault();
this.videoCommands.execute('toggleFullScreen');
}
/** Toggle fullscreen mode. */
function toggleFullScreen() {
var fullScreenClassNameEl = this.el.add(document.documentElement),
win = $(window),
text;
win = $(window), text;
if (this.videoControl.fullScreenState) {
this.videoControl.fullScreenState = this.isFullScreen = false;
......@@ -280,9 +284,14 @@ function () {
this.el.trigger('fullscreen', [this.isFullScreen]);
}
function exitFullScreen(event) {
/**
* Event handler to exit from fullscreen mode.
* @param {jquery Event} event
*/
function exitFullScreenHandler(event) {
if ((this.isFullScreen) && (event.keyCode === 27)) {
this.videoControl.toggleFullScreen(event);
event.preventDefault();
this.videoCommands.execute('toggleFullScreen');
}
}
......
......@@ -198,7 +198,7 @@ function (Iterator) {
var speed = $(event.currentTarget).parent().data('speed');
this.closeMenu();
this.setSpeed(this.state.speedToString(speed));
this.state.videoCommands.execute('speed', speed);
return false;
},
......
(function(define) {
'use strict';
// VideoCommands module.
define('video/10_commands.js', [], function() {
var VideoCommands, Command, playCommand, pauseCommand, togglePlaybackCommand,
muteCommand, unmuteCommand, toggleMuteCommand, toggleFullScreenCommand,
setSpeedCommand;
/**
* Video commands module.
* @exports video/10_commands.js
* @constructor
* @param {Object} state The object containing the state of the video
* @param {Object} i18n The object containing strings with translations.
* @return {jquery Promise}
*/
VideoCommands = function(state, i18n) {
if (!(this instanceof VideoCommands)) {
return new VideoCommands(state, i18n);
}
this.state = state;
this.state.videoCommands = this;
this.i18n = i18n;
this.commands = [];
this.initialize();
return $.Deferred().resolve().promise();
};
VideoCommands.prototype = {
/** Initializes the module. */
initialize: function() {
this.commands = this.getCommands();
},
execute: function (command) {
var args = [].slice.call(arguments, 1) || [];
if (_.has(this.commands, command)) {
this.commands[command].execute.apply(this, [this.state].concat(args));
} else {
console.log('Command "' + command + '" is not available.');
}
},
getCommands: function () {
var commands = {},
commandsList = [
playCommand, pauseCommand, togglePlaybackCommand,
toggleMuteCommand, toggleFullScreenCommand, setSpeedCommand
];
_.each(commandsList, function(command) {
commands[command.name] = command;
}, this);
return commands;
}
};
Command = function (name, execute) {
this.name = name;
this.execute = execute;
};
playCommand = new Command('play', function (state) {
state.videoPlayer.play();
});
pauseCommand = new Command('pause', function (state) {
state.videoPlayer.pause();
});
togglePlaybackCommand = new Command('togglePlayback', function (state) {
if (state.videoControl.isPlaying) {
pauseCommand.execute(state);
} else {
playCommand.execute(state);
}
});
toggleMuteCommand = new Command('toggleMute', function (state) {
state.videoVolumeControl.toggleMute();
});
toggleFullScreenCommand = new Command('toggleFullScreen', function (state) {
state.videoControl.toggleFullScreen();
});
setSpeedCommand = new Command('speed', function (state, speed) {
state.videoSpeedControl.setSpeed(state.speedToString(speed));
});
return VideoCommands;
});
}(RequireJS.define));
......@@ -43,7 +43,9 @@
'video/06_video_progress_slider.js',
'video/07_video_volume_control.js',
'video/08_video_speed_control.js',
'video/09_video_caption.js'
'video/09_video_caption.js',
'video/10_commands.js',
'video/095_video_context_menu.js'
],
function (
initialize,
......@@ -54,7 +56,9 @@
VideoProgressSlider,
VideoVolumeControl,
VideoSpeedControl,
VideoCaption
VideoCaption,
VideoCommands,
VideoContextMenu
) {
var youtubeXhr = null,
oldVideo = window.Video;
......@@ -87,7 +91,9 @@
VideoProgressSlider,
VideoVolumeControl,
VideoSpeedControl,
VideoCaption
VideoCaption,
VideoCommands,
VideoContextMenu
];
state.youtubeXhr = youtubeXhr;
......
......@@ -67,6 +67,7 @@ class VideoModule(VideoFields, VideoStudentViewHandlers, XModule):
module = __name__.replace('.video_module', '', 2)
js = {
'js': [
resource_string(module, 'js/src/video/00_component.js'),
resource_string(module, 'js/src/video/00_video_storage.js'),
resource_string(module, 'js/src/video/00_resizer.js'),
resource_string(module, 'js/src/video/00_async_process.js'),
......@@ -84,6 +85,8 @@ class VideoModule(VideoFields, VideoStudentViewHandlers, XModule):
resource_string(module, 'js/src/video/07_video_volume_control.js'),
resource_string(module, 'js/src/video/08_video_speed_control.js'),
resource_string(module, 'js/src/video/09_video_caption.js'),
resource_string(module, 'js/src/video/095_video_context_menu.js'),
resource_string(module, 'js/src/video/10_commands.js'),
resource_string(module, 'js/src/video/10_main.js')
]
}
......@@ -93,7 +96,6 @@ class VideoModule(VideoFields, VideoStudentViewHandlers, XModule):
]}
js_module_name = "Video"
def get_html(self):
track_url = None
download_video_link = None
......
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