Commit df5520bd by Chris Rodriguez

Video player: adding Dragabilly to closed captions

* tests for dragging
* icon location reference updates
* pattern library usage
parent db9037bc
......@@ -543,6 +543,7 @@ from openedx.core.lib.rooted_paths import rooted_glob
PIPELINE_CSS = {
'style-vendor': {
'source_filenames': [
'js/vendor/afontgarde/afontgarde.css',
'css/vendor/normalize.css',
'css/vendor/font-awesome.css',
'css/vendor/html5-input-polyfills/number-polyfill.css',
......
......@@ -63,10 +63,13 @@
"xblock": "coffee/src/xblock",
"utility": "js/src/utility",
"accessibility": "js/src/accessibility_tools",
"draggabilly": "js/vendor/draggabilly.pkgd",
"URI": "js/vendor/URI.min",
"ieshim": "js/src/ie_shim",
"tooltip_manager": "js/src/tooltip_manager",
"modernizr": "edx-pattern-library/js/modernizr-custom",
"afontgarde": "edx-pattern-library/js/afontgarde",
"edxicons": "edx-pattern-library/js/edx-icons",
"draggabilly": "js/vendor/draggabilly",
// Files needed for Annotations feature
"annotator": "js/vendor/ova/annotator-full",
......@@ -241,7 +244,6 @@
exports: "XBlock",
deps: ["xblock/core"]
},
"coffee/src/main": {
deps: ["coffee/src/ajax_prefix"]
},
......@@ -249,6 +251,12 @@
exports: "Logger",
deps: ["coffee/src/ajax_prefix"]
},
"modernizr": {
exports: "Modernizr"
},
"afontgarde": {
exports: "AFontGarde"
},
// the following are all needed for annotation tools
"video.dev": {
......
......@@ -46,10 +46,13 @@ requirejs.config({
"jasmine-imagediff": "xmodule_js/common_static/js/vendor/jasmine-imagediff",
"jasmine-stealth": "xmodule_js/common_static/js/vendor/jasmine-stealth",
"jasmine.async": "xmodule_js/common_static/js/vendor/jasmine.async",
"draggabilly": "xmodule_js/common_static/js/vendor/draggabilly.pkgd",
"draggabilly": "xmodule_js/common_static/js/vendor/draggabilly",
"domReady": "xmodule_js/common_static/js/vendor/domReady",
"URI": "xmodule_js/common_static/js/vendor/URI.min",
"mock-ajax": "xmodule_js/common_static/js/vendor/mock-ajax",
"modernizr": "xmodule_js/common_static/edx-pattern-library/js/modernizr-custom",
"afontgarde": "xmodule_js/common_static/edx-pattern-library/js/afontgarde",
"edxicons": "xmodule_js/common_static/edx-pattern-library/js/edx-icons",
"mathjax": "//cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured",
"youtube": "//www.youtube.com/player_api?noext",
......@@ -206,6 +209,12 @@ requirejs.config({
},
"coffee/src/ajax_prefix": {
deps: ["jquery"]
},
"modernizr": {
exports: "Modernizr"
},
"afontgarde": {
exports: "AFontGarde"
}
}
});
......
......@@ -38,7 +38,10 @@ requirejs.config({
"squire": "xmodule_js/common_static/js/vendor/Squire",
"jasmine-stealth": "xmodule_js/common_static/js/vendor/jasmine-stealth",
"jasmine.async": "xmodule_js/common_static/js/vendor/jasmine.async",
"draggabilly": "xmodule_js/common_static/js/vendor/draggabilly.pkgd",
"modernizr": "xmodule_js/common_static/edx-pattern-library/js/modernizr-custom",
"afontgarde": "xmodule_js/common_static/edx-pattern-library/js/afontgarde",
"edxicons": "xmodule_js/common_static/edx-pattern-library/js/edx-icons",
"draggabilly": "xmodule_js/common_static/js/vendor/draggabilly",
"domReady": "xmodule_js/common_static/js/vendor/domReady",
"URI": "xmodule_js/common_static/js/vendor/URI.min",
......@@ -176,6 +179,12 @@ requirejs.config({
},
"coffee/src/ajax_prefix": {
deps: ["jquery"]
},
"modernizr": {
exports: "Modernizr"
},
"afontgarde": {
exports: "AFontGarde"
}
}
});
......
......@@ -56,7 +56,7 @@ lib_paths:
- xmodule_js/common_static/js/vendor/jQuery-File-Upload/js
- xmodule_js/src/xmodule.js
- xmodule_js/common_static/js/test/i18n.js
- xmodule_js/common_static/js/vendor/draggabilly.pkgd.js
- xmodule_js/common_static/js/vendor/draggabilly.js
- xmodule_js/common_static/js/vendor/date.js
- xmodule_js/common_static/js/vendor/domReady.js
- xmodule_js/common_static/js/vendor/URI.min.js
......@@ -70,6 +70,9 @@ lib_paths:
- xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-validate.js
- xmodule_js/common_static/js/vendor/mock-ajax.js
- xmodule_js/common_static/js/vendor/requirejs/text.js
- xmodule_js/common_static/edx-pattern-library/js/modernizr-custom.js
- xmodule_js/common_static/edx-pattern-library/js/afontgarde.js
- xmodule_js/common_static/edx-pattern-library/js/edx-icons.js
# Paths to source JavaScript files
src_paths:
......
......@@ -10,54 +10,54 @@
// --------
// the html target is necessary for xblocks and xmodules, but works across the board
html:not('.afontgarde') .icon-fallback-img {
.icon-fallback-img {
.fa-play {
background: url('#{$static-path}/images/fontawesome/play.svg') center center no-repeat;
background: url('#{$static-path}/edx-pattern-library/fonts/edx-icons/fallback-img/play.svg') center center no-repeat;
}
.fa-pause {
background: url('#{$static-path}/images/fontawesome/pause.svg') center center no-repeat;
background: url('#{$static-path}/edx-pattern-library/fonts/edx-icons/fallback-img/pause.svg') center center no-repeat;
}
.fa-step-forward {
background: url('#{$static-path}/images/fontawesome/step-forward.svg') center center no-repeat;
background: url('#{$static-path}/edx-pattern-library/fonts/edx-icons/fallback-img/fast-forward.svg') center center no-repeat;
}
.fa-arrows-alt {
background: url('#{$static-path}/images/fontawesome/arrows-alt.svg') center center no-repeat;
background: url('#{$static-path}/edx-pattern-library/fonts/edx-icons/fallback-img/fullscreen.svg') center center no-repeat;
}
.fa-caret-right {
background: url('#{$static-path}/images/fontawesome/caret-right.svg') center center no-repeat;
background: url('#{$static-path}/edx-pattern-library/fonts/edx-icons/fallback-img/caret-right.svg') center center no-repeat;
}
.fa-caret-left {
background: url('#{$static-path}/images/fontawesome/caret-left.svg') center center no-repeat;
background: url('#{$static-path}/edx-pattern-library/fonts/edx-icons/fallback-img/caret-left.svg') center center no-repeat;
}
.fa-caret-up {
background: url('#{$static-path}/images/fontawesome/caret-up.svg') center center no-repeat;
background: url('#{$static-path}/edx-pattern-library/fonts/edx-icons/fallback-img/caret-up.svg') center center no-repeat;
}
.fa-compress {
background: url('#{$static-path}/images/fontawesome/compress.svg') center center no-repeat;
background: url('#{$static-path}/edx-pattern-library/fonts/edx-icons/fallback-img/exit-fullscreen.svg') center center no-repeat;
}
.fa-quote-left {
background: url('#{$static-path}/images/fontawesome/quote-left.svg') center center no-repeat;
background: url('#{$static-path}/edx-pattern-library/fonts/edx-icons/fallback-img/quote-left.svg') center center no-repeat;
}
.fa-volume-up {
background: url('#{$static-path}/images/fontawesome/volume-up.svg') center center no-repeat;
background: url('#{$static-path}/edx-pattern-library/fonts/edx-icons/fallback-img/volume-up.svg') center center no-repeat;
}
.fa-volume-down {
background: url('#{$static-path}/images/fontawesome/volume-down.svg') center center no-repeat;
background: url('#{$static-path}/edx-pattern-library/fonts/edx-icons/fallback-img/volume-down.svg') center center no-repeat;
}
.fa-volume-off {
background: url('#{$static-path}/images/fontawesome/volume-off.svg') center center no-repeat;
background: url('#{$static-path}/edx-pattern-library/fonts/edx-icons/fallback-img/volume-off.svg') center center no-repeat;
}
}
......@@ -261,6 +261,28 @@ html:not('.afontgarde') .icon-fallback-img {
padding: 8px ($baseline / 2) 8px ($baseline * 1.5);
background: rgba(0, 0, 0, .75);
color: $yellow;
&:before {
position: absolute;
display: inline-block;
top: 50%;
@include left($baseline);
margin-top: -.6em;
font-family: 'FontAwesome';
content: "\f142";
color: $white;
opacity: 0.5;
}
&:hover,
&.is-dragging {
background: rgba(0, 0, 0, 1.0);
cursor: move;
&:before {
opacity: 1.0;
}
}
}
.video-player {
......@@ -289,7 +311,7 @@ html:not('.afontgarde') .icon-fallback-img {
width: 100%;
}
h3 {
h4 {
text-align: center;
color: white;
......
......@@ -98,7 +98,7 @@ class HtmlModuleMixin(HtmlBlock, XModule):
'js': [
resource_string(__name__, 'js/src/collapsible.js'),
resource_string(__name__, 'js/src/html/imageModal.js'),
resource_string(__name__, 'js/common_static/js/vendor/draggabilly.pkgd.js'),
resource_string(__name__, 'js/common_static/js/vendor/draggabilly.js'),
]
}
js_module_name = "HTMLModule"
......
......@@ -59,6 +59,10 @@ lib_paths:
- public/js/split_test_staff.js
- common_static/js/src/accessibility_tools.js
- common_static/js/vendor/moment.min.js
- common_static/js/vendor/draggabilly.js
- common_static/edx-pattern-library/js/modernizr-custom.js
- common_static/edx-pattern-library/js/afontgarde.js
- common_static/edx-pattern-library/js/edx-icons.js
- spec/main_requirejs.js
# Paths to spec (test) JavaScript files
......
(function(requirejs) {
requirejs.config({
paths: {
"moment": "xmodule/include/common_static/js/vendor/moment.min"
"moment": "xmodule/include/common_static/js/vendor/moment.min",
"modernizr": "xmodule/include/common_static/edx-pattern-library/js/modernizr-custom",
"afontgarde": "xmodule/include/common_static/edx-pattern-library/js/afontgarde",
"edxicons": "xmodule/include/common_static/edx-pattern-library/js/edx-icons",
"draggabilly": "xmodule/include/common_static/js/vendor/draggabilly"
},
"moment": {
exports: "moment"
},
"modernizr": {
exports: "Modernizr"
},
"afontgarde": {
exports: "AFontGarde"
}
});
......
......@@ -2,11 +2,14 @@
// VideoCaption module.
'use strict';
define('video/09_video_caption.js', [
define('video/09_video_caption.js',[
'video/00_sjson.js',
'video/00_async_process.js'
],
function (Sjson, AsyncProcess) {
'video/00_async_process.js',
'draggabilly',
'modernizr',
'afontgarde',
'edxicons'
], function (Sjson, AsyncProcess, Draggabilly) {
/**
* @desc VideoCaption module exports a function.
......@@ -33,12 +36,14 @@
'handleKeypress', 'handleKeypressLink', 'openLanguageMenu', 'closeLanguageMenu',
'previousLanguageMenuItem', 'nextLanguageMenuItem', 'handleCaptionToggle',
'showClosedCaptions', 'hideClosedCaptions', 'toggleClosedCaptions',
'updateCaptioningCookie', 'handleCaptioningCookie', 'handleTranscriptToggle'
'updateCaptioningCookie', 'handleCaptioningCookie', 'handleTranscriptToggle',
'listenForDragDrop'
);
this.state = state;
this.state.videoCaption = this;
this.renderElements();
this.handleCaptioningCookie();
this.listenForDragDrop();
return $.Deferred().resolve().promise();
};
......@@ -531,7 +536,7 @@
if (state.isTouch) {
self.subtitlesEl.find('.subtitles-menu')
.text(gettext('Transcript will be displayed when you start playing the video.')) // jshint ignore: line
.wrapInner('<li></li>');
.wrapInner('<li></li>');
} else {
self.renderCaption(start, captions);
}
......@@ -1147,6 +1152,17 @@
}
},
listenForDragDrop: function() {
var captions = document.querySelector('.closed-captions'),
draggable;
if (typeof Draggabilly === "function") {
draggable = new Draggabilly(captions, { containment: true });
} else {
console.log('Closed captioning available but not draggable');
}
},
/**
* @desc Shows/Hides captions and updates the cookie.
*
......
......@@ -32,7 +32,11 @@
'jasmine-imagediff': 'js/vendor/jasmine-imagediff',
'jasmine-stealth': 'js/vendor/jasmine-stealth',
'jasmine.async': 'js/vendor/jasmine.async',
'URI': 'js/vendor/URI.min'
'URI': 'js/vendor/URI.min',
'modernizr': 'edx-pattern-library/js/modernizr-custom',
'afontgarde': 'edx-pattern-library/js/afontgarde',
'edxicons': 'edx-pattern-library/js/edx-icons',
'draggabilly': 'js/vendor/draggabilly',
},
shim: {
'gettext': {
......@@ -149,6 +153,12 @@
},
"sinon": {
exports: "sinon"
},
"modernizr": {
exports: "Modernizr"
},
"afontgarde": {
exports: "AFontGarde"
}
}
});
......
......@@ -57,4 +57,4 @@ html:not('.afontgarde') .icon-fallback-img .icon:before {
/* The img fallback version is not as reliable since it does not check to make sure the fontloaded font has loaded. If we did add the .fontloaded class, it would unnecessarily request the fallback image. */
.fontawesome .icon-fallback-img .icon {
background-image: none;
}
\ No newline at end of file
}
/*! afontgarde - v0.1.6 - 2015-03-13
* https://github.com/filamentgroup/a-font-garde
* Copyright (c) 2015 Filament Group c/o Zach Leatherman
* MIT License */
/*! fontfaceonload - v0.1.6 - 2015-03-13
* https://github.com/zachleat/fontfaceonload
* Copyright (c) 2015 Zach Leatherman (@zachleat)
* MIT License */
;(function( win, doc ) {
"use strict";
var TEST_STRING = 'AxmTYklsjo190QW',
SANS_SERIF_FONTS = 'sans-serif',
SERIF_FONTS = 'serif',
// lighter and bolder not supported
weightLookup = {
normal: '400',
bold: '700'
},
defaultOptions = {
tolerance: 2, // px
delay: 100,
glyphs: '',
success: function() {},
error: function() {},
timeout: 5000,
weight: '400', // normal
style: 'normal'
},
// See https://github.com/typekit/webfontloader/blob/master/src/core/fontruler.js#L41
style = [
'display:block',
'position:absolute',
'top:-999px',
'left:-999px',
'font-size:48px',
'width:auto',
'height:auto',
'line-height:normal',
'margin:0',
'padding:0',
'font-variant:normal',
'white-space:nowrap'
],
html = '<div style="%s">' + TEST_STRING + '</div>';
var FontFaceOnloadInstance = function() {
this.fontFamily = '';
this.appended = false;
this.serif = undefined;
this.sansSerif = undefined;
this.parent = undefined;
this.options = {};
};
FontFaceOnloadInstance.prototype.getMeasurements = function () {
return {
sansSerif: {
width: this.sansSerif.offsetWidth,
height: this.sansSerif.offsetHeight
},
serif: {
width: this.serif.offsetWidth,
height: this.serif.offsetHeight
}
};
};
FontFaceOnloadInstance.prototype.load = function () {
var startTime = new Date(),
that = this,
serif = that.serif,
sansSerif = that.sansSerif,
parent = that.parent,
appended = that.appended,
dimensions,
options = this.options,
ref = options.reference;
function getStyle( family ) {
return style
.concat( [ 'font-weight:' + options.weight, 'font-style:' + options.style ] )
.concat( "font-family:" + family )
.join( ";" );
}
var sansSerifHtml = html.replace( /\%s/, getStyle( SANS_SERIF_FONTS ) ),
serifHtml = html.replace( /\%s/, getStyle( SERIF_FONTS ) );
if( !parent ) {
parent = that.parent = doc.createElement( "div" );
}
parent.innerHTML = sansSerifHtml + serifHtml;
sansSerif = that.sansSerif = parent.firstChild;
serif = that.serif = sansSerif.nextSibling;
if( options.glyphs ) {
sansSerif.innerHTML += options.glyphs;
serif.innerHTML += options.glyphs;
}
function hasNewDimensions( dims, el, tolerance ) {
return Math.abs( dims.width - el.offsetWidth ) > tolerance ||
Math.abs( dims.height - el.offsetHeight ) > tolerance;
}
function isTimeout() {
return ( new Date() ).getTime() - startTime.getTime() > options.timeout;
}
(function checkDimensions() {
if( !ref ) {
ref = doc.body;
}
if( !appended && ref ) {
ref.appendChild( parent );
appended = that.appended = true;
dimensions = that.getMeasurements();
// Make sure we set the new font-family after we take our initial dimensions:
// handles the case where FontFaceOnload is called after the font has already
// loaded.
sansSerif.style.fontFamily = that.fontFamily + ', ' + SANS_SERIF_FONTS;
serif.style.fontFamily = that.fontFamily + ', ' + SERIF_FONTS;
}
if( appended && dimensions &&
( hasNewDimensions( dimensions.sansSerif, sansSerif, options.tolerance ) ||
hasNewDimensions( dimensions.serif, serif, options.tolerance ) ) ) {
options.success();
} else if( isTimeout() ) {
options.error();
} else {
if( !appended && "requestAnimationFrame" in window ) {
win.requestAnimationFrame( checkDimensions );
} else {
win.setTimeout( checkDimensions, options.delay );
}
}
})();
}; // end load()
FontFaceOnloadInstance.prototype.checkFontFaces = function( timeout ) {
var _t = this;
doc.fonts.forEach(function( font ) {
if( font.family.toLowerCase() === _t.fontFamily.toLowerCase() &&
( weightLookup[ font.weight ] || font.weight ) === ''+_t.options.weight &&
font.style === _t.options.style ) {
font.load().then(function() {
_t.options.success();
win.clearTimeout( timeout );
});
}
});
};
FontFaceOnloadInstance.prototype.init = function( fontFamily, options ) {
var timeout;
for( var j in defaultOptions ) {
if( !options.hasOwnProperty( j ) ) {
options[ j ] = defaultOptions[ j ];
}
}
this.options = options;
this.fontFamily = fontFamily;
// For some reason this was failing on afontgarde + icon fonts.
if( !options.glyphs && "fonts" in doc ) {
if( options.timeout ) {
timeout = win.setTimeout(function() {
options.error();
}, options.timeout );
}
this.checkFontFaces( timeout );
} else {
this.load();
}
};
var FontFaceOnload = function( fontFamily, options ) {
var instance = new FontFaceOnloadInstance();
instance.init(fontFamily, options);
return instance;
};
// intentional global
win.FontFaceOnload = FontFaceOnload;
})( this, this.document );
/*
* A Font Garde
*/
;(function( w ) {
var doc = w.document,
ref,
css = ['.FONT_NAME.supports-generatedcontent .icon-fallback-text .icon { display: inline-block; }',
'.FONT_NAME.supports-generatedcontent .icon-fallback-text .text { clip: rect(0 0 0 0); overflow: hidden; position: absolute; height: 1px; width: 1px; }',
'.FONT_NAME .icon-fallback-glyph .icon:before { font-size: 1em; font-size: inherit; line-height: 1; line-height: inherit; }'];
function addEvent( type, callback ) {
if( 'addEventListener' in w ) {
return w.addEventListener( type, callback, false );
} else if( 'attachEvent' in w ) {
return w.attachEvent( 'on' + type, callback );
}
}
// options can be a string of glyphs or an options object to pass into FontFaceOnload
AFontGarde = function( fontFamily, options ) {
var fontFamilyClassName = fontFamily.toLowerCase().replace( /\s/g, '' ),
executed = false;
function init() {
if( executed ) {
return;
}
executed = true;
if( typeof FontFaceOnload === 'undefined' ) {
throw 'FontFaceOnload is a prerequisite.';
}
if( !ref ) {
ref = doc.getElementsByTagName( 'script' )[ 0 ];
}
var style = doc.createElement( 'style' ),
cssContent = css.join( '\n' ).replace( /FONT_NAME/gi, fontFamilyClassName );
style.setAttribute( 'type', 'text/css' );
if( style.styleSheet ) {
style.styleSheet.cssText = cssContent;
} else {
style.appendChild( doc.createTextNode( cssContent ) );
}
ref.parentNode.insertBefore( style, ref );
var opts = {
timeout: 5000,
success: function() {
// If you’re using more than one icon font, change this classname (and in a-font-garde.css)
doc.documentElement.className += ' ' + fontFamilyClassName;
if( options && options.success ) {
options.success();
}
}
};
// These characters are a few of the glyphs from the font above */
if( typeof options === "string" ) {
opts.glyphs = options;
} else {
for( var j in options ) {
if( options.hasOwnProperty( j ) && j !== "success" ) {
opts[ j ] = options[ j ];
}
}
}
FontFaceOnload( fontFamily, opts );
}
// MIT credit: filamentgroup/shoestring
addEvent( "DOMContentLoaded", init );
addEvent( "readystatechange", init );
addEvent( "load", init );
if( doc.readyState === "complete" ){
init();
}
};
})( this );
\ No newline at end of file
(function() {
'use strict';
window.AFontGarde('FontAwesome', {
glyphs: '&#61515;'
});
});
/* Modernizr 2.7.1 (Custom Build) | MIT & BSD
* Build: http://modernizr.com/download/#-fontface-generatedcontent-cssclasses-teststyles-cssclassprefix:supports!
*/
;window.Modernizr=function(a,b,c){function w(a){j.cssText=a}function x(a,b){return w(prefixes.join(a+";")+(b||""))}function y(a,b){return typeof a===b}function z(a,b){return!!~(""+a).indexOf(b)}function A(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:y(f,"function")?f.bind(d||b):f}return!1}var d="2.7.1",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l=":)",m={}.toString,n={},o={},p={},q=[],r=q.slice,s,t=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["&#173;",'<style id="s',h,'">',a,"</style>"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},u={}.hasOwnProperty,v;!y(u,"undefined")&&!y(u.call,"undefined")?v=function(a,b){return u.call(a,b)}:v=function(a,b){return b in a&&y(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=r.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(r.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(r.call(arguments)))};return e}),n.fontface=function(){var a;return t('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},n.generatedcontent=function(){var a;return t(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a};for(var B in n)v(n,B)&&(s=B.toLowerCase(),e[s]=n[B](),q.push((e[s]?"":"no-")+s));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)v(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" supports-"+(b?"":"no-")+a),e[a]=b}return e},w(""),i=k=null,e._version=d,e.testStyles=t,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" supports-js supports-"+q.join(" supports-"):""),e}(this,this.document);
\ No newline at end of file
......@@ -38,10 +38,14 @@ lib_paths:
- js/vendor/backbone-min.js
- js/vendor/jquery.timeago.js
- js/vendor/URI.min.js
- js/vendor/draggabilly.js
- coffee/src/ajax_prefix.js
- js/test/add_ajax_prefix.js
- js/test/i18n.js
- coffee/src/jquery.immediateDescendents.js
- edx-pattern-library/js/modernizr-custom.js
- edx-pattern-library/js/afontgarde.js
- edx-pattern-library/js/edx-icons.js
# Paths to source JavaScript files
src_paths:
......
......@@ -8,6 +8,8 @@ import os
from mock import patch
from nose.plugins.attrib import attr
from unittest import skipIf, skip
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from ..helpers import UniqueCourseTest, is_youtube_available, YouTubeStubConfig
from ...pages.lms.video.video import VideoPage
from ...pages.lms.tab_nav import TabNavPage
......@@ -1189,6 +1191,42 @@ class YouTubeQualityTest(VideoBaseTest):
self.video.wait_for(lambda: self.video.is_quality_button_active, 'waiting for quality button activation')
@attr('shard_4')
class DragAndDropTest(VideoBaseTest):
"""
Tests draggability of closed captions within videos.
"""
def setUp(self):
super(DragAndDropTest, self).setUp()
def test_if_captions_are_draggable(self):
"""
Loads transcripts so that closed-captioning is available.
Ensures they are draggable by checking start and dropped location.
"""
self.assets.append('subs_3_yD_cEKoCk.srt.sjson')
data = {'sub': '3_yD_cEKoCk'}
self.metadata = self.metadata_for_mode('html5', additional_data=data)
self.navigate_to_video()
self.assertTrue(self.video.is_video_rendered('html5'))
self.video.show_closed_captions()
self.video.wait_for_closed_captions()
self.assertTrue(self.video.is_closed_captions_visible)
action = ActionChains(self.browser)
captions = self.browser.find_element(By.CLASS_NAME, 'closed-captions')
captions_start = captions.location
action.drag_and_drop_by_offset(captions, 0, -15).perform()
captions_end = captions.location
self.assertEqual(
captions_end.get('y') + 15,
captions_start.get('y'),
'Closed captions did not get dragged.'
)
@attr('a11y')
class LMSVideoModuleA11yTest(VideoBaseTest):
"""
......
......@@ -1261,7 +1261,8 @@ base_vendor_js = [
'js/vendor/requirejs/require.js',
'js/RequireJS-namespace-undefine.js',
'js/vendor/URI.min.js',
'js/vendor/backbone-min.js'
'js/vendor/backbone-min.js',
'edx-pattern-library/js/modernizr-custom.js',
]
main_vendor_js = base_vendor_js + [
......@@ -1269,9 +1270,6 @@ main_vendor_js = base_vendor_js + [
'js/vendor/jquery-ui.min.js',
'js/vendor/jquery.qtip.min.js',
'js/vendor/jquery.ba-bbq.min.js',
'js/vendor/afontgarde/modernizr.fontface-generatedcontent.js',
'js/vendor/afontgarde/afontgarde.js',
'js/vendor/afontgarde/edx-icons.js'
]
# Common files used by both RequireJS code and non-RequireJS code
......@@ -1670,7 +1668,10 @@ REQUIRE_JS_PATH_OVERRIDES = {
'js/student_account/logistration_factory': 'js/student_account/logistration_factory.js',
'js/student_profile/views/learner_profile_factory': 'js/student_profile/views/learner_profile_factory.js',
'js/bookmarks/bookmarks_factory': 'js/bookmarks/bookmarks_factory.js',
'js/groups/views/cohorts_dashboard_factory': 'js/groups/views/cohorts_dashboard_factory.js'
'js/groups/views/cohorts_dashboard_factory': 'js/groups/views/cohorts_dashboard_factory.js',
'afontgarde': 'edx-pattern-library/js/afontgarde.js',
'edxicons': 'edx-pattern-library/js/edx-icons.js',
'draggabilly': 'js/vendor/draggabilly.js'
}
################################# CELERY ######################################
......
......@@ -47,7 +47,6 @@
'jasmine-imagediff': 'xmodule_js/common_static/js/vendor/jasmine-imagediff',
'jasmine-stealth': 'xmodule_js/common_static/js/vendor/jasmine-stealth',
'jasmine.async': 'xmodule_js/common_static/js/vendor/jasmine.async',
'draggabilly': 'xmodule_js/common_static/js/vendor/draggabilly.pkgd',
'domReady': 'xmodule_js/common_static/js/vendor/domReady',
'mathjax': '//cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // jshint ignore:line
'youtube': '//www.youtube.com/player_api?noext',
......@@ -67,6 +66,10 @@
'mathjax_delay_renderer': 'coffee/src/mathjax_delay_renderer',
'MathJaxProcessor': 'coffee/src/customwmd',
'picturefill': 'common/js/vendor/picturefill.min',
'draggabilly': 'xmodule_js/common_static/js/vendor/draggabilly',
'modernizr': 'xmodule_js/common_static/edx-pattern-library/js/modernizr-custom',
'afontgarde': 'xmodule_js/common_static/edx-pattern-library/js/afontgarde',
'edxicons': 'xmodule_js/common_static/edx-pattern-library/js/edx-icons',
// Manually specify LMS files that are not converted to RequireJS
'history': 'js/vendor/history',
......@@ -625,8 +628,13 @@
'xmodule_js/common_static/coffee/src/discussion/utils'
],
exports: 'DiscussionSpecHelper'
},
'modernizr': {
exports: 'Modernizr'
},
'afontgarde': {
exports: 'AFontGarde'
}
}
});
......
......@@ -72,6 +72,7 @@
'utility': 'empty:',
'URI': 'empty:',
'DiscussionModuleView': 'empty:',
'modernizr': 'empty',
// Don't bundle UI Toolkit helpers as they are loaded into the "edx" namespace
'edx-ui-toolkit/js/utils/html-utils': 'empty:',
......
......@@ -39,6 +39,7 @@
defineDependency("Logger", "logger");
defineDependency("URI", "URI");
defineDependency("Backbone", "backbone");
defineDependency("Modernizr", "modernizr");
// Add the UI Toolkit helper classes that have been installed in the "edx" namespace
defineDependency("edx.HtmlUtils", "edx-ui-toolkit/js/utils/html-utils");
......@@ -73,6 +74,10 @@
"URI": "js/vendor/URI.min",
"string_utils": "js/src/string_utils",
"utility": "js/src/utility",
"modernizr": "edx-pattern-library/js/modernizr-custom",
"afontgarde": "edx-pattern-library/js/afontgarde",
"edxicons": "edx-pattern-library/js/edx-icons",
"draggabilly": "js/vendor/draggabilly",
// Files needed by OVA
"annotator": "js/vendor/ova/annotator-full",
......@@ -200,6 +205,15 @@
},
"moment-with-locales": {
exports: "moment"
},
"afontgarde": {
exports: "AFontGarde"
},
// Because Draggabilly is being used by video code, the namespaced version of
// require is not being recognized. Therefore the library is being added to the
// global namespace instead of being registered in require.
"draggabilly": {
exports: "Draggabilly"
}
}
});
......
......@@ -3,7 +3,7 @@
"version": "0.1.0",
"dependencies": {
"coffee-script": "1.6.1",
"edx-pattern-library": "~0.12.1",
"edx-pattern-library": "~0.12.4",
"edx-ui-toolkit": "~0.9.1",
"requirejs": "~2.1.22",
"uglify-js": "2.4.24",
......
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