Video player: adding Dragabilly to closed captions
* tests for dragging * icon location reference updates * pattern library usage
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
(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;
|
||||
}
|
||||
}
|
||||
|
||||
287
common/static/js/vendor/afontgarde/afontgarde.js
vendored
287
common/static/js/vendor/afontgarde/afontgarde.js
vendored
@@ -1,287 +0,0 @@
|
||||
/*! 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 );
|
||||
@@ -1,7 +0,0 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
window.AFontGarde('FontAwesome', {
|
||||
glyphs: ''
|
||||
});
|
||||
});
|
||||
@@ -1,4 +0,0 @@
|
||||
/* 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=["­",'<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);
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user