Run eslint autofixer on /common
This commit is contained in:
@@ -55,3 +55,6 @@ common/lib/xmodule/xmodule/js/src/sequence/display.js
|
||||
common/lib/xmodule/xmodule/js/src/sequence/edit.js
|
||||
common/lib/xmodule/xmodule/js/src/tabs/tabs-aggregator.js
|
||||
common/lib/xmodule/xmodule/js/src/vertical/edit.js
|
||||
|
||||
# This file is responsible for almost half of the repo's total issues.
|
||||
common/lib/xmodule/xmodule/js/src/capa/schematic.js
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
require('coffee-script');
|
||||
var importAll = function (modulePath) {
|
||||
module = require(modulePath);
|
||||
for(key in module){
|
||||
global[key] = module[key];
|
||||
}
|
||||
}
|
||||
var importAll = function(modulePath) {
|
||||
module = require(modulePath);
|
||||
for (key in module) {
|
||||
global[key] = module[key];
|
||||
}
|
||||
};
|
||||
|
||||
importAll("mersenne-twister-min");
|
||||
importAll("xproblem");
|
||||
importAll('mersenne-twister-min');
|
||||
importAll('xproblem');
|
||||
|
||||
generatorModulePath = process.argv[2];
|
||||
dependencies = JSON.parse(process.argv[3]);
|
||||
seed = JSON.parse(process.argv[4]);
|
||||
params = JSON.parse(process.argv[5]);
|
||||
dependencies = JSON.parse(process.argv[3]);
|
||||
seed = JSON.parse(process.argv[4]);
|
||||
params = JSON.parse(process.argv[5]);
|
||||
|
||||
if(seed==null){
|
||||
if (seed == null) {
|
||||
seed = 4;
|
||||
}
|
||||
|
||||
for(var i = 0; i < dependencies.length; i++){
|
||||
for (var i = 0; i < dependencies.length; i++) {
|
||||
importAll(dependencies[i]);
|
||||
}
|
||||
|
||||
generatorModule = require(generatorModulePath);
|
||||
generatorClass = generatorModule.generatorClass;
|
||||
generatorClass = generatorModule.generatorClass;
|
||||
generator = new generatorClass(seed, params);
|
||||
console.log(JSON.stringify(generator.generate()));
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
require('coffee-script');
|
||||
var importAll = function (modulePath) {
|
||||
module = require(modulePath);
|
||||
for(key in module){
|
||||
global[key] = module[key];
|
||||
}
|
||||
}
|
||||
var importAll = function(modulePath) {
|
||||
module = require(modulePath);
|
||||
for (key in module) {
|
||||
global[key] = module[key];
|
||||
}
|
||||
};
|
||||
|
||||
importAll("xproblem");
|
||||
importAll('xproblem');
|
||||
|
||||
graderModulePath = process.argv[2];
|
||||
dependencies = JSON.parse(process.argv[3]);
|
||||
submission = JSON.parse(process.argv[4]);
|
||||
problemState = JSON.parse(process.argv[5]);
|
||||
params = JSON.parse(process.argv[6]);
|
||||
graderModulePath = process.argv[2];
|
||||
dependencies = JSON.parse(process.argv[3]);
|
||||
submission = JSON.parse(process.argv[4]);
|
||||
problemState = JSON.parse(process.argv[5]);
|
||||
params = JSON.parse(process.argv[6]);
|
||||
|
||||
for(var i = 0; i < dependencies.length; i++){
|
||||
for (var i = 0; i < dependencies.length; i++) {
|
||||
importAll(dependencies[i]);
|
||||
}
|
||||
|
||||
graderModule = require(graderModulePath);
|
||||
graderClass = graderModule.graderClass;
|
||||
graderClass = graderModule.graderClass;
|
||||
grader = new graderClass(submission, problemState, params);
|
||||
console.log(JSON.stringify(grader.grade()));
|
||||
console.log(JSON.stringify(grader.evaluation));
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/* JavaScript for special editing operations that can be done on LibraryContentXBlock */
|
||||
window.LibraryContentAuthorView = function (runtime, element) {
|
||||
"use strict";
|
||||
window.LibraryContentAuthorView = function(runtime, element) {
|
||||
'use strict';
|
||||
var $element = $(element);
|
||||
var usage_id = $element.data('usage-id');
|
||||
// The "Update Now" button is not a child of 'element', as it is in the validation message area
|
||||
// But it is still inside this xblock's wrapper element, which we can easily find:
|
||||
var $wrapper = $element.parents('*[data-locator="'+usage_id+'"]');
|
||||
var $wrapper = $element.parents('*[data-locator="' + usage_id + '"]');
|
||||
|
||||
// We can't bind to the button itself because in the bok choy test environment,
|
||||
// it may not yet exist at this point in time... not sure why.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* JavaScript for editing operations that can be done on the split test author view. */
|
||||
window.SplitTestAuthorView = function (runtime, element) {
|
||||
"use strict";
|
||||
window.SplitTestAuthorView = function(runtime, element) {
|
||||
'use strict';
|
||||
var $element = $(element);
|
||||
var splitTestLocator = $element.closest('.studio-xblock-wrapper').data('locator');
|
||||
|
||||
runtime.listenTo("add-missing-groups", function (parentLocator) {
|
||||
runtime.listenTo('add-missing-groups', function(parentLocator) {
|
||||
if (splitTestLocator === parentLocator) {
|
||||
runtime.notify('save', {
|
||||
state: 'start',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Creates a new selector for managing toggling which child to show. */
|
||||
window.ABTestSelector = function (runtime, elem) {
|
||||
"use strict";
|
||||
window.ABTestSelector = function(runtime, elem) {
|
||||
'use strict';
|
||||
var _this = {};
|
||||
_this.elem = $(elem);
|
||||
_this.children = _this.elem.find('.split-test-child');
|
||||
@@ -12,7 +12,7 @@ window.ABTestSelector = function (runtime, elem) {
|
||||
_this.children.each(function() {
|
||||
// force this id to remain a string, even if it looks like something else
|
||||
var child_group_id = $(this).data('group-id').toString();
|
||||
if(child_group_id === group_id) {
|
||||
if (child_group_id === group_id) {
|
||||
_this.content_container.html($(this).text());
|
||||
XBlock.initializeBlocks(_this.content_container, $(elem).data('request-token'));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Javascript for the Split Test XBlock. */
|
||||
window.SplitTestStudentView = function (runtime, element) {
|
||||
"use strict";
|
||||
window.SplitTestStudentView = function(runtime, element) {
|
||||
'use strict';
|
||||
$.post(runtime.handlerUrl(element, 'log_child_render'));
|
||||
return {};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* JavaScript for Vertical Student View. */
|
||||
window.VerticalStudentView = function (runtime, element) {
|
||||
"use strict";
|
||||
RequireJS.require(['js/bookmarks/views/bookmark_button'], function (BookmarkButton) {
|
||||
window.VerticalStudentView = function(runtime, element) {
|
||||
'use strict';
|
||||
RequireJS.require(['js/bookmarks/views/bookmark_button'], function(BookmarkButton) {
|
||||
var $element = $(element);
|
||||
var $bookmarkButtonElement = $element.find('.bookmark-button');
|
||||
|
||||
@@ -10,7 +10,7 @@ window.VerticalStudentView = function (runtime, element) {
|
||||
bookmarkId: $bookmarkButtonElement.data('bookmarkId'),
|
||||
usageId: $element.data('usageId'),
|
||||
bookmarked: $element.parent('#seq_content').data('bookmarked'),
|
||||
apiUrl: $(".courseware-bookmarks-button").data('bookmarksApiUrl')
|
||||
apiUrl: $('.courseware-bookmarks-button').data('bookmarksApiUrl')
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
// Somehow the code initialized in jQuery's onready doesn't get called before karma auto starts
|
||||
|
||||
'use strict';
|
||||
window.__karma__.loaded = function () {
|
||||
setTimeout(function () {
|
||||
window.__karma__.loaded = function() {
|
||||
setTimeout(function() {
|
||||
window.__karma__.start();
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
@@ -49,7 +49,7 @@ var options = {
|
||||
{pattern: 'common_static/common/js/spec_helpers/jasmine-extensions.js', included: true},
|
||||
{pattern: 'common_static/js/vendor/sinon-1.17.0.js', included: true},
|
||||
|
||||
{pattern: 'spec/main_requirejs.js', included: true},
|
||||
{pattern: 'spec/main_requirejs.js', included: true}
|
||||
],
|
||||
|
||||
libraryFiles: [
|
||||
@@ -78,6 +78,6 @@ var options = {
|
||||
]
|
||||
};
|
||||
|
||||
module.exports = function (config) {
|
||||
module.exports = function(config) {
|
||||
configModule.configure(config, options);
|
||||
};
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
* ~ Donald Knuth
|
||||
*/
|
||||
|
||||
(function ($, ImageInput, undefined) {
|
||||
describe('ImageInput', function () {
|
||||
(function($, ImageInput, undefined) {
|
||||
describe('ImageInput', function() {
|
||||
var state;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
var el;
|
||||
|
||||
loadFixtures('imageinput.html');
|
||||
@@ -20,7 +20,7 @@
|
||||
state = new ImageInput('12345');
|
||||
});
|
||||
|
||||
it('initialization', function () {
|
||||
it('initialization', function() {
|
||||
// Check that object's properties are present, and that the DOM
|
||||
// elements they reference exist.
|
||||
expect(state.el).toBeDefined();
|
||||
@@ -35,7 +35,7 @@
|
||||
expect(state.el).toHandle('click');
|
||||
});
|
||||
|
||||
it('cross becomes visible after first click', function () {
|
||||
it('cross becomes visible after first click', function() {
|
||||
expect(state.crossEl.css('visibility')).toBe('hidden');
|
||||
|
||||
state.el.click();
|
||||
@@ -43,7 +43,7 @@
|
||||
expect(state.crossEl.css('visibility')).toBe('visible');
|
||||
});
|
||||
|
||||
it('coordinates are updated [offsetX is set]', function () {
|
||||
it('coordinates are updated [offsetX is set]', function() {
|
||||
var event, posX, posY, cssLeft, cssTop;
|
||||
|
||||
// Set up of 'click' event.
|
||||
@@ -71,7 +71,7 @@
|
||||
);
|
||||
});
|
||||
|
||||
it('coordinates are updated [offsetX is NOT set]', function () {
|
||||
it('coordinates are updated [offsetX is NOT set]', function() {
|
||||
var offset = state.el.offset(),
|
||||
event, posX, posY, cssLeft, cssTop;
|
||||
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
(function (undefined) {
|
||||
(function(undefined) {
|
||||
'use strict';
|
||||
|
||||
describe('Collapsible', function () {
|
||||
describe('Collapsible', function() {
|
||||
var el, html, html_custom,
|
||||
initialize = function (template) {
|
||||
initialize = function(template) {
|
||||
setFixtures(template);
|
||||
el = $('.collapsible');
|
||||
Collapsible.setCollapsibles(el);
|
||||
},
|
||||
disableFx = function () {
|
||||
disableFx = function() {
|
||||
$.fx.off = true;
|
||||
},
|
||||
enableFx = function () {
|
||||
enableFx = function() {
|
||||
$.fx.off = false;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
html = '' +
|
||||
'<section class="collapsible">' +
|
||||
'<div class="shortform">shortform message</div>' +
|
||||
@@ -36,8 +36,8 @@
|
||||
'</section>';
|
||||
});
|
||||
|
||||
describe('setCollapsibles', function () {
|
||||
it('Default container initialized correctly', function () {
|
||||
describe('setCollapsibles', function() {
|
||||
it('Default container initialized correctly', function() {
|
||||
initialize(html);
|
||||
|
||||
expect(el.find('.shortform')).toContainElement('.full-top');
|
||||
@@ -46,7 +46,7 @@
|
||||
expect(el.find('.full')).toHandle('click');
|
||||
});
|
||||
|
||||
it('Custom container initialized correctly', function () {
|
||||
it('Custom container initialized correctly', function() {
|
||||
initialize(html_custom);
|
||||
|
||||
expect(el.find('.shortform-custom')).toContainElement('.full-custom');
|
||||
@@ -56,8 +56,8 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('toggleFull', function () {
|
||||
var assertChanges = function (state, anchorsElClass, showText, hideText) {
|
||||
describe('toggleFull', function() {
|
||||
var assertChanges = function(state, anchorsElClass, showText, hideText) {
|
||||
var anchors, text;
|
||||
|
||||
if (state == null) {
|
||||
@@ -76,20 +76,20 @@
|
||||
text = hideText;
|
||||
}
|
||||
|
||||
$.each(anchors, function (index, el) {
|
||||
$.each(anchors, function(index, el) {
|
||||
expect(el).toHaveText(text);
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
disableFx();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
enableFx();
|
||||
});
|
||||
|
||||
it('Default container', function () {
|
||||
it('Default container', function() {
|
||||
var event;
|
||||
|
||||
initialize(html);
|
||||
@@ -105,7 +105,7 @@
|
||||
assertChanges('closed', 'full', 'See full output', 'Hide output');
|
||||
});
|
||||
|
||||
it('Custom container', function () {
|
||||
it('Custom container', function() {
|
||||
var event;
|
||||
|
||||
initialize(html_custom);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(function () {
|
||||
(function() {
|
||||
'use strict';
|
||||
var origAjax = $.ajax;
|
||||
|
||||
var stubbedYT = {
|
||||
Player: function () {
|
||||
Player: function() {
|
||||
var Player = jasmine.createSpyObj(
|
||||
'YT.Player',
|
||||
[
|
||||
@@ -33,7 +33,7 @@
|
||||
BUFFERING: 3,
|
||||
CUED: 5
|
||||
},
|
||||
ready: function (f) {
|
||||
ready: function(f) {
|
||||
return f();
|
||||
}
|
||||
};
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
window.STATUS = window.YT.PlayerState;
|
||||
|
||||
window.onTouchBasedDevice = function () {
|
||||
window.onTouchBasedDevice = function() {
|
||||
return navigator.userAgent.match(/iPhone|iPod|iPad/i);
|
||||
};
|
||||
|
||||
@@ -77,31 +77,31 @@
|
||||
|
||||
jasmine.stubbedMetadata = {
|
||||
'7tqY6eQzVhE': {
|
||||
contentDetails : {
|
||||
contentDetails: {
|
||||
id: '7tqY6eQzVhE',
|
||||
duration: 'PT5M0S'
|
||||
}
|
||||
},
|
||||
'cogebirgzzM': {
|
||||
contentDetails : {
|
||||
contentDetails: {
|
||||
id: 'cogebirgzzM',
|
||||
duration: 'PT3M20S'
|
||||
}
|
||||
},
|
||||
'abcdefghijkl': {
|
||||
contentDetails : {
|
||||
contentDetails: {
|
||||
id: 'abcdefghijkl',
|
||||
duration: 'PT6M40S'
|
||||
}
|
||||
},
|
||||
bogus: {
|
||||
contentDetails : {
|
||||
contentDetails: {
|
||||
duration: 'PT1M40S'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.fireEvent = function (el, eventName) {
|
||||
jasmine.fireEvent = function(el, eventName) {
|
||||
var event;
|
||||
|
||||
if (document.createEvent) {
|
||||
@@ -123,20 +123,20 @@
|
||||
|
||||
jasmine.stubbedHtml5Speeds = ['0.75', '1.0', '1.25', '1.50'];
|
||||
|
||||
jasmine.stubRequests = function () {
|
||||
jasmine.stubRequests = function() {
|
||||
var spy = $.ajax;
|
||||
if (!jasmine.isSpy($.ajax)) {
|
||||
spy = spyOn($, 'ajax');
|
||||
}
|
||||
|
||||
return spy.and.callFake(function (settings) {
|
||||
return spy.and.callFake(function(settings) {
|
||||
var match = settings.url
|
||||
.match(/googleapis\.com\/.+\/videos\/\?id=(.+)&part=contentDetails/),
|
||||
status, callCallback;
|
||||
if (match) {
|
||||
status = match[1].split('_');
|
||||
if (status && status[0] === 'status') {
|
||||
callCallback = function (callback) {
|
||||
callCallback = function(callback) {
|
||||
callback.call(window, {}, status[1]);
|
||||
};
|
||||
|
||||
@@ -151,10 +151,10 @@
|
||||
});
|
||||
} else {
|
||||
return {
|
||||
always: function (callback) {
|
||||
always: function(callback) {
|
||||
return callback.call(window, {}, 'success');
|
||||
},
|
||||
done: function (callback) {
|
||||
done: function(callback) {
|
||||
return callback.call(window, {}, 'success');
|
||||
}
|
||||
};
|
||||
@@ -177,7 +177,7 @@
|
||||
return;
|
||||
} else if (settings.url === '/save_user_state') {
|
||||
return {success: true};
|
||||
} else if(settings.url.match(new RegExp(jasmine.getFixtures().fixturesPath + ".+", 'g'))) {
|
||||
} else if (settings.url.match(new RegExp(jasmine.getFixtures().fixturesPath + '.+', 'g'))) {
|
||||
return origAjax(settings);
|
||||
} else {
|
||||
$.ajax.and.callThrough();
|
||||
@@ -196,9 +196,9 @@
|
||||
|
||||
// Stub window.Video.loadYouTubeIFrameAPI()
|
||||
window.Video.loadYouTubeIFrameAPI = jasmine.createSpy('window.Video.loadYouTubeIFrameAPI').and.returnValue(
|
||||
function (scriptTag) {
|
||||
function(scriptTag) {
|
||||
var event = document.createEvent('Event');
|
||||
if (fixture === "video.html") {
|
||||
if (fixture === 'video.html') {
|
||||
event.initEvent('load', false, false);
|
||||
} else {
|
||||
event.initEvent('error', false, false);
|
||||
@@ -207,7 +207,7 @@
|
||||
}
|
||||
);
|
||||
|
||||
jasmine.initializePlayer = function (fixture, params) {
|
||||
jasmine.initializePlayer = function(fixture, params) {
|
||||
var state;
|
||||
|
||||
if (_.isString(fixture)) {
|
||||
@@ -235,7 +235,7 @@
|
||||
jasmine.stubRequests();
|
||||
state = new window.Video('#example');
|
||||
|
||||
state.resizer = (function () {
|
||||
state.resizer = (function() {
|
||||
var methods = [
|
||||
'align',
|
||||
'alignByWidthOnly',
|
||||
@@ -251,7 +251,7 @@
|
||||
reset: jasmine.createSpy().and.returnValue(obj)
|
||||
};
|
||||
|
||||
$.each(methods, function (index, method) {
|
||||
$.each(methods, function(index, method) {
|
||||
obj[method] = jasmine.createSpy(method).and.returnValue(obj);
|
||||
});
|
||||
|
||||
@@ -264,7 +264,7 @@
|
||||
return state;
|
||||
};
|
||||
|
||||
jasmine.initializePlayerYouTube = function (params) {
|
||||
jasmine.initializePlayerYouTube = function(params) {
|
||||
// "video.html" contains HTML template for a YouTube video.
|
||||
return jasmine.initializePlayer('video.html', params);
|
||||
};
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
// into the optimized files. Therefore load these libraries through script tags and explicitly define them.
|
||||
// Note that when the optimizer executes this code, window will not be defined.
|
||||
if (window) {
|
||||
var defineDependency = function (globalName, name, noShim) {
|
||||
var defineDependency = function(globalName, name, noShim) {
|
||||
var getGlobalValue = function(name) {
|
||||
var globalNamePath = name.split('.'),
|
||||
result = window,
|
||||
i;
|
||||
for (i = 0; i < globalNamePath.length; i++) {
|
||||
result = result[globalNamePath[i]];
|
||||
}
|
||||
return result;
|
||||
},
|
||||
var globalNamePath = name.split('.'),
|
||||
result = window,
|
||||
i;
|
||||
for (i = 0; i < globalNamePath.length; i++) {
|
||||
result = result[globalNamePath[i]];
|
||||
}
|
||||
return result;
|
||||
},
|
||||
globalValue = getGlobalValue(globalName);
|
||||
if (globalValue) {
|
||||
if (noShim) {
|
||||
@@ -24,22 +24,22 @@
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.error("Expected library to be included on page, but not found on window object: " + name);
|
||||
console.error('Expected library to be included on page, but not found on window object: ' + name);
|
||||
}
|
||||
};
|
||||
defineDependency("jQuery", "jquery");
|
||||
defineDependency("jQuery", "jquery-migrate");
|
||||
defineDependency("_", "underscore");
|
||||
defineDependency('jQuery', 'jquery');
|
||||
defineDependency('jQuery', 'jquery-migrate');
|
||||
defineDependency('_', 'underscore');
|
||||
}
|
||||
requirejs.config({
|
||||
baseUrl: '/base/',
|
||||
paths: {
|
||||
"moment": "common_static/js/vendor/moment.min",
|
||||
"draggabilly": "common_static/js/vendor/draggabilly",
|
||||
'moment': 'common_static/js/vendor/moment.min',
|
||||
'draggabilly': 'common_static/js/vendor/draggabilly',
|
||||
'edx-ui-toolkit': 'common_static/edx-ui-toolkit'
|
||||
},
|
||||
"moment": {
|
||||
exports: "moment"
|
||||
'moment': {
|
||||
exports: 'moment'
|
||||
}
|
||||
});
|
||||
}).call(this, RequireJS.requirejs, RequireJS.define);
|
||||
|
||||
@@ -13,7 +13,7 @@ describe('Tests for split_test staff view switching', function() {
|
||||
delete window.XBlock;
|
||||
});
|
||||
|
||||
it("test that we have only one visible condition", function() {
|
||||
it('test that we have only one visible condition', function() {
|
||||
var containers = elem.find('.split-test-child-container').length;
|
||||
var conditions_shown = elem.find('.split-test-child-container .condition-text').length;
|
||||
expect(containers).toEqual(1);
|
||||
@@ -21,17 +21,15 @@ describe('Tests for split_test staff view switching', function() {
|
||||
expect(XBlock.initializeBlocks).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("test that the right child is visible when selected", function() {
|
||||
it('test that the right child is visible when selected', function() {
|
||||
var groups = ['0', '1', '2'];
|
||||
|
||||
for(var i = 0; i < groups.length; i++) {
|
||||
for (var i = 0; i < groups.length; i++) {
|
||||
var to_select = groups[i];
|
||||
elem.find('.split-test-select').val(to_select).change();
|
||||
var child_text = elem.find('.split-test-child-container .condition-text').text();
|
||||
expect(child_text).toContain(to_select);
|
||||
expect(XBlock.initializeBlocks).toHaveBeenCalled();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
(function (undefined) {
|
||||
(function(undefined) {
|
||||
'use strict';
|
||||
|
||||
describe('Time', function () {
|
||||
describe('format', function () {
|
||||
describe('with NAN', function () {
|
||||
it('return a correct time format', function () {
|
||||
describe('Time', function() {
|
||||
describe('format', function() {
|
||||
describe('with NAN', function() {
|
||||
it('return a correct time format', function() {
|
||||
expect(Time.format('string')).toEqual('0:00');
|
||||
expect(Time.format(void(0))).toEqual('0:00');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with duration more than or equal to 1 hour', function () {
|
||||
it('return a correct time format', function () {
|
||||
describe('with duration more than or equal to 1 hour', function() {
|
||||
it('return a correct time format', function() {
|
||||
expect(Time.format(3600)).toEqual('1:00:00');
|
||||
expect(Time.format(7272)).toEqual('2:01:12');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with duration less than 1 hour', function () {
|
||||
it('return a correct time format', function () {
|
||||
describe('with duration less than 1 hour', function() {
|
||||
it('return a correct time format', function() {
|
||||
expect(Time.format(1)).toEqual('0:01');
|
||||
expect(Time.format(61)).toEqual('1:01');
|
||||
expect(Time.format(3599)).toEqual('59:59');
|
||||
@@ -26,17 +26,17 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatFull', function () {
|
||||
it('gives correct string for times', function () {
|
||||
describe('formatFull', function() {
|
||||
it('gives correct string for times', function() {
|
||||
var testTimes = [
|
||||
[0, '00:00:00'], [60, '00:01:00'],
|
||||
[488, '00:08:08'], [2452, '00:40:52'],
|
||||
[3600, '01:00:00'], [28800, '08:00:00'],
|
||||
[0, '00:00:00'], [60, '00:01:00'],
|
||||
[488, '00:08:08'], [2452, '00:40:52'],
|
||||
[3600, '01:00:00'], [28800, '08:00:00'],
|
||||
[144532, '40:08:52'], [190360, '52:52:40'],
|
||||
[294008, '81:40:08'], [-5, '00:00:00']
|
||||
[294008, '81:40:08'], [-5, '00:00:00']
|
||||
];
|
||||
|
||||
$.each(testTimes, function (index, times) {
|
||||
$.each(testTimes, function(index, times) {
|
||||
var timeInt = times[0],
|
||||
timeStr = times[1];
|
||||
|
||||
@@ -45,13 +45,12 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('convert', function () {
|
||||
it('return a correct time based on speed modifier', function () {
|
||||
describe('convert', function() {
|
||||
it('return a correct time based on speed modifier', function() {
|
||||
expect(Time.convert(0, 1, 1.5)).toEqual('0.000');
|
||||
expect(Time.convert(100, 1, 1.5)).toEqual('66.667');
|
||||
expect(Time.convert(100, 1.5, 1)).toEqual('150.000');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}).call(this);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(function (require) {
|
||||
require(
|
||||
(function(require) {
|
||||
require(
|
||||
['video/00_async_process.js'],
|
||||
function (AsyncProcess) {
|
||||
var getArrayNthLength = function (n, multiplier) {
|
||||
function(AsyncProcess) {
|
||||
var getArrayNthLength = function(n, multiplier) {
|
||||
var result = [],
|
||||
mul = multiplier || 1;
|
||||
|
||||
@@ -14,65 +14,65 @@ function (AsyncProcess) {
|
||||
},
|
||||
items = getArrayNthLength(1000);
|
||||
|
||||
describe('AsyncProcess', function () {
|
||||
it ('Array is processed successfully', function (done) {
|
||||
describe('AsyncProcess', function() {
|
||||
it('Array is processed successfully', function(done) {
|
||||
var processedArray,
|
||||
expectedArray = getArrayNthLength(1000, 2),
|
||||
process = function (item) {
|
||||
process = function(item) {
|
||||
return 2 * item;
|
||||
};
|
||||
|
||||
AsyncProcess.array(items, process).done(function (result) {
|
||||
AsyncProcess.array(items, process).done(function(result) {
|
||||
processedArray = result;
|
||||
});
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return processedArray;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(processedArray).toEqual(expectedArray);
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it ('If non-array is passed, error callback is called', function (done) {
|
||||
it('If non-array is passed, error callback is called', function(done) {
|
||||
var isError,
|
||||
process = function () {};
|
||||
process = function() {};
|
||||
|
||||
AsyncProcess.array('string', process).fail(function () {
|
||||
AsyncProcess.array('string', process).fail(function() {
|
||||
isError = true;
|
||||
});
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return isError;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(isError).toBeTruthy();
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it ('If an empty array is passed, returns initial array', function (done) {
|
||||
it('If an empty array is passed, returns initial array', function(done) {
|
||||
var processedArray,
|
||||
process = function () {};
|
||||
process = function() {};
|
||||
|
||||
AsyncProcess.array([], process).done(function (result) {
|
||||
AsyncProcess.array([], process).done(function(result) {
|
||||
processedArray = result;
|
||||
});
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return processedArray;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(processedArray).toEqual([]);
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it ('If no process function passed, returns initial array', function (done) {
|
||||
it('If no process function passed, returns initial array', function(done) {
|
||||
var processedArray;
|
||||
|
||||
AsyncProcess.array(items).done(function (result) {
|
||||
AsyncProcess.array(items).done(function(result) {
|
||||
processedArray = result;
|
||||
});
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return processedArray;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(processedArray).toEqual(items);
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(function (undefined) {
|
||||
describe('VideoPlayer Events', function () {
|
||||
(function(undefined) {
|
||||
describe('VideoPlayer Events', function() {
|
||||
var state, oldOTBD;
|
||||
|
||||
describe('HTML5', function () {
|
||||
beforeEach(function () {
|
||||
describe('HTML5', function() {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine
|
||||
.createSpy('onTouchBasedDevice')
|
||||
@@ -14,53 +14,53 @@
|
||||
state.videoEl = $('video, iframe');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
});
|
||||
|
||||
it('initialize', function (done) {
|
||||
jasmine.waitUntil(function () {
|
||||
it('initialize', function(done) {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.el.hasClass('is-initialized');
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect('initialize').not.toHaveBeenTriggeredOn('.video');
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it('ready', function (done) {
|
||||
jasmine.waitUntil(function () {
|
||||
it('ready', function(done) {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.el.hasClass('is-initialized');
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect('ready').not.toHaveBeenTriggeredOn('.video');
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it('play', function () {
|
||||
it('play', function() {
|
||||
state.videoPlayer.play();
|
||||
expect('play').not.toHaveBeenTriggeredOn('.video');
|
||||
});
|
||||
|
||||
it('pause', function () {
|
||||
it('pause', function() {
|
||||
state.videoPlayer.play();
|
||||
state.videoPlayer.pause();
|
||||
expect('pause').not.toHaveBeenTriggeredOn('.video');
|
||||
});
|
||||
|
||||
it('volumechange', function () {
|
||||
it('volumechange', function() {
|
||||
state.videoPlayer.onVolumeChange(60);
|
||||
|
||||
expect('volumechange').not.toHaveBeenTriggeredOn('.video');
|
||||
});
|
||||
|
||||
it('speedchange', function () {
|
||||
it('speedchange', function() {
|
||||
state.videoPlayer.onSpeedChange('2.0');
|
||||
|
||||
expect('speedchange').not.toHaveBeenTriggeredOn('.video');
|
||||
});
|
||||
|
||||
it('seek', function () {
|
||||
it('seek', function() {
|
||||
state.videoPlayer.onCaptionSeek({
|
||||
time: 1,
|
||||
type: 'any'
|
||||
@@ -69,15 +69,15 @@
|
||||
expect('seek').not.toHaveBeenTriggeredOn('.video');
|
||||
});
|
||||
|
||||
it('ended', function () {
|
||||
it('ended', function() {
|
||||
state.videoPlayer.onEnded();
|
||||
|
||||
expect('ended').not.toHaveBeenTriggeredOn('.video');
|
||||
});
|
||||
});
|
||||
|
||||
describe('YouTube', function () {
|
||||
beforeEach(function () {
|
||||
describe('YouTube', function() {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine
|
||||
.createSpy('onTouchBasedDevice')
|
||||
@@ -86,19 +86,18 @@
|
||||
state = jasmine.initializePlayerYouTube();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
});
|
||||
|
||||
it('qualitychange', function () {
|
||||
it('qualitychange', function() {
|
||||
state.videoPlayer.onPlaybackQualityChange();
|
||||
|
||||
expect('qualitychange').not.toHaveBeenTriggeredOn('.video');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}).call(this);
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
(function (undefined) {
|
||||
describe('Video', function () {
|
||||
(function(undefined) {
|
||||
describe('Video', function() {
|
||||
var oldOTBD, state;
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
window.VideoState = {};
|
||||
window.VideoState.id = {};
|
||||
window.YT = jasmine.YT;
|
||||
});
|
||||
|
||||
describe('constructor', function () {
|
||||
describe('YT', function () {
|
||||
beforeEach(function () {
|
||||
describe('constructor', function() {
|
||||
describe('YT', function() {
|
||||
beforeEach(function() {
|
||||
loadFixtures('video.html');
|
||||
$.cookie.and.returnValue('0.50');
|
||||
});
|
||||
|
||||
describe('by default', function () {
|
||||
beforeEach(function () {
|
||||
describe('by default', function() {
|
||||
beforeEach(function() {
|
||||
this.state = jasmine.initializePlayerYouTube('video_html5.html');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
this.state.storage.clear();
|
||||
this.state.videoPlayer.destroy();
|
||||
});
|
||||
|
||||
it('check videoType', function () {
|
||||
it('check videoType', function() {
|
||||
expect(this.state.videoType).toEqual('youtube');
|
||||
});
|
||||
|
||||
it('set the elements', function () {
|
||||
it('set the elements', function() {
|
||||
expect(this.state.el).toEqual($('#video_id'));
|
||||
});
|
||||
|
||||
it('parse the videos', function () {
|
||||
it('parse the videos', function() {
|
||||
expect(this.state.videos).toEqual({
|
||||
'0.50': '7tqY6eQzVhE',
|
||||
'1.0': 'cogebirgzzM',
|
||||
@@ -42,49 +42,49 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('parse available video speeds', function () {
|
||||
it('parse available video speeds', function() {
|
||||
expect(this.state.speeds).toEqual(['0.50', '1.0', '1.50']);
|
||||
});
|
||||
|
||||
it('set current video speed via cookie', function () {
|
||||
it('set current video speed via cookie', function() {
|
||||
expect(this.state.speed).toEqual('1.50');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('HTML5', function () {
|
||||
describe('HTML5', function() {
|
||||
var state;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
$.cookie.and.returnValue('0.75');
|
||||
state = jasmine.initializePlayer('video_html5.html');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
});
|
||||
|
||||
describe('by default', function () {
|
||||
it('check videoType', function () {
|
||||
describe('by default', function() {
|
||||
it('check videoType', function() {
|
||||
expect(state.videoType).toEqual('html5');
|
||||
});
|
||||
|
||||
it('set the elements', function () {
|
||||
it('set the elements', function() {
|
||||
expect(state.el).toEqual($('#video_id'));
|
||||
});
|
||||
|
||||
it('doesn\'t have `videos` dictionary', function () {
|
||||
it('doesn\'t have `videos` dictionary', function() {
|
||||
expect(state.videos).toBeUndefined();
|
||||
});
|
||||
|
||||
it('parse available video speeds', function () {
|
||||
it('parse available video speeds', function() {
|
||||
var speeds = jasmine.stubbedHtml5Speeds;
|
||||
|
||||
expect(state.speeds).toEqual(speeds);
|
||||
});
|
||||
|
||||
it('set current video speed via cookie', function () {
|
||||
it('set current video speed via cookie', function() {
|
||||
expect(state.speed).toEqual('1.50');
|
||||
});
|
||||
});
|
||||
@@ -93,34 +93,34 @@
|
||||
// handled by Require JS. When state.videoPlayer is created,
|
||||
// the stand alone HTML5 player object is already loaded, so no
|
||||
// further testing in that case is required.
|
||||
describe('HTML5 API is available', function () {
|
||||
it('create the Video Player', function () {
|
||||
describe('HTML5 API is available', function() {
|
||||
it('create the Video Player', function() {
|
||||
expect(state.videoPlayer.player).not.toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('YouTube API is not loaded', function () {
|
||||
describe('YouTube API is not loaded', function() {
|
||||
var state;
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
window.YT = undefined;
|
||||
state = jasmine.initializePlayerYouTube();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
});
|
||||
|
||||
it('callback, to be called after YouTube API loads, exists and is called', function (done) {
|
||||
it('callback, to be called after YouTube API loads, exists and is called', function(done) {
|
||||
window.YT = jasmine.YT;
|
||||
// Call the callback that must be called when YouTube API is
|
||||
// loaded. By specification.
|
||||
window.onYouTubeIframeAPIReady();
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.youtubeApiAvailable === true;
|
||||
}).done(function(){
|
||||
}).done(function() {
|
||||
// If YouTube API is not loaded, then the code will should create
|
||||
// a global callback that will be called by API once it is loaded.
|
||||
expect(window.onYouTubeIframeAPIReady).not.toBeUndefined();
|
||||
@@ -128,7 +128,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('checking start and end times', function () {
|
||||
describe('checking start and end times', function() {
|
||||
var state;
|
||||
var miniTestSuite = [
|
||||
{
|
||||
@@ -158,19 +158,19 @@
|
||||
}
|
||||
];
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
});
|
||||
|
||||
$.each(miniTestSuite, function (index, test) {
|
||||
$.each(miniTestSuite, function(index, test) {
|
||||
itFabrique(test.itDescription, test.data, test.expectData);
|
||||
});
|
||||
|
||||
return;
|
||||
|
||||
function itFabrique(itDescription, data, expectData) {
|
||||
it(itDescription, function () {
|
||||
it(itDescription, function() {
|
||||
state = jasmine.initializePlayer('video.html', {
|
||||
'start': data.start,
|
||||
'end': data.end
|
||||
@@ -183,10 +183,10 @@
|
||||
});
|
||||
|
||||
// Disabled 11/25/13 due to flakiness in master
|
||||
xdescribe('multiple YT on page', function () {
|
||||
xdescribe('multiple YT on page', function() {
|
||||
var state1, state2, state3;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
loadFixtures('video_yt_multiple.html');
|
||||
|
||||
spyOn($, 'ajaxWithPrefix');
|
||||
@@ -207,32 +207,32 @@
|
||||
|
||||
it(
|
||||
'check for YT availability is performed only once',
|
||||
function ()
|
||||
function()
|
||||
{
|
||||
var numAjaxCalls = 0;
|
||||
var numAjaxCalls = 0;
|
||||
|
||||
// Total ajax calls made.
|
||||
numAjaxCalls = $.ajax.calls.length;
|
||||
numAjaxCalls = $.ajax.calls.length;
|
||||
|
||||
// Subtract ajax calls to get captions via
|
||||
// state.videoCaption.fetchCaption() function.
|
||||
numAjaxCalls -= $.ajaxWithPrefix.calls.length;
|
||||
numAjaxCalls -= $.ajaxWithPrefix.calls.length;
|
||||
|
||||
// Subtract ajax calls to get metadata for each video via
|
||||
// state.getVideoMetadata() function.
|
||||
numAjaxCalls -= 3;
|
||||
numAjaxCalls -= 3;
|
||||
|
||||
// Subtract ajax calls to log event 'pause_video' via
|
||||
// state.videoPlayer.log() function.
|
||||
numAjaxCalls -= 3;
|
||||
numAjaxCalls -= 3;
|
||||
|
||||
// This should leave just one call. It was made to check
|
||||
// for YT availability. This is done in state.initialize()
|
||||
// function. SPecifically, with the statement
|
||||
//
|
||||
// this.youtubeXhr = this.getVideoMetadata();
|
||||
expect(numAjaxCalls).toBe(1);
|
||||
});
|
||||
expect(numAjaxCalls).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
}).call(this);
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
(function (undefined) {
|
||||
describe('Video HTML5Video', function () {
|
||||
(function(undefined) {
|
||||
describe('Video HTML5Video', function() {
|
||||
var STATUS = window.STATUS;
|
||||
var state, oldOTBD, playbackRates = [0.75, 1.0, 1.25, 1.5];
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine
|
||||
.createSpy('onTouchBasedDevice').and.returnValue(null);
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
$.fn.scrollTo.calls.reset();
|
||||
@@ -18,70 +17,70 @@
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
});
|
||||
|
||||
describe('on non-Touch devices', function () {
|
||||
beforeEach(function () {
|
||||
describe('on non-Touch devices', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer('video_html5.html');
|
||||
|
||||
state.videoPlayer.player.config.events.onReady = jasmine.createSpy('onReady');
|
||||
});
|
||||
|
||||
describe('events:', function () {
|
||||
beforeEach(function () {
|
||||
describe('events:', function() {
|
||||
beforeEach(function() {
|
||||
spyOn(state.videoPlayer.player, 'callStateChangeCallback').and.callThrough();
|
||||
});
|
||||
|
||||
describe('[click]', function () {
|
||||
describe('when player is paused', function () {
|
||||
beforeEach(function () {
|
||||
describe('[click]', function() {
|
||||
describe('when player is paused', function() {
|
||||
beforeEach(function() {
|
||||
spyOn(state.videoPlayer.player.video, 'play').and.callThrough();
|
||||
state.videoPlayer.player.playerState = STATUS.PAUSED;
|
||||
$(state.videoPlayer.player.videoEl).trigger('click');
|
||||
});
|
||||
|
||||
it('native play event was called', function () {
|
||||
it('native play event was called', function() {
|
||||
expect(state.videoPlayer.player.video.play).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('player state was changed', function (done) {
|
||||
jasmine.waitUntil(function () {
|
||||
it('player state was changed', function(done) {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() === STATUS.PLAYING;
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
// Flaky. Checking the parameters of calls to onStateChange() will likely be more reliable.
|
||||
xit('callback was not called', function (done) {
|
||||
jasmine.waitUntil(function () {
|
||||
xit('callback was not called', function(done) {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() !== STATUS.PAUSED;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(state.videoPlayer.player.callStateChangeCallback).not.toHaveBeenCalled();
|
||||
}).always(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('[player is playing]', function () {
|
||||
beforeEach(function () {
|
||||
describe('[player is playing]', function() {
|
||||
beforeEach(function() {
|
||||
spyOn(state.videoPlayer.player.video, 'pause').and.callThrough();
|
||||
state.videoPlayer.player.playerState = STATUS.PLAYING;
|
||||
state.videoPlayer.player.playerState = STATUS.PLAYING;
|
||||
$(state.videoPlayer.player.videoEl).trigger('click');
|
||||
});
|
||||
|
||||
it('native event was called', function () {
|
||||
it('native event was called', function() {
|
||||
expect(state.videoPlayer.player.video.pause).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('player state was changed', function (done) {
|
||||
jasmine.waitUntil(function () {
|
||||
it('player state was changed', function(done) {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() !== STATUS.PLAYING;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(state.videoPlayer.player.getPlayerState())
|
||||
.toBe(STATUS.PAUSED);
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it('callback was not called', function (done) {
|
||||
jasmine.waitUntil(function () {
|
||||
it('callback was not called', function(done) {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() !== STATUS.PLAYING;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(state.videoPlayer.player.callStateChangeCallback)
|
||||
.not.toHaveBeenCalled();
|
||||
}).always(done);
|
||||
@@ -89,82 +88,82 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('[play]', function () {
|
||||
beforeEach(function () {
|
||||
describe('[play]', function() {
|
||||
beforeEach(function() {
|
||||
spyOn(state.videoPlayer.player.video, 'play').and.callThrough();
|
||||
state.videoPlayer.player.playerState = STATUS.PAUSED;
|
||||
state.videoPlayer.player.playVideo();
|
||||
});
|
||||
|
||||
it('native event was called', function () {
|
||||
it('native event was called', function() {
|
||||
expect(state.videoPlayer.player.video.play).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
||||
it('player state was changed', function (done) {
|
||||
jasmine.waitUntil(function () {
|
||||
it('player state was changed', function(done) {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() !== STATUS.PAUSED;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(state.videoPlayer.player.getPlayerState())
|
||||
.toBe(STATUS.BUFFERING);
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it('callback was called', function (done) {
|
||||
jasmine.waitUntil(function () {
|
||||
it('callback was called', function(done) {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() !== STATUS.PAUSED;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(state.videoPlayer.player.callStateChangeCallback)
|
||||
.toHaveBeenCalled();
|
||||
}).always(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('[pause]', function () {
|
||||
beforeEach(function (done) {
|
||||
describe('[pause]', function() {
|
||||
beforeEach(function(done) {
|
||||
spyOn(state.videoPlayer.player.video, 'pause').and.callThrough();
|
||||
state.videoPlayer.player.playerState = STATUS.UNSTARTED;
|
||||
state.videoPlayer.player.playVideo();
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() !== STATUS.UNSTARTED;
|
||||
}).done(done);
|
||||
|
||||
state.videoPlayer.player.pauseVideo();
|
||||
});
|
||||
|
||||
it('native event was called', function () {
|
||||
it('native event was called', function() {
|
||||
expect(state.videoPlayer.player.video.pause).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('player state was changed', function (done) {
|
||||
jasmine.waitUntil(function () {
|
||||
it('player state was changed', function(done) {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() !== STATUS.PLAYING;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(state.videoPlayer.player.getPlayerState())
|
||||
.toBe(STATUS.PAUSED);
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it('callback was called', function (done) {
|
||||
jasmine.waitUntil(function () {
|
||||
it('callback was called', function(done) {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() !== STATUS.PLAYING;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(state.videoPlayer.player.callStateChangeCallback)
|
||||
.toHaveBeenCalled();
|
||||
}).always(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('[loadedmetadata]', function () {
|
||||
describe('[loadedmetadata]', function() {
|
||||
it(
|
||||
'player state was changed, start/end was defined, ' +
|
||||
'onReady called', function (done)
|
||||
'onReady called', function(done)
|
||||
{
|
||||
jasmine.fireEvent(state.videoPlayer.player.video, 'loadedmetadata');
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() !== STATUS.UNSTARTED;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(state.videoPlayer.player.getPlayerState())
|
||||
.toBe(STATUS.PAUSED);
|
||||
expect(state.videoPlayer.player.video.currentTime).toBe(0);
|
||||
@@ -174,20 +173,20 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('[ended]', function () {
|
||||
beforeEach(function (done) {
|
||||
describe('[ended]', function() {
|
||||
beforeEach(function(done) {
|
||||
state.videoPlayer.player.playVideo();
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() !== STATUS.UNSTARTED;
|
||||
}).done(done);
|
||||
});
|
||||
|
||||
it('player state was changed', function () {
|
||||
it('player state was changed', function() {
|
||||
jasmine.fireEvent(state.videoPlayer.player.video, 'ended');
|
||||
expect(state.videoPlayer.player.getPlayerState()).toBe(STATUS.ENDED);
|
||||
});
|
||||
|
||||
it('callback was called', function () {
|
||||
it('callback was called', function() {
|
||||
jasmine.fireEvent(state.videoPlayer.player.video, 'ended');
|
||||
expect(state.videoPlayer.player.callStateChangeCallback)
|
||||
.toHaveBeenCalled();
|
||||
@@ -195,23 +194,23 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('methods', function () {
|
||||
describe('methods', function() {
|
||||
var volume, seek, duration, playbackRate;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
volume = state.videoPlayer.player.video.volume;
|
||||
});
|
||||
|
||||
it('pauseVideo', function () {
|
||||
it('pauseVideo', function() {
|
||||
spyOn(state.videoPlayer.player.video, 'pause').and.callThrough();
|
||||
state.videoPlayer.player.pauseVideo();
|
||||
expect(state.videoPlayer.player.video.pause).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('seekTo', function () {
|
||||
it('set new correct value', function (done) {
|
||||
describe('seekTo', function() {
|
||||
it('set new correct value', function(done) {
|
||||
state.videoPlayer.player.playVideo();
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() === STATUS.PLAYING;
|
||||
}).then(function() {
|
||||
state.videoPlayer.player.seekTo(2);
|
||||
@@ -219,7 +218,7 @@
|
||||
}).done(done);
|
||||
});
|
||||
|
||||
it('set new inccorrect values', function () {
|
||||
it('set new inccorrect values', function() {
|
||||
var seek = state.videoPlayer.player.video.currentTime;
|
||||
state.videoPlayer.player.seekTo(-50);
|
||||
expect(state.videoPlayer.player.getCurrentTime()).toBe(seek);
|
||||
@@ -230,13 +229,13 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('setVolume', function () {
|
||||
it('set new correct value', function () {
|
||||
describe('setVolume', function() {
|
||||
it('set new correct value', function() {
|
||||
state.videoPlayer.player.setVolume(50);
|
||||
expect(state.videoPlayer.player.getVolume()).toBe(50 * 0.01);
|
||||
});
|
||||
|
||||
it('set new incorrect values', function () {
|
||||
it('set new incorrect values', function() {
|
||||
state.videoPlayer.player.setVolume(-50);
|
||||
expect(state.videoPlayer.player.getVolume()).toBe(volume);
|
||||
state.videoPlayer.player.setVolume('5');
|
||||
@@ -246,9 +245,9 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('getCurrentTime', function (done) {
|
||||
it('getCurrentTime', function(done) {
|
||||
state.videoPlayer.player.playVideo();
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() === STATUS.PLAYING;
|
||||
}).then(function() {
|
||||
state.videoPlayer.player.video.currentTime = 3;
|
||||
@@ -257,42 +256,42 @@
|
||||
}).done(done);
|
||||
});
|
||||
|
||||
it('playVideo', function () {
|
||||
it('playVideo', function() {
|
||||
spyOn(state.videoPlayer.player.video, 'play').and.callThrough();
|
||||
state.videoPlayer.player.playVideo();
|
||||
expect(state.videoPlayer.player.video.play).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('getPlayerState', function () {
|
||||
it('getPlayerState', function() {
|
||||
state.videoPlayer.player.playerState = STATUS.PLAYING;
|
||||
expect(state.videoPlayer.player.getPlayerState()).toBe(STATUS.PLAYING);
|
||||
state.videoPlayer.player.playerState = STATUS.ENDED;
|
||||
expect(state.videoPlayer.player.getPlayerState()).toBe(STATUS.ENDED);
|
||||
});
|
||||
|
||||
it('getVolume', function () {
|
||||
it('getVolume', function() {
|
||||
volume = state.videoPlayer.player.video.volume = 0.5;
|
||||
expect(state.videoPlayer.player.getVolume()).toBe(volume);
|
||||
});
|
||||
|
||||
it('getDuration', function (done) {
|
||||
it('getDuration', function(done) {
|
||||
state.videoPlayer.player.playVideo();
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() === STATUS.PLAYING;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
duration = state.videoPlayer.player.video.duration;
|
||||
expect(state.videoPlayer.player.getDuration()).toBe(duration);
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
describe('setPlaybackRate', function () {
|
||||
it('set a correct value', function () {
|
||||
describe('setPlaybackRate', function() {
|
||||
it('set a correct value', function() {
|
||||
playbackRate = 1.5;
|
||||
state.videoPlayer.player.setPlaybackRate(playbackRate);
|
||||
expect(state.videoPlayer.player.video.playbackRate).toBe(playbackRate);
|
||||
});
|
||||
|
||||
it('set NaN value', function () {
|
||||
it('set NaN value', function() {
|
||||
var oldPlaybackRate = state.videoPlayer.player.video.playbackRate;
|
||||
|
||||
// When we try setting the playback rate to some
|
||||
@@ -304,14 +303,14 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('getAvailablePlaybackRates', function () {
|
||||
it('getAvailablePlaybackRates', function() {
|
||||
expect(state.videoPlayer.player.getAvailablePlaybackRates())
|
||||
.toEqual(playbackRates);
|
||||
});
|
||||
|
||||
it('_getLogs', function (done) {
|
||||
it('_getLogs', function(done) {
|
||||
state.videoPlayer.player.playVideo();
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.player.getPlayerState() === STATUS.PLAYING;
|
||||
}).then(function() {
|
||||
var logs = state.videoPlayer.player._getLogs();
|
||||
@@ -322,7 +321,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('native controls are used on iPhone', function () {
|
||||
it('native controls are used on iPhone', function() {
|
||||
window.onTouchBasedDevice.and.returnValue(['iPhone']);
|
||||
|
||||
state = jasmine.initializePlayer('video_html5.html');
|
||||
|
||||
@@ -1,30 +1,29 @@
|
||||
(function (requirejs, require, define, undefined) {
|
||||
(function(requirejs, require, define, undefined) {
|
||||
'use strict';
|
||||
|
||||
'use strict';
|
||||
|
||||
require(
|
||||
require(
|
||||
['video/01_initialize.js'],
|
||||
function (Initialize) {
|
||||
describe('Initialize', function () {
|
||||
function(Initialize) {
|
||||
describe('Initialize', function() {
|
||||
var state = {};
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
state = {};
|
||||
});
|
||||
|
||||
describe('getCurrentLanguage', function () {
|
||||
describe('getCurrentLanguage', function() {
|
||||
var msg;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
state.config = {};
|
||||
state.config.transcriptLanguages = {
|
||||
'de': 'German',
|
||||
'en': 'English',
|
||||
'uk': 'Ukrainian',
|
||||
'uk': 'Ukrainian'
|
||||
};
|
||||
});
|
||||
|
||||
it ('returns current language', function () {
|
||||
it('returns current language', function() {
|
||||
var expected;
|
||||
|
||||
state.lang = 'de';
|
||||
@@ -33,7 +32,7 @@ function (Initialize) {
|
||||
});
|
||||
|
||||
msg = 'returns `en`, if language isn\'t available for the video';
|
||||
it (msg, function () {
|
||||
it(msg, function() {
|
||||
var expected;
|
||||
|
||||
state.lang = 'zh';
|
||||
@@ -43,19 +42,19 @@ function (Initialize) {
|
||||
|
||||
msg = 'returns any available language, if current and `en` ' +
|
||||
'languages aren\'t available for the video';
|
||||
it (msg, function () {
|
||||
it(msg, function() {
|
||||
var expected;
|
||||
|
||||
state.lang = 'zh';
|
||||
state.config.transcriptLanguages = {
|
||||
'de': 'German',
|
||||
'uk': 'Ukrainian',
|
||||
'uk': 'Ukrainian'
|
||||
};
|
||||
expected = Initialize.prototype.getCurrentLanguage.call(state);
|
||||
expect(expected).toBe('uk');
|
||||
});
|
||||
|
||||
it ('returns `null`, if transcript unavailable', function () {
|
||||
it('returns `null`, if transcript unavailable', function() {
|
||||
var expected;
|
||||
|
||||
state.lang = 'zh';
|
||||
@@ -65,8 +64,8 @@ function (Initialize) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getDuration', function () {
|
||||
beforeEach(function () {
|
||||
describe('getDuration', function() {
|
||||
beforeEach(function() {
|
||||
state = {
|
||||
speed: '1.50',
|
||||
metadata: {
|
||||
@@ -87,7 +86,7 @@ function (Initialize) {
|
||||
});
|
||||
|
||||
var msg = 'returns duration for the 1.0 speed if speed is not 1.0';
|
||||
it(msg, function () {
|
||||
it(msg, function() {
|
||||
var expected;
|
||||
|
||||
state.speed = '1.50';
|
||||
@@ -96,8 +95,8 @@ function (Initialize) {
|
||||
expect(expected).toEqual(400);
|
||||
});
|
||||
|
||||
describe('Flash mode', function () {
|
||||
it('returns duration for current video', function () {
|
||||
describe('Flash mode', function() {
|
||||
it('returns duration for current video', function() {
|
||||
var expected;
|
||||
|
||||
state.isFlashMode.and.returnValue(true);
|
||||
@@ -107,7 +106,7 @@ function (Initialize) {
|
||||
});
|
||||
|
||||
var msg = 'returns duration for the 1.0 speed as a fall-back';
|
||||
it(msg, function () {
|
||||
it(msg, function() {
|
||||
var expected;
|
||||
|
||||
state.isFlashMode.and.returnValue(true);
|
||||
@@ -119,8 +118,8 @@ function (Initialize) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('youtubeId', function () {
|
||||
beforeEach(function () {
|
||||
describe('youtubeId', function() {
|
||||
beforeEach(function() {
|
||||
state = {
|
||||
speed: '1.50',
|
||||
videos: {
|
||||
@@ -132,8 +131,8 @@ function (Initialize) {
|
||||
};
|
||||
});
|
||||
|
||||
describe('with speed', function () {
|
||||
it('return the video id for given speed', function () {
|
||||
describe('with speed', function() {
|
||||
it('return the video id for given speed', function() {
|
||||
$.each(state.videos, function(speed, videoId) {
|
||||
var expected = Initialize.prototype.youtubeId.call(
|
||||
state, speed
|
||||
@@ -144,8 +143,8 @@ function (Initialize) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('without speed for flash mode', function () {
|
||||
it('return the video id for current speed', function () {
|
||||
describe('without speed for flash mode', function() {
|
||||
it('return the video id for current speed', function() {
|
||||
var expected;
|
||||
|
||||
state.isFlashMode.and.returnValue(true);
|
||||
@@ -155,16 +154,16 @@ function (Initialize) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('without speed for youtube html5 mode', function () {
|
||||
it('return the video id for 1.0x speed', function () {
|
||||
describe('without speed for youtube html5 mode', function() {
|
||||
it('return the video id for 1.0x speed', function() {
|
||||
var expected = Initialize.prototype.youtubeId.call(state);
|
||||
|
||||
expect(expected).toEqual('cogebirgzzM');
|
||||
});
|
||||
});
|
||||
|
||||
describe('speed is absent in the list of video speeds', function () {
|
||||
it('return the video id for 1.0x speed', function () {
|
||||
describe('speed is absent in the list of video speeds', function() {
|
||||
it('return the video id for 1.0x speed', function() {
|
||||
var expected = Initialize.prototype.youtubeId.call(state, '0.0');
|
||||
|
||||
expect(expected).toEqual('cogebirgzzM');
|
||||
@@ -172,16 +171,16 @@ function (Initialize) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('setSpeed', function () {
|
||||
describe('YT', function () {
|
||||
beforeEach(function () {
|
||||
describe('setSpeed', function() {
|
||||
describe('YT', function() {
|
||||
beforeEach(function() {
|
||||
state = {
|
||||
speeds: ['0.25', '0.50', '1.0', '1.50', '2.0'],
|
||||
storage: jasmine.createSpyObj('storage', ['setItem'])
|
||||
};
|
||||
});
|
||||
|
||||
it('check mapping', function () {
|
||||
it('check mapping', function() {
|
||||
var map = {
|
||||
'0.75': '0.50',
|
||||
'1.25': '1.50'
|
||||
@@ -194,35 +193,35 @@ function (Initialize) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('HTML5', function () {
|
||||
beforeEach(function () {
|
||||
describe('HTML5', function() {
|
||||
beforeEach(function() {
|
||||
state = {
|
||||
speeds: ['0.75', '1.0', '1.25', '1.50'],
|
||||
storage: jasmine.createSpyObj('storage', ['setItem'])
|
||||
};
|
||||
});
|
||||
|
||||
describe('when new speed is available', function () {
|
||||
beforeEach(function () {
|
||||
describe('when new speed is available', function() {
|
||||
beforeEach(function() {
|
||||
Initialize.prototype.setSpeed.call(state, '0.75');
|
||||
});
|
||||
|
||||
it('set new speed', function () {
|
||||
it('set new speed', function() {
|
||||
expect(state.speed).toEqual('0.75');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when new speed is not available', function () {
|
||||
beforeEach(function () {
|
||||
describe('when new speed is not available', function() {
|
||||
beforeEach(function() {
|
||||
Initialize.prototype.setSpeed.call(state, '1.75');
|
||||
});
|
||||
|
||||
it('set speed to 1.0x', function () {
|
||||
it('set speed to 1.0x', function() {
|
||||
expect(state.speed).toEqual('1.0');
|
||||
});
|
||||
});
|
||||
|
||||
it('check mapping', function () {
|
||||
it('check mapping', function() {
|
||||
var map = {
|
||||
'0.25': '0.75',
|
||||
'0.50': '0.75',
|
||||
@@ -237,14 +236,14 @@ function (Initialize) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('setPlayerMode', function () {
|
||||
beforeEach(function () {
|
||||
describe('setPlayerMode', function() {
|
||||
beforeEach(function() {
|
||||
state = {
|
||||
currentPlayerMode: 'flash',
|
||||
currentPlayerMode: 'flash'
|
||||
};
|
||||
});
|
||||
|
||||
it('updates player mode', function () {
|
||||
it('updates player mode', function() {
|
||||
var setPlayerMode = Initialize.prototype.setPlayerMode;
|
||||
|
||||
setPlayerMode.call(state, 'html5');
|
||||
@@ -253,7 +252,7 @@ function (Initialize) {
|
||||
expect(state.currentPlayerMode).toBe('flash');
|
||||
});
|
||||
|
||||
it('sets default mode if passed is not supported', function () {
|
||||
it('sets default mode if passed is not supported', function() {
|
||||
var setPlayerMode = Initialize.prototype.setPlayerMode;
|
||||
|
||||
setPlayerMode.call(state, '77html77');
|
||||
@@ -261,14 +260,14 @@ function (Initialize) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPlayerMode', function () {
|
||||
beforeEach(function () {
|
||||
describe('getPlayerMode', function() {
|
||||
beforeEach(function() {
|
||||
state = {
|
||||
currentPlayerMode: 'flash',
|
||||
currentPlayerMode: 'flash'
|
||||
};
|
||||
});
|
||||
|
||||
it('returns current player mode', function () {
|
||||
it('returns current player mode', function() {
|
||||
var getPlayerMode = Initialize.prototype.getPlayerMode,
|
||||
actual = getPlayerMode.call(state);
|
||||
|
||||
@@ -276,10 +275,10 @@ function (Initialize) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('isFlashMode', function () {
|
||||
it('returns `true` if player in `flash` mode', function () {
|
||||
describe('isFlashMode', function() {
|
||||
it('returns `true` if player in `flash` mode', function() {
|
||||
var state = {
|
||||
getPlayerMode: jasmine.createSpy().and.returnValue('flash'),
|
||||
getPlayerMode: jasmine.createSpy().and.returnValue('flash')
|
||||
},
|
||||
isFlashMode = Initialize.prototype.isFlashMode,
|
||||
actual = isFlashMode.call(state);
|
||||
@@ -287,9 +286,9 @@ function (Initialize) {
|
||||
expect(actual).toBeTruthy();
|
||||
});
|
||||
|
||||
it('returns `false` if player is not in `flash` mode', function () {
|
||||
it('returns `false` if player is not in `flash` mode', function() {
|
||||
var state = {
|
||||
getPlayerMode: jasmine.createSpy().and.returnValue('html5'),
|
||||
getPlayerMode: jasmine.createSpy().and.returnValue('html5')
|
||||
},
|
||||
isFlashMode = Initialize.prototype.isFlashMode,
|
||||
actual = isFlashMode.call(state);
|
||||
@@ -298,10 +297,10 @@ function (Initialize) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('isHtml5Mode', function () {
|
||||
it('returns `true` if player in `html5` mode', function () {
|
||||
describe('isHtml5Mode', function() {
|
||||
it('returns `true` if player in `html5` mode', function() {
|
||||
var state = {
|
||||
getPlayerMode: jasmine.createSpy().and.returnValue('html5'),
|
||||
getPlayerMode: jasmine.createSpy().and.returnValue('html5')
|
||||
},
|
||||
isHtml5Mode = Initialize.prototype.isHtml5Mode,
|
||||
actual = isHtml5Mode.call(state);
|
||||
@@ -309,9 +308,9 @@ function (Initialize) {
|
||||
expect(actual).toBeTruthy();
|
||||
});
|
||||
|
||||
it('returns `false` if player is not in `html5` mode', function () {
|
||||
it('returns `false` if player is not in `html5` mode', function() {
|
||||
var state = {
|
||||
getPlayerMode: jasmine.createSpy().and.returnValue('flash'),
|
||||
getPlayerMode: jasmine.createSpy().and.returnValue('flash')
|
||||
},
|
||||
isHtml5Mode = Initialize.prototype.isHtml5Mode,
|
||||
actual = isHtml5Mode.call(state);
|
||||
@@ -321,5 +320,4 @@ function (Initialize) {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(function (require) {
|
||||
require(
|
||||
(function(require) {
|
||||
require(
|
||||
['video/00_iterator.js'],
|
||||
function (Iterator) {
|
||||
describe('Iterator', function () {
|
||||
function(Iterator) {
|
||||
describe('Iterator', function() {
|
||||
var list = ['a', 'b', 'c', 'd', 'e'],
|
||||
iterator;
|
||||
|
||||
@@ -10,36 +10,36 @@ function (Iterator) {
|
||||
iterator = new Iterator(list);
|
||||
});
|
||||
|
||||
it('size contains correct list length', function () {
|
||||
it('size contains correct list length', function() {
|
||||
expect(iterator.size).toBe(list.length);
|
||||
expect(iterator.lastIndex).toBe(list.length - 1);
|
||||
});
|
||||
|
||||
describe('next', function () {
|
||||
describe('with passed `index`', function () {
|
||||
it('returns next item in the list', function () {
|
||||
describe('next', function() {
|
||||
describe('with passed `index`', function() {
|
||||
it('returns next item in the list', function() {
|
||||
expect(iterator.next(2)).toBe('d');
|
||||
expect(iterator.next(0)).toBe('b');
|
||||
});
|
||||
|
||||
it('returns first item if index equal last item', function () {
|
||||
it('returns first item if index equal last item', function() {
|
||||
expect(iterator.next(4)).toBe('a');
|
||||
});
|
||||
|
||||
it('returns next item if index is not valid', function () {
|
||||
it('returns next item if index is not valid', function() {
|
||||
expect(iterator.next(-4)).toBe('b'); // index < 0
|
||||
expect(iterator.next(100)).toBe('c'); // index > size
|
||||
expect(iterator.next('99')).toBe('d'); // incorrect Type
|
||||
});
|
||||
});
|
||||
|
||||
describe('without passed `index`', function () {
|
||||
it('returns next item in the list', function () {
|
||||
describe('without passed `index`', function() {
|
||||
it('returns next item in the list', function() {
|
||||
expect(iterator.next()).toBe('b');
|
||||
expect(iterator.next()).toBe('c');
|
||||
});
|
||||
|
||||
it('returns first item if index equal last item', function () {
|
||||
it('returns first item if index equal last item', function() {
|
||||
expect(iterator.next()).toBe('b');
|
||||
expect(iterator.next()).toBe('c');
|
||||
expect(iterator.next()).toBe('d');
|
||||
@@ -49,45 +49,45 @@ function (Iterator) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('prev', function () {
|
||||
describe('with passed `index`', function () {
|
||||
it('returns previous item in the list', function () {
|
||||
describe('prev', function() {
|
||||
describe('with passed `index`', function() {
|
||||
it('returns previous item in the list', function() {
|
||||
expect(iterator.prev(3)).toBe('c');
|
||||
expect(iterator.prev(1)).toBe('a');
|
||||
});
|
||||
|
||||
it('returns last item if index equal first item', function () {
|
||||
it('returns last item if index equal first item', function() {
|
||||
expect(iterator.prev(0)).toBe('e');
|
||||
});
|
||||
|
||||
it('returns previous item if index is not valid', function () {
|
||||
it('returns previous item if index is not valid', function() {
|
||||
expect(iterator.prev(-4)).toBe('e'); // index < 0
|
||||
expect(iterator.prev(100)).toBe('d'); // index > size
|
||||
expect(iterator.prev('99')).toBe('c'); // incorrect Type
|
||||
});
|
||||
});
|
||||
|
||||
describe('without passed `index`', function () {
|
||||
it('returns previous item in the list', function () {
|
||||
describe('without passed `index`', function() {
|
||||
it('returns previous item in the list', function() {
|
||||
expect(iterator.prev()).toBe('e');
|
||||
expect(iterator.prev()).toBe('d');
|
||||
});
|
||||
|
||||
it('returns last item if index equal first item', function () {
|
||||
it('returns last item if index equal first item', function() {
|
||||
expect(iterator.prev()).toBe('e');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('returns last item in the list', function () {
|
||||
it('returns last item in the list', function() {
|
||||
expect(iterator.last()).toBe('e');
|
||||
});
|
||||
|
||||
it('returns first item in the list', function () {
|
||||
it('returns first item in the list', function() {
|
||||
expect(iterator.first()).toBe('a');
|
||||
});
|
||||
|
||||
it('isEnd works correctly', function () {
|
||||
it('isEnd works correctly', function() {
|
||||
expect(iterator.isEnd()).toBeFalsy();
|
||||
iterator.next(); // => index 1
|
||||
expect(iterator.isEnd()).toBeFalsy();
|
||||
|
||||
@@ -1,26 +1,24 @@
|
||||
(function (requirejs, require, define, undefined) {
|
||||
|
||||
require(
|
||||
(function(requirejs, require, define, undefined) {
|
||||
require(
|
||||
['video/00_resizer.js'],
|
||||
function (Resizer) {
|
||||
|
||||
describe('Resizer', function () {
|
||||
function(Resizer) {
|
||||
describe('Resizer', function() {
|
||||
var html = [
|
||||
'<div ' +
|
||||
'class="rszr-wrapper" ' +
|
||||
'style="width:200px; height: 200px;"' +
|
||||
'>',
|
||||
'<div ' +
|
||||
'<div ' +
|
||||
'class="rszr-el" ' +
|
||||
'style="width:100px; height: 150px;"' +
|
||||
'>',
|
||||
'Content',
|
||||
'</div>',
|
||||
'Content',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join(''),
|
||||
config, container, element;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
setFixtures(html);
|
||||
|
||||
container = $('.rszr-wrapper');
|
||||
@@ -34,13 +32,13 @@ function (Resizer) {
|
||||
});
|
||||
|
||||
it('When Initialize without required parameters, log message is shown',
|
||||
function () {
|
||||
function() {
|
||||
new Resizer({ });
|
||||
expect(console.log).toHaveBeenCalled();
|
||||
}
|
||||
);
|
||||
|
||||
it('`alignByWidthOnly` works correctly', function () {
|
||||
it('`alignByWidthOnly` works correctly', function() {
|
||||
var resizer = new Resizer(config).alignByWidthOnly(),
|
||||
expectedWidth = container.width(),
|
||||
realWidth = element.width();
|
||||
@@ -48,7 +46,7 @@ function (Resizer) {
|
||||
expect(realWidth).toBe(expectedWidth);
|
||||
});
|
||||
|
||||
it('`alignByHeightOnly` works correctly', function () {
|
||||
it('`alignByHeightOnly` works correctly', function() {
|
||||
var resizer = new Resizer(config).alignByHeightOnly(),
|
||||
expectedHeight = container.height(),
|
||||
realHeight = element.height();
|
||||
@@ -56,7 +54,7 @@ function (Resizer) {
|
||||
expect(realHeight).toBe(expectedHeight);
|
||||
});
|
||||
|
||||
it('`align` works correctly', function () {
|
||||
it('`align` works correctly', function() {
|
||||
var resizer = new Resizer(config).align(),
|
||||
expectedHeight = container.height(),
|
||||
realHeight = element.height(),
|
||||
@@ -71,10 +69,9 @@ function (Resizer) {
|
||||
realWidth = element.width();
|
||||
|
||||
expect(realWidth).toBe(expectedWidth);
|
||||
|
||||
});
|
||||
|
||||
it('`setMode` works correctly', function () {
|
||||
it('`setMode` works correctly', function() {
|
||||
var resizer = new Resizer(config).setMode('height'),
|
||||
expectedHeight = container.height(),
|
||||
realHeight = element.height(),
|
||||
@@ -91,7 +88,7 @@ function (Resizer) {
|
||||
expect(realWidth).toBe(expectedWidth);
|
||||
});
|
||||
|
||||
it('`setElement` works correctly', function () {
|
||||
it('`setElement` works correctly', function() {
|
||||
container.append('<div ' +
|
||||
'id="Another-el" ' +
|
||||
'style="width:100px; height: 150px;"' +
|
||||
@@ -105,14 +102,14 @@ function (Resizer) {
|
||||
expect(newElement.height()).toBe(expectedHeight);
|
||||
});
|
||||
|
||||
describe('Callbacks', function () {
|
||||
describe('Callbacks', function() {
|
||||
var resizer,
|
||||
spiesList = [];
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
var spiesCount = _.range(3);
|
||||
|
||||
spiesList = $.map(spiesCount, function () {
|
||||
spiesList = $.map(spiesCount, function() {
|
||||
return jasmine.createSpy();
|
||||
});
|
||||
|
||||
@@ -120,19 +117,19 @@ function (Resizer) {
|
||||
});
|
||||
|
||||
|
||||
it('callbacks are called', function () {
|
||||
$.each(spiesList, function (index, spy) {
|
||||
it('callbacks are called', function() {
|
||||
$.each(spiesList, function(index, spy) {
|
||||
resizer.callbacks.add(spy);
|
||||
});
|
||||
|
||||
resizer.align();
|
||||
|
||||
$.each(spiesList, function (index, spy) {
|
||||
$.each(spiesList, function(index, spy) {
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('callback called just once', function () {
|
||||
it('callback called just once', function() {
|
||||
resizer.callbacks.once(spiesList[0]);
|
||||
|
||||
resizer
|
||||
@@ -142,21 +139,21 @@ function (Resizer) {
|
||||
expect(spiesList[0].calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it('all callbacks are removed', function () {
|
||||
$.each(spiesList, function (index, spy) {
|
||||
it('all callbacks are removed', function() {
|
||||
$.each(spiesList, function(index, spy) {
|
||||
resizer.callbacks.add(spy);
|
||||
});
|
||||
|
||||
resizer.callbacks.removeAll();
|
||||
resizer.align();
|
||||
|
||||
$.each(spiesList, function (index, spy) {
|
||||
$.each(spiesList, function(index, spy) {
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('specific callback is removed', function () {
|
||||
$.each(spiesList, function (index, spy) {
|
||||
it('specific callback is removed', function() {
|
||||
$.each(spiesList, function(index, spy) {
|
||||
resizer.callbacks.add(spy);
|
||||
});
|
||||
|
||||
@@ -168,32 +165,31 @@ function (Resizer) {
|
||||
|
||||
it(
|
||||
'Error message is shown when wrong argument type is passed',
|
||||
function ()
|
||||
function()
|
||||
{
|
||||
var methods = ['add', 'once'],
|
||||
errorMessage = '[Video info]: TypeError: Argument is not a function.',
|
||||
arg = {};
|
||||
var methods = ['add', 'once'],
|
||||
errorMessage = '[Video info]: TypeError: Argument is not a function.',
|
||||
arg = {};
|
||||
|
||||
spyOn(console, 'error');
|
||||
spyOn(console, 'error');
|
||||
|
||||
$.each(methods, function (index, methodName) {
|
||||
resizer.callbacks[methodName](arg);
|
||||
expect(console.error).toHaveBeenCalledWith(errorMessage);
|
||||
//reset spy
|
||||
console.log.calls.reset();
|
||||
$.each(methods, function(index, methodName) {
|
||||
resizer.callbacks[methodName](arg);
|
||||
expect(console.error).toHaveBeenCalledWith(errorMessage);
|
||||
// reset spy
|
||||
console.log.calls.reset();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('Delta', function () {
|
||||
describe('Delta', function() {
|
||||
var resizer;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
resizer = new Resizer(config);
|
||||
});
|
||||
|
||||
it('adding delta align correctly by height', function () {
|
||||
it('adding delta align correctly by height', function() {
|
||||
var delta = 100,
|
||||
expectedHeight = container.height() + delta,
|
||||
realHeight;
|
||||
@@ -207,7 +203,7 @@ function (Resizer) {
|
||||
expect(realHeight).toBe(expectedHeight);
|
||||
});
|
||||
|
||||
it('adding delta align correctly by width', function () {
|
||||
it('adding delta align correctly by width', function() {
|
||||
var delta = 100,
|
||||
expectedWidth = container.width() + delta,
|
||||
realWidth;
|
||||
@@ -221,7 +217,7 @@ function (Resizer) {
|
||||
expect(realWidth).toBe(expectedWidth);
|
||||
});
|
||||
|
||||
it('substract delta align correctly by height', function () {
|
||||
it('substract delta align correctly by height', function() {
|
||||
var delta = 100,
|
||||
expectedHeight = container.height() - delta,
|
||||
realHeight;
|
||||
@@ -235,7 +231,7 @@ function (Resizer) {
|
||||
expect(realHeight).toBe(expectedHeight);
|
||||
});
|
||||
|
||||
it('substract delta align correctly by width', function () {
|
||||
it('substract delta align correctly by width', function() {
|
||||
var delta = 100,
|
||||
expectedWidth = container.width() - delta,
|
||||
realWidth;
|
||||
@@ -249,7 +245,7 @@ function (Resizer) {
|
||||
expect(realWidth).toBe(expectedWidth);
|
||||
});
|
||||
|
||||
it('reset delta', function () {
|
||||
it('reset delta', function() {
|
||||
var delta = 100,
|
||||
expectedWidth = container.width(),
|
||||
realWidth;
|
||||
@@ -266,6 +262,4 @@ function (Resizer) {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(function (require) {
|
||||
require(
|
||||
(function(require) {
|
||||
require(
|
||||
['video/00_sjson.js'],
|
||||
function (Sjson) {
|
||||
describe('Sjson', function () {
|
||||
function(Sjson) {
|
||||
describe('Sjson', function() {
|
||||
var data = jasmine.stubbedCaption,
|
||||
sjson;
|
||||
var videoStops = [0, 3120, 6270, 8490, 21620, 24920];
|
||||
@@ -12,19 +12,19 @@ function (Sjson) {
|
||||
sjson = new Sjson(data);
|
||||
});
|
||||
|
||||
it ('returns captions', function () {
|
||||
it('returns captions', function() {
|
||||
expect(sjson.getCaptions()).toEqual(data.text);
|
||||
});
|
||||
|
||||
it ('returns start times', function () {
|
||||
it('returns start times', function() {
|
||||
expect(sjson.getStartTimes()).toEqual(data.start);
|
||||
});
|
||||
|
||||
it ('returns correct length', function () {
|
||||
it('returns correct length', function() {
|
||||
expect(sjson.getSize()).toEqual(data.text.length);
|
||||
});
|
||||
|
||||
it('search returns a correct caption index', function () {
|
||||
it('search returns a correct caption index', function() {
|
||||
expect(sjson.search(videoStops[0])).toEqual(0);
|
||||
expect(sjson.search(videoStops[1])).toEqual(1);
|
||||
expect(sjson.search(videoStops[2])).toEqual(2);
|
||||
@@ -41,7 +41,7 @@ function (Sjson) {
|
||||
expect(sjson.search(-1)).toEqual(0);
|
||||
});
|
||||
|
||||
it('search only searches through a subrange of times if start / end times are specified', function () {
|
||||
it('search only searches through a subrange of times if start / end times are specified', function() {
|
||||
var start = videoStops[2] - 100;
|
||||
var end = videoStops[5] - 100;
|
||||
var results = sjson.filter(start, end);
|
||||
@@ -54,7 +54,7 @@ function (Sjson) {
|
||||
expect(sjson.search(OUT_OF_BOUNDS_STOP, start, end)).toEqual(expectedLength);
|
||||
});
|
||||
|
||||
it('filters results correctly given a start and end time', function () {
|
||||
it('filters results correctly given a start and end time', function() {
|
||||
var start = videoStops[1] - 100;
|
||||
var end = videoStops[4] - 100;
|
||||
var results = sjson.filter(start, end);
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
(function (undefined) {
|
||||
describe('Video Accessible Menu', function () {
|
||||
(function(undefined) {
|
||||
describe('Video Accessible Menu', function() {
|
||||
var state;
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
});
|
||||
|
||||
describe('constructor', function () {
|
||||
describe('always', function () {
|
||||
describe('constructor', function() {
|
||||
describe('always', function() {
|
||||
var videoTracks, container, button, menu, menuItems,
|
||||
menuItemsLinks;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
videoTracks = $('li.video-tracks');
|
||||
container = videoTracks.children('div.a11y-menu-container');
|
||||
@@ -23,7 +23,7 @@
|
||||
menuItemsLinks = menuItems.children('a.a11y-menu-item-link');
|
||||
});
|
||||
|
||||
it('add the accessible menu', function () {
|
||||
it('add the accessible menu', function() {
|
||||
var activeMenuItem;
|
||||
// Make sure we have the expected HTML structure:
|
||||
// Menu container exists
|
||||
@@ -59,7 +59,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('when running', function () {
|
||||
describe('when running', function() {
|
||||
var videoTracks, container, button, menu, menuItems,
|
||||
menuItemsLinks, KEY = $.ui.keyCode,
|
||||
|
||||
@@ -88,12 +88,12 @@
|
||||
// Get next element in array or cyles back to the first if
|
||||
// it is the last.
|
||||
nextSpeed = function(index) {
|
||||
return speedEntries.eq(index >= speedEntries.length-1 ?
|
||||
return speedEntries.eq(index >= speedEntries.length - 1 ?
|
||||
0 :
|
||||
index + 1);
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
videoTracks = $('li.video-tracks');
|
||||
container = videoTracks.children('div.a11y-menu-container');
|
||||
@@ -104,7 +104,7 @@
|
||||
spyOn($.fn, 'focus').and.callThrough();
|
||||
});
|
||||
|
||||
it('open/close the menu on mouseenter/mouseleave', function () {
|
||||
it('open/close the menu on mouseenter/mouseleave', function() {
|
||||
container.mouseenter();
|
||||
expect(container).toHaveClass('open');
|
||||
container.mouseleave();
|
||||
@@ -112,72 +112,72 @@
|
||||
});
|
||||
|
||||
it('do not close the menu on mouseleave if a menu item has ' +
|
||||
'focus', function () {
|
||||
'focus', function() {
|
||||
// Open menu. Focus is on last menu item.
|
||||
container.trigger(keyPressEvent(KEY.ENTER));
|
||||
container.mouseenter().mouseleave();
|
||||
expect(container).toHaveClass('open');
|
||||
});
|
||||
|
||||
it('close the menu on click', function () {
|
||||
it('close the menu on click', function() {
|
||||
container.mouseenter().click();
|
||||
expect(container).not.toHaveClass('open');
|
||||
});
|
||||
|
||||
it('close the menu on outside click', function () {
|
||||
it('close the menu on outside click', function() {
|
||||
container.trigger(keyPressEvent(KEY.ENTER));
|
||||
$(window).click();
|
||||
expect(container).not.toHaveClass('open');
|
||||
});
|
||||
|
||||
it('open the menu on ENTER keydown', function () {
|
||||
it('open the menu on ENTER keydown', function() {
|
||||
container.trigger(keyPressEvent(KEY.ENTER));
|
||||
expect(container).toHaveClass('open');
|
||||
expect(menuItemsLinks.last().focus).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('open the menu on SPACE keydown', function () {
|
||||
it('open the menu on SPACE keydown', function() {
|
||||
container.trigger(keyPressEvent(KEY.SPACE));
|
||||
expect(container).toHaveClass('open');
|
||||
expect(menuItemsLinks.last().focus).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('open the menu on UP keydown', function () {
|
||||
it('open the menu on UP keydown', function() {
|
||||
container.trigger(keyPressEvent(KEY.UP));
|
||||
expect(container).toHaveClass('open');
|
||||
expect(menuItemsLinks.last().focus).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('close the menu on ESCAPE keydown', function () {
|
||||
it('close the menu on ESCAPE keydown', function() {
|
||||
container.trigger(keyPressEvent(KEY.ESCAPE));
|
||||
expect(container).not.toHaveClass('open');
|
||||
});
|
||||
|
||||
it('UP and DOWN keydown function as expected on menu items',
|
||||
function () {
|
||||
function() {
|
||||
// Iterate through list in both directions and check if
|
||||
// things wrap up correctly.
|
||||
var lastEntry = menuItemsLinks.length-1, i;
|
||||
var lastEntry = menuItemsLinks.length - 1, i;
|
||||
|
||||
// First open menu
|
||||
container.trigger(keyPressEvent(KEY.UP));
|
||||
container.trigger(keyPressEvent(KEY.UP));
|
||||
|
||||
// Iterate with UP key until we have looped.
|
||||
for (i = lastEntry; i >= 0; i--) {
|
||||
menuItemsLinks.eq(i).trigger(keyPressEvent(KEY.UP));
|
||||
}
|
||||
for (i = lastEntry; i >= 0; i--) {
|
||||
menuItemsLinks.eq(i).trigger(keyPressEvent(KEY.UP));
|
||||
}
|
||||
|
||||
// Iterate with DOWN key until we have looped.
|
||||
for (i = 0; i <= lastEntry; i++) {
|
||||
menuItemsLinks.eq(i).trigger(keyPressEvent(KEY.DOWN));
|
||||
}
|
||||
for (i = 0; i <= lastEntry; i++) {
|
||||
menuItemsLinks.eq(i).trigger(keyPressEvent(KEY.DOWN));
|
||||
}
|
||||
|
||||
// Test if each element has been called twice.
|
||||
expect($.fn.focus.calls.count())
|
||||
.toEqual(2*menuItemsLinks.length+1);
|
||||
});
|
||||
expect($.fn.focus.calls.count())
|
||||
.toEqual(2 * menuItemsLinks.length + 1);
|
||||
});
|
||||
|
||||
it('ESC keydown on menu item closes menu', function () {
|
||||
it('ESC keydown on menu item closes menu', function() {
|
||||
// First open menu. Focus is on last speed entry.
|
||||
container.trigger(keyPressEvent(KEY.UP));
|
||||
menuItemsLinks.last().trigger(keyPressEvent(KEY.ESCAPE));
|
||||
@@ -189,12 +189,12 @@
|
||||
});
|
||||
|
||||
it('ENTER keydown on menu item selects its data and closes menu',
|
||||
function () {
|
||||
function() {
|
||||
// First open menu.
|
||||
container.trigger(keyPressEvent(KEY.UP));
|
||||
container.trigger(keyPressEvent(KEY.UP));
|
||||
// Focus on '.txt'
|
||||
menuItemsLinks.eq(0).focus();
|
||||
menuItemsLinks.eq(0).trigger(keyPressEvent(KEY.ENTER));
|
||||
menuItemsLinks.eq(0).focus();
|
||||
menuItemsLinks.eq(0).trigger(keyPressEvent(KEY.ENTER));
|
||||
|
||||
// Menu is closed, focus has been returned to container
|
||||
// and file format is '.txt'.
|
||||
@@ -204,15 +204,15 @@
|
||||
.toHaveClass('active');
|
||||
expect($('.speeds p.active')).toHaveHtml('1.50x');
|
||||
*/
|
||||
});
|
||||
});
|
||||
|
||||
it('SPACE keydown on menu item selects its data and closes menu',
|
||||
function () {
|
||||
function() {
|
||||
// First open menu.
|
||||
container.trigger(keyPressEvent(KEY.UP));
|
||||
container.trigger(keyPressEvent(KEY.UP));
|
||||
// Focus on '.txt'
|
||||
menuItemsLinks.eq(0).focus();
|
||||
menuItemsLinks.eq(0).trigger(keyPressEvent(KEY.SPACE));
|
||||
menuItemsLinks.eq(0).focus();
|
||||
menuItemsLinks.eq(0).trigger(keyPressEvent(KEY.SPACE));
|
||||
|
||||
// Menu is closed, focus has been returned to container
|
||||
// and file format is '.txt'.
|
||||
@@ -222,11 +222,11 @@
|
||||
.toHaveClass('active');
|
||||
expect($('.speeds p.active')).toHaveHtml('1.50x');
|
||||
*/
|
||||
});
|
||||
});
|
||||
|
||||
// TO DO? No such behavior implemented.
|
||||
xit('TAB + SHIFT keydown on speed entry closes menu and gives ' +
|
||||
'focus to Play/Pause control', function () {
|
||||
'focus to Play/Pause control', function() {
|
||||
// First open menu. Focus is on last speed entry.
|
||||
speedControl.trigger(keyPressEvent(KEY.UP));
|
||||
speedEntries.last().trigger(tabBackPressEvent());
|
||||
@@ -239,7 +239,7 @@
|
||||
|
||||
// TO DO? No such behavior implemented.
|
||||
xit('TAB keydown on speed entry closes menu and gives focus ' +
|
||||
'to Volume control', function () {
|
||||
'to Volume control', function() {
|
||||
// First open menu. Focus is on last speed entry.
|
||||
speedControl.trigger(keyPressEvent(KEY.UP));
|
||||
speedEntries.last().trigger(tabForwardPressEvent());
|
||||
@@ -253,9 +253,9 @@
|
||||
});
|
||||
|
||||
// TODO
|
||||
xdescribe('change file format', function () {
|
||||
describe('when new file format is not the same', function () {
|
||||
beforeEach(function () {
|
||||
xdescribe('change file format', function() {
|
||||
describe('when new file format is not the same', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
state.videoSpeedControl.setSpeed(1.0);
|
||||
spyOn(state.videoPlayer, 'onSpeedChange').and.callThrough();
|
||||
@@ -263,7 +263,7 @@
|
||||
$('li[data-speed="0.75"] .speed-link').click();
|
||||
});
|
||||
|
||||
it('trigger speedChange event', function () {
|
||||
it('trigger speedChange event', function() {
|
||||
expect(state.videoPlayer.onSpeedChange).toHaveBeenCalled();
|
||||
expect(state.videoSpeedControl.currentSpeed).toEqual(0.75);
|
||||
});
|
||||
@@ -271,14 +271,14 @@
|
||||
});
|
||||
|
||||
// TODO
|
||||
xdescribe('onSpeedChange', function () {
|
||||
beforeEach(function () {
|
||||
xdescribe('onSpeedChange', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
$('li[data-speed="1.0"] .speed-link').addClass('active');
|
||||
state.videoSpeedControl.setSpeed(0.75);
|
||||
});
|
||||
|
||||
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"]'))
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
(function (WAIT_TIMEOUT) {
|
||||
(function(WAIT_TIMEOUT) {
|
||||
'use strict';
|
||||
describe('VideoBumper', function () {
|
||||
describe('VideoBumper', function() {
|
||||
var state, oldOTBD, waitForPlaying;
|
||||
|
||||
waitForPlaying = function (state, done) {
|
||||
jasmine.waitUntil(function () {
|
||||
waitForPlaying = function(state, done) {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.el.hasClass('is-playing');
|
||||
}).done(done);
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine
|
||||
.createSpy('onTouchBasedDevice').and.returnValue(null);
|
||||
@@ -18,7 +18,7 @@
|
||||
jasmine.clock().install();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
state.storage.clear();
|
||||
if (state.bumperState && state.bumperState.videoPlayer) {
|
||||
@@ -31,39 +31,39 @@
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
|
||||
it('can render the bumper video', function () {
|
||||
it('can render the bumper video', function() {
|
||||
expect($('.is-bumper')).toExist();
|
||||
});
|
||||
|
||||
it('can show the main video on error', function (done) {
|
||||
it('can show the main video on error', function(done) {
|
||||
state.el.triggerHandler('error');
|
||||
jasmine.clock().tick(20);
|
||||
expect($('.is-bumper')).not.toExist();
|
||||
waitForPlaying(state, done);
|
||||
});
|
||||
|
||||
it('can show the main video once bumper ends', function (done) {
|
||||
it('can show the main video once bumper ends', function(done) {
|
||||
state.el.trigger('ended');
|
||||
jasmine.clock().tick(20);
|
||||
expect($('.is-bumper')).not.toExist();
|
||||
waitForPlaying(state, done);
|
||||
});
|
||||
|
||||
it('can show the main video on skip', function (done) {
|
||||
it('can show the main video on skip', function(done) {
|
||||
state.bumperState.videoBumper.skip();
|
||||
jasmine.clock().tick(20);
|
||||
expect($('.is-bumper')).not.toExist();
|
||||
waitForPlaying(state, done);
|
||||
});
|
||||
|
||||
it('can stop the bumper video playing if it is too long', function (done) {
|
||||
it('can stop the bumper video playing if it is too long', function(done) {
|
||||
state.el.trigger('timeupdate', [state.bumperState.videoBumper.maxBumperDuration + 1]);
|
||||
jasmine.clock().tick(20);
|
||||
expect($('.is-bumper')).not.toExist();
|
||||
waitForPlaying(state, done);
|
||||
});
|
||||
|
||||
it('can save appropriate states correctly on ended', function () {
|
||||
it('can save appropriate states correctly on ended', function() {
|
||||
var saveState = jasmine.createSpy('saveState');
|
||||
state.bumperState.videoSaveStatePlugin.saveState = saveState;
|
||||
state.el.trigger('ended');
|
||||
@@ -72,7 +72,7 @@
|
||||
bumper_last_view_date: true});
|
||||
});
|
||||
|
||||
it('can save appropriate states correctly on skip', function () {
|
||||
it('can save appropriate states correctly on skip', function() {
|
||||
var saveState = jasmine.createSpy('saveState');
|
||||
state.bumperState.videoSaveStatePlugin.saveState = saveState;
|
||||
state.bumperState.videoBumper.skip();
|
||||
@@ -82,7 +82,7 @@
|
||||
bumper_last_view_date: true});
|
||||
});
|
||||
|
||||
it('can save appropriate states correctly on error', function () {
|
||||
it('can save appropriate states correctly on error', function() {
|
||||
var saveState = jasmine.createSpy('saveState');
|
||||
state.bumperState.videoSaveStatePlugin.saveState = saveState;
|
||||
state.el.triggerHandler('error');
|
||||
@@ -92,7 +92,7 @@
|
||||
bumper_last_view_date: true});
|
||||
});
|
||||
|
||||
it('can save appropriate states correctly on skip and do not show again', function () {
|
||||
it('can save appropriate states correctly on skip and do not show again', function() {
|
||||
var saveState = jasmine.createSpy('saveState');
|
||||
state.bumperState.videoSaveStatePlugin.saveState = saveState;
|
||||
state.bumperState.videoBumper.skipAndDoNotShowAgain();
|
||||
@@ -102,7 +102,7 @@
|
||||
bumper_last_view_date: true, bumper_do_not_show_again: true});
|
||||
});
|
||||
|
||||
it('can destroy itself', function () {
|
||||
it('can destroy itself', function() {
|
||||
state.bumperState.videoBumper.destroy();
|
||||
expect(state.videoBumper).toBeUndefined();
|
||||
});
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
(function (undefined) {
|
||||
describe('VideoCaption', function () {
|
||||
(function(undefined) {
|
||||
describe('VideoCaption', function() {
|
||||
var state, oldOTBD;
|
||||
var parseIntAttribute = function (element, attrName) {
|
||||
var parseIntAttribute = function(element, attrName) {
|
||||
return parseInt(element.attr(attrName));
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice')
|
||||
.and.returnValue(null);
|
||||
@@ -13,7 +13,7 @@
|
||||
$.fn.scrollTo.calls.reset();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
// `source` tags should be removed to avoid memory leak bug that we
|
||||
// had before. Removing of `source` tag, not `video` tag, stops
|
||||
// loading video source and clears the memory.
|
||||
@@ -25,22 +25,20 @@
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
});
|
||||
|
||||
describe('constructor', function () {
|
||||
|
||||
describe('always', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
describe('constructor', function() {
|
||||
describe('always', function() {
|
||||
beforeEach(function() {
|
||||
spyOn($, 'ajaxWithPrefix').and.callThrough();
|
||||
});
|
||||
|
||||
it('create the transcript element', function () {
|
||||
it('create the transcript element', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
expect($('.video')).toContainElement('.subtitles');
|
||||
});
|
||||
|
||||
|
||||
it('has appropriate lang attributes', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
|
||||
$('.video .toggle-captions').trigger('click');
|
||||
|
||||
expect($('.video .subtitles-menu')).toHaveAttrs({
|
||||
@@ -51,12 +49,12 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('add transcript control to video player', function () {
|
||||
it('add transcript control to video player', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
expect($('.video')).toContainElement('.toggle-transcript');
|
||||
});
|
||||
|
||||
it('add ARIA attributes to transcript control', function () {
|
||||
it('add ARIA attributes to transcript control', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
var captionControl = $('.toggle-transcript');
|
||||
expect(captionControl).toHaveAttrs({
|
||||
@@ -70,12 +68,12 @@
|
||||
expect($('.video')).toContainElement('.closed-captions');
|
||||
});
|
||||
|
||||
it('fetch the transcript in HTML5 mode', function (done) {
|
||||
it('fetch the transcript in HTML5 mode', function(done) {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoCaption.loaded;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect($.ajaxWithPrefix).toHaveBeenCalledWith({
|
||||
url: '/transcript/translation/en',
|
||||
notifyOnError: false,
|
||||
@@ -88,14 +86,14 @@
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it('fetch the transcript in Flash mode', function (done) {
|
||||
it('fetch the transcript in Flash mode', function(done) {
|
||||
state = jasmine.initializePlayerYouTube();
|
||||
spyOn(state, 'isFlashMode').and.returnValue(true);
|
||||
state.videoCaption.fetchCaption();
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoCaption.loaded;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect($.ajaxWithPrefix).toHaveBeenCalledWith({
|
||||
url: '/transcript/translation/en',
|
||||
notifyOnError: false,
|
||||
@@ -110,12 +108,12 @@
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it('fetch the transcript in Youtube mode', function (done) {
|
||||
it('fetch the transcript in Youtube mode', function(done) {
|
||||
state = jasmine.initializePlayerYouTube();
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoCaption.loaded;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect($.ajaxWithPrefix).toHaveBeenCalledWith({
|
||||
url: '/transcript/translation/en',
|
||||
notifyOnError: false,
|
||||
@@ -130,24 +128,23 @@
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it('bind the mouse movement', function () {
|
||||
it('bind the mouse movement', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
expect($('.subtitles-menu')).toHandle('mouseover');
|
||||
expect($('.subtitles-menu')).toHandle('mouseout');
|
||||
expect($('.subtitles-menu')).toHandle('mousemove');
|
||||
expect($('.subtitles-menu')).toHandle('mousewheel');
|
||||
expect($('.subtitles-menu')).toHandle('DOMMouseScroll');
|
||||
});
|
||||
});
|
||||
|
||||
it('bind the scroll', function () {
|
||||
it('bind the scroll', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
expect($('.subtitles-menu'))
|
||||
.toHandleWith('scroll', state.videoControl.showControls);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('can destroy itself', function () {
|
||||
it('can destroy itself', function() {
|
||||
spyOn($, 'ajaxWithPrefix');
|
||||
state = jasmine.initializePlayer();
|
||||
var plugin = state.videoCaption;
|
||||
@@ -169,13 +166,12 @@
|
||||
});
|
||||
|
||||
describe('renderCaptions', function() {
|
||||
|
||||
describe('is rendered', function() {
|
||||
var KEY = $.ui.keyCode,
|
||||
|
||||
keyPressEvent = function(key) {
|
||||
return $.Event('keydown', { keyCode: key });
|
||||
};
|
||||
keyPressEvent = function(key) {
|
||||
return $.Event('keydown', {keyCode: key});
|
||||
};
|
||||
|
||||
it('toggles the captions on control click', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
@@ -215,16 +211,15 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('renderLanguageMenu', function () {
|
||||
|
||||
describe('is rendered', function () {
|
||||
describe('renderLanguageMenu', function() {
|
||||
describe('is rendered', function() {
|
||||
var KEY = $.ui.keyCode,
|
||||
|
||||
keyPressEvent = function(key) {
|
||||
return $.Event('keydown', { keyCode: key });
|
||||
};
|
||||
keyPressEvent = function(key) {
|
||||
return $.Event('keydown', {keyCode: key});
|
||||
};
|
||||
|
||||
it('if languages more than 1', function () {
|
||||
it('if languages more than 1', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
var transcripts = state.config.transcriptLanguages,
|
||||
langCodes = _.keys(transcripts),
|
||||
@@ -244,7 +239,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('when clicking on link with new language', function () {
|
||||
it('when clicking on link with new language', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
var Caption = state.videoCaption,
|
||||
link = $('.langs-list li[data-lang-code="de"] .control-lang');
|
||||
@@ -269,7 +264,7 @@
|
||||
expect(link).toHaveAttr('aria-pressed', 'true');
|
||||
});
|
||||
|
||||
it('when clicking on link with current language', function () {
|
||||
it('when clicking on link with current language', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
var Caption = state.videoCaption,
|
||||
link = $('.langs-list li[data-lang-code="en"] .control-lang');
|
||||
@@ -288,7 +283,7 @@
|
||||
expect(link).toHaveAttr('aria-pressed', 'true');
|
||||
});
|
||||
|
||||
it('open the language toggle on hover', function () {
|
||||
it('open the language toggle on hover', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
$('.lang').mouseenter();
|
||||
expect($('.lang')).toHaveClass('is-opened');
|
||||
@@ -314,10 +309,10 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('is not rendered', function () {
|
||||
it('if just 1 language', function () {
|
||||
describe('is not rendered', function() {
|
||||
it('if just 1 language', function() {
|
||||
state = jasmine.initializePlayer(null, {
|
||||
'transcriptLanguages': {"en": "English"}
|
||||
'transcriptLanguages': {'en': 'English'}
|
||||
});
|
||||
|
||||
expect($('.langs-list')).not.toExist();
|
||||
@@ -327,20 +322,20 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('when on a non touch-based device', function () {
|
||||
beforeEach(function (done) {
|
||||
describe('when on a non touch-based device', function() {
|
||||
beforeEach(function(done) {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoCaption.rendered;
|
||||
}).then(done);
|
||||
});
|
||||
|
||||
it('render the transcript', function () {
|
||||
it('render the transcript', function() {
|
||||
var captionsData = jasmine.stubbedCaption,
|
||||
items = $('.subtitles li[data-index]');
|
||||
items = $('.subtitles li[data-index]');
|
||||
|
||||
_.each(captionsData.text, function (text, index) {
|
||||
_.each(captionsData.text, function(text, index) {
|
||||
var item = items.eq(index);
|
||||
|
||||
expect(parseIntAttribute(item, 'data-index')).toEqual(index);
|
||||
@@ -350,7 +345,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('add a padding element to transcript', function () {
|
||||
it('add a padding element to transcript', function() {
|
||||
expect($('.subtitles li:first').hasClass('spacing'))
|
||||
.toBe(true);
|
||||
expect($('.subtitles li:last').hasClass('spacing'))
|
||||
@@ -358,7 +353,7 @@
|
||||
});
|
||||
|
||||
|
||||
it('bind all the transcript link', function () {
|
||||
it('bind all the transcript link', function() {
|
||||
var handlerList = ['captionMouseOverOut', 'captionClick',
|
||||
'captionMouseDown', 'captionFocus', 'captionBlur',
|
||||
'captionKeyDown'
|
||||
@@ -368,68 +363,66 @@
|
||||
spyOn(state.videoCaption, handler);
|
||||
});
|
||||
$('.subtitles li[data-index]').each(
|
||||
function (index, link) {
|
||||
function(index, link) {
|
||||
$(link).trigger('mouseover');
|
||||
expect(state.videoCaption.captionMouseOverOut).toHaveBeenCalled();
|
||||
|
||||
state.videoCaption.captionMouseOverOut.calls.reset();
|
||||
$(link).trigger('mouseout');
|
||||
expect(state.videoCaption.captionMouseOverOut).toHaveBeenCalled();
|
||||
|
||||
$(link).trigger('mouseover');
|
||||
expect(state.videoCaption.captionMouseOverOut).toHaveBeenCalled();
|
||||
$(this).click();
|
||||
expect(state.videoCaption.captionClick).toHaveBeenCalled();
|
||||
|
||||
state.videoCaption.captionMouseOverOut.calls.reset();
|
||||
$(link).trigger('mouseout');
|
||||
expect(state.videoCaption.captionMouseOverOut).toHaveBeenCalled();
|
||||
$(this).trigger('mousedown');
|
||||
expect(state.videoCaption.captionMouseDown).toHaveBeenCalled();
|
||||
|
||||
$(this).click();
|
||||
expect(state.videoCaption.captionClick).toHaveBeenCalled();
|
||||
$(this).trigger('focus');
|
||||
expect(state.videoCaption.captionFocus).toHaveBeenCalled();
|
||||
|
||||
$(this).trigger('mousedown');
|
||||
expect(state.videoCaption.captionMouseDown).toHaveBeenCalled();
|
||||
$(this).trigger('blur');
|
||||
expect(state.videoCaption.captionBlur).toHaveBeenCalled();
|
||||
|
||||
$(this).trigger('focus');
|
||||
expect(state.videoCaption.captionFocus).toHaveBeenCalled();
|
||||
|
||||
$(this).trigger('blur');
|
||||
expect(state.videoCaption.captionBlur).toHaveBeenCalled();
|
||||
|
||||
$(this).trigger('keydown');
|
||||
expect(state.videoCaption.captionKeyDown).toHaveBeenCalled();
|
||||
});
|
||||
$(this).trigger('keydown');
|
||||
expect(state.videoCaption.captionKeyDown).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('set rendered to true', function (done) {
|
||||
it('set rendered to true', function(done) {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoCaption.rendered;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(state.videoCaption.rendered).toBeTruthy();
|
||||
}).always(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when on a touch-based device', function () {
|
||||
beforeEach(function () {
|
||||
describe('when on a touch-based device', function() {
|
||||
beforeEach(function() {
|
||||
window.onTouchBasedDevice.and.returnValue(['iPad']);
|
||||
|
||||
state = jasmine.initializePlayer();
|
||||
$.fn.scrollTo.calls.reset();
|
||||
});
|
||||
|
||||
it('show explanation message', function () {
|
||||
it('show explanation message', function() {
|
||||
expect($('.subtitles .subtitles-menu li')).toHaveText(
|
||||
'Transcript will be displayed when you start playing the video.'
|
||||
);
|
||||
});
|
||||
|
||||
it('show transcript on play', function (done) {
|
||||
it('show transcript on play', function(done) {
|
||||
state.el.trigger('play');
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoCaption.rendered;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
var captionsData = jasmine.stubbedCaption,
|
||||
items = $('.subtitles li[data-index]');
|
||||
items = $('.subtitles li[data-index]');
|
||||
|
||||
_.each(captionsData.text, function (text, index) {
|
||||
_.each(captionsData.text, function(text, index) {
|
||||
var item = items.eq(index);
|
||||
|
||||
expect(parseIntAttribute(item, 'data-index')).toEqual(index);
|
||||
@@ -440,20 +433,20 @@
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it('does not set rendered to true', function () {
|
||||
it('does not set rendered to true', function() {
|
||||
expect(state.videoCaption.rendered).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when no transcripts file was specified', function () {
|
||||
beforeEach(function () {
|
||||
describe('when no transcripts file was specified', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer('video_all.html', {
|
||||
'sub': '',
|
||||
'transcriptLanguages': {},
|
||||
'transcriptLanguages': {}
|
||||
});
|
||||
});
|
||||
|
||||
it('transcript panel is not shown', function () {
|
||||
it('transcript panel is not shown', function() {
|
||||
expect(state.videoCaption.languageChooserEl).toBeHidden();
|
||||
});
|
||||
});
|
||||
@@ -461,12 +454,12 @@
|
||||
|
||||
var originalClearTimeout;
|
||||
|
||||
describe('mouse movement', function () {
|
||||
beforeEach(function (done) {
|
||||
describe('mouse movement', function() {
|
||||
beforeEach(function(done) {
|
||||
jasmine.clock().install();
|
||||
state = jasmine.initializePlayer();
|
||||
jasmine.clock().tick(50);
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoCaption.rendered;
|
||||
}).then(done);
|
||||
|
||||
@@ -475,19 +468,19 @@
|
||||
window.clearTimeout = jasmine.createSpy().and.callFake(originalClearTimeout);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
window.clearTimeout = originalClearTimeout;
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
|
||||
describe('when cursor is outside of the transcript box', function () {
|
||||
it('does not set freezing timeout', function () {
|
||||
describe('when cursor is outside of the transcript box', function() {
|
||||
it('does not set freezing timeout', function() {
|
||||
expect(state.videoCaption.frozen).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when cursor is in the transcript box', function () {
|
||||
beforeEach(function () {
|
||||
describe('when cursor is in the transcript box', function() {
|
||||
beforeEach(function() {
|
||||
spyOn(state.videoCaption, 'onMouseLeave');
|
||||
$(window).trigger(jQuery.Event('mousemove'));
|
||||
jasmine.clock().tick(state.config.captionsFreezeTime);
|
||||
@@ -495,20 +488,20 @@
|
||||
jasmine.clock().tick(state.config.captionsFreezeTime);
|
||||
});
|
||||
|
||||
it('set the freezing timeout', function () {
|
||||
it('set the freezing timeout', function() {
|
||||
expect(state.videoCaption.frozen).not.toBeFalsy();
|
||||
expect(state.videoCaption.onMouseLeave).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('when the cursor is moving', function () {
|
||||
it('reset the freezing timeout', function () {
|
||||
describe('when the cursor is moving', function() {
|
||||
it('reset the freezing timeout', function() {
|
||||
$('.subtitles-menu').trigger(jQuery.Event('mousemove'));
|
||||
expect(window.clearTimeout).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the mouse is scrolling', function () {
|
||||
it('reset the freezing timeout', function () {
|
||||
describe('when the mouse is scrolling', function() {
|
||||
it('reset the freezing timeout', function() {
|
||||
$('.subtitles-menu').trigger(jQuery.Event('mousewheel'));
|
||||
expect(window.clearTimeout).toHaveBeenCalled();
|
||||
});
|
||||
@@ -517,57 +510,56 @@
|
||||
|
||||
describe(
|
||||
'when cursor is moving out of the transcript box',
|
||||
function () {
|
||||
|
||||
beforeEach(function () {
|
||||
state.videoCaption.frozen = 100;
|
||||
$.fn.scrollTo.calls.reset();
|
||||
});
|
||||
|
||||
describe('always', function () {
|
||||
beforeEach(function () {
|
||||
$('.subtitles-menu').trigger(jQuery.Event('mouseout'));
|
||||
function() {
|
||||
beforeEach(function() {
|
||||
state.videoCaption.frozen = 100;
|
||||
$.fn.scrollTo.calls.reset();
|
||||
});
|
||||
|
||||
it('reset the freezing timeout', function () {
|
||||
expect(window.clearTimeout).toHaveBeenCalledWith(100);
|
||||
describe('always', function() {
|
||||
beforeEach(function() {
|
||||
$('.subtitles-menu').trigger(jQuery.Event('mouseout'));
|
||||
});
|
||||
|
||||
it('reset the freezing timeout', function() {
|
||||
expect(window.clearTimeout).toHaveBeenCalledWith(100);
|
||||
});
|
||||
|
||||
it('unfreeze the transcript', function() {
|
||||
expect(state.videoCaption.frozen).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
it('unfreeze the transcript', function () {
|
||||
expect(state.videoCaption.frozen).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the player is playing', function () {
|
||||
beforeEach(function () {
|
||||
state.videoCaption.playing = true;
|
||||
$('.subtitles-menu li[data-index]:first')
|
||||
describe('when the player is playing', function() {
|
||||
beforeEach(function() {
|
||||
state.videoCaption.playing = true;
|
||||
$('.subtitles-menu li[data-index]:first')
|
||||
.addClass('current');
|
||||
$('.subtitles-menu').trigger(jQuery.Event('mouseout'));
|
||||
$('.subtitles-menu').trigger(jQuery.Event('mouseout'));
|
||||
});
|
||||
|
||||
it('scroll the transcript', function() {
|
||||
expect($.fn.scrollTo).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('scroll the transcript', function () {
|
||||
expect($.fn.scrollTo).toHaveBeenCalled();
|
||||
describe('when the player is not playing', function() {
|
||||
beforeEach(function() {
|
||||
state.videoCaption.playing = false;
|
||||
$('.subtitles-menu').trigger(jQuery.Event('mouseout'));
|
||||
});
|
||||
|
||||
it('does not scroll the transcript', function() {
|
||||
expect($.fn.scrollTo).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the player is not playing', function () {
|
||||
beforeEach(function () {
|
||||
state.videoCaption.playing = false;
|
||||
$('.subtitles-menu').trigger(jQuery.Event('mouseout'));
|
||||
});
|
||||
|
||||
it('does not scroll the transcript', function () {
|
||||
expect($.fn.scrollTo).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchCaption', function () {
|
||||
describe('fetchCaption', function() {
|
||||
var Caption, msg;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
Caption = state.videoCaption;
|
||||
spyOn($, 'ajaxWithPrefix').and.callThrough();
|
||||
@@ -578,7 +570,7 @@
|
||||
spyOn(state, 'youtubeId').and.returnValue('Z5KLxerq05Y');
|
||||
});
|
||||
|
||||
it('show transcript on language change', function () {
|
||||
it('show transcript on language change', function() {
|
||||
Caption.loaded = true;
|
||||
Caption.fetchCaption();
|
||||
|
||||
@@ -588,7 +580,7 @@
|
||||
|
||||
msg = 'use cookie to show/hide transcripts if they have not been ' +
|
||||
'loaded yet';
|
||||
it(msg, function () {
|
||||
it(msg, function() {
|
||||
Caption.loaded = false;
|
||||
state.hide_captions = false;
|
||||
Caption.fetchCaption();
|
||||
@@ -605,7 +597,7 @@
|
||||
expect(Caption.hideCaptions).toHaveBeenCalledWith(true, false);
|
||||
});
|
||||
|
||||
it('on success: on touch devices', function () {
|
||||
it('on success: on touch devices', function() {
|
||||
state.isTouch = true;
|
||||
Caption.loaded = false;
|
||||
Caption.fetchCaption();
|
||||
@@ -619,7 +611,7 @@
|
||||
|
||||
msg = 'on success: change language on touch devices when ' +
|
||||
'transcripts have not been rendered yet';
|
||||
it(msg, function () {
|
||||
it(msg, function() {
|
||||
state.isTouch = true;
|
||||
Caption.loaded = true;
|
||||
Caption.rendered = false;
|
||||
@@ -632,7 +624,7 @@
|
||||
expect(Caption.loaded).toBeTruthy();
|
||||
});
|
||||
|
||||
it('on success: re-render on touch devices', function () {
|
||||
it('on success: re-render on touch devices', function() {
|
||||
state.isTouch = true;
|
||||
Caption.loaded = true;
|
||||
Caption.rendered = true;
|
||||
@@ -645,7 +637,7 @@
|
||||
expect(Caption.loaded).toBeTruthy();
|
||||
});
|
||||
|
||||
it('on success: rendered correct', function () {
|
||||
it('on success: rendered correct', function() {
|
||||
Caption.loaded = false;
|
||||
Caption.fetchCaption();
|
||||
|
||||
@@ -656,7 +648,7 @@
|
||||
expect(Caption.loaded).toBeTruthy();
|
||||
});
|
||||
|
||||
it('on success: re-rendered correct', function () {
|
||||
it('on success: re-rendered correct', function() {
|
||||
Caption.loaded = true;
|
||||
Caption.rendered = true;
|
||||
Caption.fetchCaption();
|
||||
@@ -669,9 +661,9 @@
|
||||
});
|
||||
|
||||
msg = 'on error: transcripts are hidden if there are no transcripts';
|
||||
it(msg, function () {
|
||||
it(msg, function() {
|
||||
spyOn(Caption, 'fetchAvailableTranslations');
|
||||
$.ajax.and.callFake(function (settings) {
|
||||
$.ajax.and.callFake(function(settings) {
|
||||
_.result(settings, 'error');
|
||||
});
|
||||
|
||||
@@ -687,10 +679,10 @@
|
||||
|
||||
msg = 'on error: for Html5 player an attempt to fetch transcript ' +
|
||||
'with youtubeId if there are no additional transcripts';
|
||||
it(msg, function () {
|
||||
it(msg, function() {
|
||||
spyOn(Caption, 'fetchAvailableTranslations');
|
||||
spyOn(Caption, 'fetchCaption').and.callThrough();
|
||||
$.ajax.and.callFake(function (settings) {
|
||||
$.ajax.and.callFake(function(settings) {
|
||||
_.result(settings, 'error');
|
||||
});
|
||||
|
||||
@@ -701,7 +693,7 @@
|
||||
|
||||
expect(Caption.fetchAvailableTranslations).not.toHaveBeenCalled();
|
||||
expect($.ajaxWithPrefix.calls.mostRecent().args[0].data)
|
||||
.toEqual({'videoId':'Z5KLxerq05Y'});
|
||||
.toEqual({'videoId': 'Z5KLxerq05Y'});
|
||||
expect(Caption.hideCaptions.calls.mostRecent().args)
|
||||
.toEqual([true, false]);
|
||||
expect(Caption.fetchCaption.calls.mostRecent().args[0]).toEqual(true);
|
||||
@@ -710,7 +702,7 @@
|
||||
|
||||
msg = 'on success: when fetchCaption called with fetch_with_youtubeId to ' +
|
||||
'get transcript with youtubeId for html5';
|
||||
it(msg, function () {
|
||||
it(msg, function() {
|
||||
spyOn(Caption, 'fetchAvailableTranslations');
|
||||
spyOn(Caption, 'fetchCaption').and.callThrough();
|
||||
|
||||
@@ -722,7 +714,7 @@
|
||||
|
||||
expect(Caption.fetchAvailableTranslations).not.toHaveBeenCalled();
|
||||
expect($.ajaxWithPrefix.calls.mostRecent().args[0].data)
|
||||
.toEqual({'videoId':'Z5KLxerq05Y'});
|
||||
.toEqual({'videoId': 'Z5KLxerq05Y'});
|
||||
expect(Caption.hideCaptions).toHaveBeenCalledWith(false);
|
||||
expect(Caption.fetchCaption.calls.mostRecent().args[0]).toEqual(true);
|
||||
expect(Caption.fetchCaption.calls.count()).toEqual(1);
|
||||
@@ -730,15 +722,15 @@
|
||||
|
||||
msg = 'on error: fetch available translations if there are ' +
|
||||
'additional transcripts';
|
||||
it(msg, function () {
|
||||
it(msg, function() {
|
||||
$.ajax
|
||||
.and.callFake(function (settings) {
|
||||
.and.callFake(function(settings) {
|
||||
_.result(settings, 'error');
|
||||
});
|
||||
|
||||
state.config.transcriptLanguages = {
|
||||
'en': 'English',
|
||||
'uk': 'Ukrainian',
|
||||
'uk': 'Ukrainian'
|
||||
};
|
||||
|
||||
spyOn(Caption, 'fetchAvailableTranslations');
|
||||
@@ -749,10 +741,10 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchAvailableTranslations', function () {
|
||||
describe('fetchAvailableTranslations', function() {
|
||||
var Caption, msg;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
Caption = state.videoCaption;
|
||||
spyOn($, 'ajaxWithPrefix').and.callThrough();
|
||||
@@ -761,7 +753,7 @@
|
||||
spyOn(Caption, 'renderLanguageMenu');
|
||||
});
|
||||
|
||||
it('request created with correct parameters', function () {
|
||||
it('request created with correct parameters', function() {
|
||||
Caption.fetchAvailableTranslations();
|
||||
|
||||
expect($.ajaxWithPrefix).toHaveBeenCalledWith({
|
||||
@@ -773,7 +765,7 @@
|
||||
});
|
||||
|
||||
msg = 'on succes: language menu is rendered if translations available';
|
||||
it(msg, function () {
|
||||
it(msg, function() {
|
||||
state.config.transcriptLanguages = {
|
||||
'en': 'English',
|
||||
'uk': 'Ukrainian',
|
||||
@@ -794,7 +786,7 @@
|
||||
});
|
||||
|
||||
msg = 'on succes: language menu isn\'t rendered if translations unavailable';
|
||||
it(msg, function () {
|
||||
it(msg, function() {
|
||||
state.config.transcriptLanguages = {
|
||||
'en': 'English',
|
||||
'ru': 'Russian'
|
||||
@@ -808,8 +800,8 @@
|
||||
});
|
||||
|
||||
msg = 'on error: transcripts are hidden if there are no transcript';
|
||||
it(msg, function () {
|
||||
$.ajax.and.callFake(function (settings) {
|
||||
it(msg, function() {
|
||||
$.ajax.and.callFake(function(settings) {
|
||||
_.result(settings, 'error');
|
||||
});
|
||||
Caption.fetchAvailableTranslations();
|
||||
@@ -820,73 +812,73 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('play', function () {
|
||||
describe('when the transcript was not rendered', function () {
|
||||
beforeEach(function (done) {
|
||||
describe('play', function() {
|
||||
describe('when the transcript was not rendered', function() {
|
||||
beforeEach(function(done) {
|
||||
window.onTouchBasedDevice.and.returnValue(['iPad']);
|
||||
|
||||
state = jasmine.initializePlayer();
|
||||
state.videoCaption.play();
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoCaption.rendered;
|
||||
}).then(function(){
|
||||
}).then(function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('render the transcript', function () {
|
||||
it('render the transcript', function() {
|
||||
var captionsData;
|
||||
|
||||
captionsData = jasmine.stubbedCaption;
|
||||
|
||||
$('.subtitles li[data-index]').each(
|
||||
function (index, item) {
|
||||
expect(parseIntAttribute($(item), 'data-index')).toEqual(index);
|
||||
expect(parseIntAttribute($(item), 'data-start')).toEqual(captionsData.start[index]);
|
||||
expect($(item).attr('tabindex')).toEqual('0');
|
||||
expect($(item).text().trim()).toEqual(captionsData.text[index]);
|
||||
});
|
||||
function(index, item) {
|
||||
expect(parseIntAttribute($(item), 'data-index')).toEqual(index);
|
||||
expect(parseIntAttribute($(item), 'data-start')).toEqual(captionsData.start[index]);
|
||||
expect($(item).attr('tabindex')).toEqual('0');
|
||||
expect($(item).text().trim()).toEqual(captionsData.text[index]);
|
||||
});
|
||||
});
|
||||
|
||||
it('add a padding element to transcript', function () {
|
||||
it('add a padding element to transcript', function() {
|
||||
expect($('.subtitles li:first')).toHaveClass('spacing');
|
||||
expect($('.subtitles li:last')).toHaveClass('spacing');
|
||||
});
|
||||
|
||||
it('set rendered to true', function () {
|
||||
it('set rendered to true', function() {
|
||||
expect(state.videoCaption.rendered).toBeTruthy();
|
||||
});
|
||||
|
||||
it('set playing to true', function () {
|
||||
it('set playing to true', function() {
|
||||
expect(state.videoCaption.playing).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('pause', function () {
|
||||
beforeEach(function () {
|
||||
describe('pause', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
state.videoCaption.playing = true;
|
||||
state.videoCaption.pause();
|
||||
});
|
||||
|
||||
it('set playing to false', function () {
|
||||
it('set playing to false', function() {
|
||||
expect(state.videoCaption.playing).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('updatePlayTime', function () {
|
||||
beforeEach(function (done) {
|
||||
describe('updatePlayTime', function() {
|
||||
beforeEach(function(done) {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoCaption.rendered;
|
||||
}).then(done);
|
||||
});
|
||||
|
||||
describe('when the video speed is 1.0x', function () {
|
||||
it('search the caption based on time', function () {
|
||||
describe('when the video speed is 1.0x', function() {
|
||||
it('search the caption based on time', function() {
|
||||
state.videoCaption.updatePlayTime(25.000);
|
||||
expect(state.videoCaption.currentIndex).toEqual(5);
|
||||
|
||||
@@ -898,8 +890,8 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the video speed is not 1.0x', function () {
|
||||
it('search the transcript based on 1.0x speed', function () {
|
||||
describe('when the video speed is not 1.0x', function() {
|
||||
it('search the transcript based on 1.0x speed', function() {
|
||||
state.videoCaption.updatePlayTime(25.000);
|
||||
expect(state.videoCaption.currentIndex).toEqual(5);
|
||||
|
||||
@@ -918,34 +910,34 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the index is not the same', function () {
|
||||
beforeEach(function () {
|
||||
describe('when the index is not the same', function() {
|
||||
beforeEach(function() {
|
||||
state.videoCaption.currentIndex = 1;
|
||||
$('.subtitles li[data-index=5]').addClass('current');
|
||||
state.videoCaption.updatePlayTime(25.000);
|
||||
});
|
||||
|
||||
it('deactivate the previous transcript', function () {
|
||||
it('deactivate the previous transcript', function() {
|
||||
expect($('.subtitles li[data-index=1]'))
|
||||
.not.toHaveClass('current');
|
||||
});
|
||||
|
||||
it('activate new transcript', function () {
|
||||
it('activate new transcript', function() {
|
||||
expect($('.subtitles li[data-index=5]'))
|
||||
.toHaveClass('current');
|
||||
});
|
||||
|
||||
it('save new index', function () {
|
||||
it('save new index', function() {
|
||||
expect(state.videoCaption.currentIndex).toEqual(5);
|
||||
});
|
||||
|
||||
it('scroll transcript to new position', function () {
|
||||
it('scroll transcript to new position', function() {
|
||||
expect($.fn.scrollTo).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the index is the same', function () {
|
||||
it('does not change current subtitle', function () {
|
||||
describe('when the index is the same', function() {
|
||||
it('does not change current subtitle', function() {
|
||||
state.videoCaption.currentIndex = 1;
|
||||
$('.subtitles li[data-index=3]').addClass('current');
|
||||
state.videoCaption.updatePlayTime(15.000);
|
||||
@@ -955,21 +947,21 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('resize', function () {
|
||||
beforeEach(function (done) {
|
||||
describe('resize', function() {
|
||||
beforeEach(function(done) {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoCaption.rendered;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
videoControl = state.videoControl;
|
||||
$('.subtitles li[data-index=1]').addClass('current');
|
||||
state.videoCaption.onResize();
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
describe('set the height of transcript container', function () {
|
||||
it('when transcript button is enabled', function () {
|
||||
describe('set the height of transcript container', function() {
|
||||
it('when transcript button is enabled', function() {
|
||||
var realHeight = parseInt(
|
||||
$('.subtitles').css('maxHeight'), 10
|
||||
),
|
||||
@@ -980,7 +972,7 @@
|
||||
expect(realHeight).toBeCloseTo(shouldBeHeight, 2);
|
||||
});
|
||||
|
||||
it('when transcript button is disabled ', function () {
|
||||
it('when transcript button is disabled ', function() {
|
||||
var realHeight, videoWrapperHeight, progressSliderHeight,
|
||||
controlHeight, shouldBeHeight;
|
||||
|
||||
@@ -1001,7 +993,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('set the height of transcript spacing', function () {
|
||||
it('set the height of transcript spacing', function() {
|
||||
var firstSpacing, lastSpacing;
|
||||
|
||||
firstSpacing = Math.abs(parseInt(
|
||||
@@ -1017,25 +1009,25 @@
|
||||
.toBeLessThan(1);
|
||||
});
|
||||
|
||||
it('scroll transcript to new position', function () {
|
||||
it('scroll transcript to new position', function() {
|
||||
expect($.fn.scrollTo).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
xdescribe('scrollCaption', function () {
|
||||
beforeEach(function () {
|
||||
runs(function () {
|
||||
xdescribe('scrollCaption', function() {
|
||||
beforeEach(function() {
|
||||
runs(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
});
|
||||
|
||||
waitsFor(function () {
|
||||
waitsFor(function() {
|
||||
return state.videoCaption.rendered;
|
||||
}, 'Transcripts are not rendered', WAIT_TIMEOUT);
|
||||
});
|
||||
|
||||
describe('when frozen', function () {
|
||||
it('does not scroll the transcript', function () {
|
||||
runs(function () {
|
||||
describe('when frozen', function() {
|
||||
it('does not scroll the transcript', function() {
|
||||
runs(function() {
|
||||
state.videoCaption.frozen = true;
|
||||
$('.subtitles li[data-index=1]').addClass('current');
|
||||
state.videoCaption.scrollCaption();
|
||||
@@ -1044,25 +1036,25 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('when not frozen', function () {
|
||||
beforeEach(function () {
|
||||
runs(function () {
|
||||
describe('when not frozen', function() {
|
||||
beforeEach(function() {
|
||||
runs(function() {
|
||||
state.videoCaption.frozen = false;
|
||||
});
|
||||
});
|
||||
|
||||
describe('when there is no current transcript', function () {
|
||||
it('does not scroll the transcript', function () {
|
||||
runs(function () {
|
||||
describe('when there is no current transcript', function() {
|
||||
it('does not scroll the transcript', function() {
|
||||
runs(function() {
|
||||
state.videoCaption.scrollCaption();
|
||||
expect($.fn.scrollTo).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when there is a current transcript', function () {
|
||||
it('scroll to current transcript', function () {
|
||||
runs(function () {
|
||||
describe('when there is a current transcript', function() {
|
||||
it('scroll to current transcript', function() {
|
||||
runs(function() {
|
||||
$('.subtitles li[data-index=1]').addClass('current');
|
||||
state.videoCaption.scrollCaption();
|
||||
expect($.fn.scrollTo).toHaveBeenCalled();
|
||||
@@ -1072,13 +1064,13 @@
|
||||
});
|
||||
});
|
||||
|
||||
xdescribe('seekPlayer', function () {
|
||||
beforeEach(function () {
|
||||
runs(function () {
|
||||
xdescribe('seekPlayer', function() {
|
||||
beforeEach(function() {
|
||||
runs(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
});
|
||||
|
||||
waitsFor(function () {
|
||||
waitsFor(function() {
|
||||
var duration = state.videoPlayer.duration(),
|
||||
isRendered = state.videoCaption.rendered;
|
||||
|
||||
@@ -1086,9 +1078,9 @@
|
||||
}, 'Transcripts are not rendered', WAIT_TIMEOUT);
|
||||
});
|
||||
|
||||
describe('when the video speed is 1.0x', function () {
|
||||
it('trigger seek event with the correct time', function () {
|
||||
runs(function () {
|
||||
describe('when the video speed is 1.0x', function() {
|
||||
it('trigger seek event with the correct time', function() {
|
||||
runs(function() {
|
||||
state.videoSpeedControl.currentSpeed = '1.0';
|
||||
$('.subtitles li[data-start="14910"]').trigger('click');
|
||||
expect(state.videoPlayer.currentTime).toEqual(14.91);
|
||||
@@ -1096,9 +1088,9 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the video speed is not 1.0x', function () {
|
||||
it('trigger seek event with the correct time', function () {
|
||||
runs(function () {
|
||||
describe('when the video speed is not 1.0x', function() {
|
||||
it('trigger seek event with the correct time', function() {
|
||||
runs(function() {
|
||||
state.videoSpeedControl.currentSpeed = '0.75';
|
||||
$('.subtitles li[data-start="14910"]').trigger('click');
|
||||
expect(state.videoPlayer.currentTime).toEqual(14.91);
|
||||
@@ -1107,52 +1099,52 @@
|
||||
});
|
||||
|
||||
describe('when the player type is Flash at speed 0.75x',
|
||||
function () {
|
||||
it('trigger seek event with the correct time', function () {
|
||||
runs(function () {
|
||||
state.videoSpeedControl.currentSpeed = '0.75';
|
||||
state.currentPlayerMode = 'flash';
|
||||
$('.subtitles li[data-start="14910"]').trigger('click');
|
||||
expect(state.videoPlayer.currentTime).toEqual(15);
|
||||
function() {
|
||||
it('trigger seek event with the correct time', function() {
|
||||
runs(function() {
|
||||
state.videoSpeedControl.currentSpeed = '0.75';
|
||||
state.currentPlayerMode = 'flash';
|
||||
$('.subtitles li[data-start="14910"]').trigger('click');
|
||||
expect(state.videoPlayer.currentTime).toEqual(15);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('toggle', function () {
|
||||
beforeEach(function () {
|
||||
describe('toggle', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
$('.subtitles li[data-index=1]').addClass('current');
|
||||
});
|
||||
|
||||
describe('when the transcript is visible', function () {
|
||||
beforeEach(function () {
|
||||
describe('when the transcript is visible', function() {
|
||||
beforeEach(function() {
|
||||
state.el.removeClass('closed');
|
||||
state.videoCaption.toggle(jQuery.Event('click'));
|
||||
});
|
||||
|
||||
it('hide the transcript', function () {
|
||||
it('hide the transcript', function() {
|
||||
expect(state.el).toHaveClass('closed');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the transcript is hidden', function () {
|
||||
beforeEach(function () {
|
||||
describe('when the transcript is hidden', function() {
|
||||
beforeEach(function() {
|
||||
state.el.addClass('closed');
|
||||
state.videoCaption.toggle(jQuery.Event('click'));
|
||||
jasmine.clock().install();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
|
||||
it('show the transcript', function () {
|
||||
it('show the transcript', function() {
|
||||
expect(state.el).not.toHaveClass('closed');
|
||||
});
|
||||
|
||||
// Test turned off due to flakiness (11/25/13)
|
||||
xit('scroll the transcript', function () {
|
||||
xit('scroll the transcript', function() {
|
||||
// After transcripts are shown, and the video plays for a
|
||||
// bit.
|
||||
jasmine.clock().tick(1000);
|
||||
@@ -1161,53 +1153,53 @@
|
||||
// position. When they advance, the list scrolls. The
|
||||
// current transcript position should be constantly
|
||||
// visible.
|
||||
runs(function () {
|
||||
runs(function() {
|
||||
expect($.fn.scrollTo).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('transcript accessibility', function () {
|
||||
beforeEach(function (done) {
|
||||
describe('transcript accessibility', function() {
|
||||
beforeEach(function(done) {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoCaption.rendered;
|
||||
}).then(done);
|
||||
});
|
||||
|
||||
describe('when getting focus through TAB key', function () {
|
||||
beforeEach(function () {
|
||||
describe('when getting focus through TAB key', function() {
|
||||
beforeEach(function() {
|
||||
state.videoCaption.isMouseFocus = false;
|
||||
$('.subtitles li[data-index=0]').trigger(
|
||||
jQuery.Event('focus')
|
||||
);
|
||||
});
|
||||
|
||||
it('shows an outline around the transcript', function () {
|
||||
it('shows an outline around the transcript', function() {
|
||||
expect($('.subtitles li[data-index=0]'))
|
||||
.toHaveClass('focused');
|
||||
});
|
||||
|
||||
it('has automatic scrolling disabled', function () {
|
||||
it('has automatic scrolling disabled', function() {
|
||||
expect(state.videoCaption.autoScrolling).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when loosing focus through TAB key', function () {
|
||||
beforeEach(function () {
|
||||
describe('when loosing focus through TAB key', function() {
|
||||
beforeEach(function() {
|
||||
$('.subtitles li[data-index=0]').trigger(
|
||||
jQuery.Event('blur')
|
||||
);
|
||||
});
|
||||
|
||||
it('does not show an outline around the transcript', function () {
|
||||
it('does not show an outline around the transcript', function() {
|
||||
expect($('.subtitles li[data-index=0]'))
|
||||
.not.toHaveClass('focused');
|
||||
});
|
||||
|
||||
it('has automatic scrolling enabled', function () {
|
||||
it('has automatic scrolling enabled', function() {
|
||||
expect(state.videoCaption.autoScrolling).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -1215,60 +1207,57 @@
|
||||
describe(
|
||||
'when same transcript gets the focus through mouse after ' +
|
||||
'having focus through TAB key',
|
||||
function () {
|
||||
|
||||
beforeEach(function () {
|
||||
state.videoCaption.isMouseFocus = false;
|
||||
$('.subtitles li[data-index=0]')
|
||||
function() {
|
||||
beforeEach(function() {
|
||||
state.videoCaption.isMouseFocus = false;
|
||||
$('.subtitles li[data-index=0]')
|
||||
.trigger(jQuery.Event('focus'));
|
||||
$('.subtitles li[data-index=0]')
|
||||
$('.subtitles li[data-index=0]')
|
||||
.trigger(jQuery.Event('mousedown'));
|
||||
});
|
||||
});
|
||||
|
||||
it('does not show an outline around it', function () {
|
||||
expect($('.subtitles li[data-index=0]'))
|
||||
it('does not show an outline around it', function() {
|
||||
expect($('.subtitles li[data-index=0]'))
|
||||
.not.toHaveClass('focused');
|
||||
});
|
||||
});
|
||||
|
||||
it('has automatic scrolling enabled', function () {
|
||||
expect(state.videoCaption.autoScrolling).toBe(true);
|
||||
it('has automatic scrolling enabled', function() {
|
||||
expect(state.videoCaption.autoScrolling).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe(
|
||||
'when a second transcript gets focus through mouse after ' +
|
||||
'first had focus through TAB key',
|
||||
function () {
|
||||
function() {
|
||||
var subDataLiIdx__0, subDataLiIdx__1;
|
||||
|
||||
var subDataLiIdx__0, subDataLiIdx__1;
|
||||
beforeEach(function() {
|
||||
subDataLiIdx__0 = $('.subtitles li[data-index=0]');
|
||||
subDataLiIdx__1 = $('.subtitles li[data-index=1]');
|
||||
|
||||
beforeEach(function () {
|
||||
subDataLiIdx__0 = $('.subtitles li[data-index=0]');
|
||||
subDataLiIdx__1 = $('.subtitles li[data-index=1]');
|
||||
state.videoCaption.isMouseFocus = false;
|
||||
|
||||
state.videoCaption.isMouseFocus = false;
|
||||
subDataLiIdx__0.trigger(jQuery.Event('focus'));
|
||||
subDataLiIdx__0.trigger(jQuery.Event('blur'));
|
||||
|
||||
subDataLiIdx__0.trigger(jQuery.Event('focus'));
|
||||
subDataLiIdx__0.trigger(jQuery.Event('blur'));
|
||||
state.videoCaption.isMouseFocus = true;
|
||||
|
||||
state.videoCaption.isMouseFocus = true;
|
||||
subDataLiIdx__1.trigger(jQuery.Event('mousedown'));
|
||||
});
|
||||
|
||||
subDataLiIdx__1.trigger(jQuery.Event('mousedown'));
|
||||
it('does not show an outline around the first', function() {
|
||||
expect(subDataLiIdx__0).not.toHaveClass('focused');
|
||||
});
|
||||
|
||||
it('does not show an outline around the second', function() {
|
||||
expect(subDataLiIdx__1).not.toHaveClass('focused');
|
||||
});
|
||||
|
||||
it('has automatic scrolling enabled', function() {
|
||||
expect(state.videoCaption.autoScrolling).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('does not show an outline around the first', function () {
|
||||
expect(subDataLiIdx__0).not.toHaveClass('focused');
|
||||
});
|
||||
|
||||
it('does not show an outline around the second', function () {
|
||||
expect(subDataLiIdx__1).not.toHaveClass('focused');
|
||||
});
|
||||
|
||||
it('has automatic scrolling enabled', function () {
|
||||
expect(state.videoCaption.autoScrolling).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}).call(this);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
(function () {
|
||||
(function() {
|
||||
'use strict';
|
||||
describe('Video Context Menu', function () {
|
||||
describe('Video Context Menu', function() {
|
||||
var state, openMenu, keyPressEvent, openSubmenuMouse, openSubmenuKeyboard, closeSubmenuMouse,
|
||||
closeSubmenuKeyboard, menu, menuItems, menuSubmenuItem, submenu, submenuItems, overlay, playButton;
|
||||
|
||||
openMenu = function () {
|
||||
openMenu = function() {
|
||||
var container = $('.video');
|
||||
container.find('video').trigger('contextmenu');
|
||||
menu = container.children('.contextmenu');
|
||||
@@ -20,42 +20,42 @@
|
||||
return $.Event('keydown', {keyCode: key});
|
||||
};
|
||||
|
||||
openSubmenuMouse = function (menuSubmenuItem) {
|
||||
openSubmenuMouse = function(menuSubmenuItem) {
|
||||
menuSubmenuItem.mouseover();
|
||||
jasmine.clock().tick(200);
|
||||
expect(menuSubmenuItem).toHaveClass('is-opened');
|
||||
};
|
||||
|
||||
openSubmenuKeyboard = function (menuSubmenuItem, keyCode) {
|
||||
openSubmenuKeyboard = function(menuSubmenuItem, keyCode) {
|
||||
menuSubmenuItem.focus().trigger(keyPressEvent(keyCode || $.ui.keyCode.RIGHT));
|
||||
expect(menuSubmenuItem).toHaveClass('is-opened');
|
||||
expect(menuSubmenuItem.children().last().children().first()).toBeFocused();
|
||||
};
|
||||
|
||||
closeSubmenuMouse = function (menuSubmenuItem) {
|
||||
closeSubmenuMouse = function(menuSubmenuItem) {
|
||||
menuSubmenuItem.mouseleave();
|
||||
jasmine.clock().tick(200);
|
||||
expect(menuSubmenuItem).not.toHaveClass('is-opened');
|
||||
};
|
||||
|
||||
closeSubmenuKeyboard = function (menuSubmenuItem) {
|
||||
closeSubmenuKeyboard = function(menuSubmenuItem) {
|
||||
menuSubmenuItem.children().first().focus().trigger(keyPressEvent($.ui.keyCode.LEFT));
|
||||
expect(menuSubmenuItem).not.toHaveClass('is-opened');
|
||||
expect(menuSubmenuItem).toBeFocused();
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
jasmine.clock().install();
|
||||
// $.cookie is mocked, make sure we have a state with an unmuted volume.
|
||||
$.cookie.and.returnValue('100');
|
||||
jasmine.addMatchers({
|
||||
toHaveCorrectLabels: function () {
|
||||
toHaveCorrectLabels: function() {
|
||||
return {
|
||||
compare: function (actual, labelsList) {
|
||||
compare: function(actual, labelsList) {
|
||||
return {
|
||||
pass: _.difference(labelsList, _.map(actual, function (item) {
|
||||
return $(item).text();
|
||||
})).length === 0
|
||||
pass: _.difference(labelsList, _.map(actual, function(item) {
|
||||
return $(item).text();
|
||||
})).length === 0
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -63,7 +63,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
_.result(state.storage, 'clear');
|
||||
_.result($('video').data('contextmenu'), 'destroy');
|
||||
@@ -71,8 +71,8 @@
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
|
||||
describe('constructor', function () {
|
||||
it('the structure should be created on first `contextmenu` call', function () {
|
||||
describe('constructor', function() {
|
||||
it('the structure should be created on first `contextmenu` call', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
expect(menu).not.toExist();
|
||||
openMenu();
|
||||
@@ -98,12 +98,12 @@
|
||||
expect(_.size(submenuItems.filter('.is-selected'))).toBe(1);
|
||||
});
|
||||
|
||||
it('add ARIA attributes to menu, menu items, submenu and submenu items', function () {
|
||||
it('add ARIA attributes to menu, menu items, submenu and submenu items', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
openMenu();
|
||||
// Menu and its items.
|
||||
expect(menu).toHaveAttr('role', 'menu');
|
||||
menuItems.each(function () {
|
||||
menuItems.each(function() {
|
||||
expect($(this)).toHaveAttrs({
|
||||
'aria-selected': 'false',
|
||||
'role': 'menuitem'
|
||||
@@ -118,69 +118,69 @@
|
||||
|
||||
// Submenu and its items.
|
||||
expect(submenu).toHaveAttr('role', 'menu');
|
||||
submenuItems.each(function () {
|
||||
submenuItems.each(function() {
|
||||
expect($(this)).toHaveAttr('role', 'menuitem');
|
||||
expect($(this)).toHaveAttr('aria-selected');
|
||||
});
|
||||
});
|
||||
|
||||
it('is not used by Youtube type of video player', function () {
|
||||
it('is not used by Youtube type of video player', function() {
|
||||
state = jasmine.initializePlayer('video.html');
|
||||
expect($('video, iframe')).not.toHaveData('contextmenu');
|
||||
});
|
||||
});
|
||||
|
||||
describe('methods:', function () {
|
||||
beforeEach(function () {
|
||||
describe('methods:', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
openMenu();
|
||||
});
|
||||
|
||||
it('menu can be destroyed successfully', function () {
|
||||
it('menu can be destroyed successfully', function() {
|
||||
var menuitemEvents = ['click', 'keydown', 'contextmenu', 'mouseover'],
|
||||
menuEvents = ['keydown', 'contextmenu', 'mouseleave', 'mouseover'];
|
||||
|
||||
menu.data('menu').destroy();
|
||||
expect(menu).not.toBeInDOM();
|
||||
expect(overlay).not.toBeInDOM();
|
||||
_.each(menuitemEvents, function (eventName) {
|
||||
_.each(menuitemEvents, function(eventName) {
|
||||
expect(menuItems.first()).not.toHandle(eventName);
|
||||
})
|
||||
_.each(menuEvents, function (eventName) {
|
||||
});
|
||||
_.each(menuEvents, function(eventName) {
|
||||
expect(menuSubmenuItem).not.toHandle(eventName);
|
||||
})
|
||||
_.each(menuEvents, function (eventName) {
|
||||
});
|
||||
_.each(menuEvents, function(eventName) {
|
||||
expect(menu).not.toHandle(eventName);
|
||||
})
|
||||
});
|
||||
expect($('video')).not.toHandle('contextmenu');
|
||||
expect($('video')).not.toHaveData('contextmenu');
|
||||
});
|
||||
|
||||
it('can change label for the submenu', function () {
|
||||
it('can change label for the submenu', function() {
|
||||
expect(menuSubmenuItem.children('span')).toHaveText('Speed');
|
||||
menuSubmenuItem.data('menu').setLabel('New Name');
|
||||
expect(menuSubmenuItem.children('span')).toHaveText('New Name');
|
||||
});
|
||||
|
||||
it('can change label for the menuitem', function () {
|
||||
it('can change label for the menuitem', function() {
|
||||
expect(menuItems.first()).toHaveText('Play');
|
||||
menuItems.first().data('menu').setLabel('Pause');
|
||||
expect(menuItems.first()).toHaveText('Pause');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when video is right-clicked', function () {
|
||||
beforeEach(function () {
|
||||
describe('when video is right-clicked', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
openMenu();
|
||||
});
|
||||
|
||||
it('context menu opens', function () {
|
||||
it('context menu opens', function() {
|
||||
expect(menu).toHaveClass('is-opened');
|
||||
expect(overlay).toBeInDOM();
|
||||
});
|
||||
|
||||
it('mouseover and mouseleave behave as expected', function () {
|
||||
it('mouseover and mouseleave behave as expected', function() {
|
||||
openSubmenuMouse(menuSubmenuItem);
|
||||
expect(menuSubmenuItem).toHaveClass('is-opened');
|
||||
closeSubmenuMouse(menuSubmenuItem);
|
||||
@@ -189,28 +189,28 @@
|
||||
expect(submenuItems.eq(1)).toBeFocused();
|
||||
});
|
||||
|
||||
it('mouse left-clicking outside of the context menu will close it', function () {
|
||||
it('mouse left-clicking outside of the context menu will close it', function() {
|
||||
// Left-click outside of open menu, for example on Play button
|
||||
playButton.click();
|
||||
expect(menu).not.toHaveClass('is-opened');
|
||||
expect(overlay).not.toBeInDOM();
|
||||
});
|
||||
|
||||
it('mouse right-clicking outside of video will close it', function () {
|
||||
it('mouse right-clicking outside of video will close it', function() {
|
||||
// Right-click outside of open menu for example on Play button
|
||||
playButton.trigger('contextmenu');
|
||||
expect(menu).not.toHaveClass('is-opened');
|
||||
expect(overlay).not.toBeInDOM();
|
||||
});
|
||||
|
||||
it('mouse right-clicking inside video but outside of context menu will not close it', function () {
|
||||
it('mouse right-clicking inside video but outside of context menu will not close it', function() {
|
||||
spyOn(menu.data('menu'), 'pointInContainerBox').and.returnValue(true);
|
||||
overlay.trigger('contextmenu');
|
||||
expect(menu).toHaveClass('is-opened');
|
||||
expect(overlay).toBeInDOM();
|
||||
});
|
||||
|
||||
it('mouse right-clicking inside video but outside of context menu will close submenus', function () {
|
||||
it('mouse right-clicking inside video but outside of context menu will close submenus', function() {
|
||||
spyOn(menu.data('menu'), 'pointInContainerBox').and.returnValue(true);
|
||||
openSubmenuMouse(menuSubmenuItem);
|
||||
expect(menuSubmenuItem).toHaveClass('is-opened');
|
||||
@@ -218,14 +218,14 @@
|
||||
expect(menuSubmenuItem).not.toHaveClass('is-opened');
|
||||
});
|
||||
|
||||
it('mouse left/right-clicking behaves as expected on play/pause menu item', function () {
|
||||
it('mouse left/right-clicking behaves as expected on play/pause menu item', function() {
|
||||
var menuItem = menuItems.first();
|
||||
spyOn(state.videoPlayer, 'isPlaying');
|
||||
spyOn(state.videoPlayer, 'play').and.callFake(function () {
|
||||
spyOn(state.videoPlayer, 'play').and.callFake(function() {
|
||||
state.videoPlayer.isPlaying.and.returnValue(true);
|
||||
state.el.trigger('play');
|
||||
});
|
||||
spyOn(state.videoPlayer, 'pause').and.callFake(function () {
|
||||
spyOn(state.videoPlayer, 'pause').and.callFake(function() {
|
||||
state.videoPlayer.isPlaying.and.returnValue(false);
|
||||
state.el.trigger('pause');
|
||||
});
|
||||
@@ -245,7 +245,7 @@
|
||||
expect(menuItem).toHaveText('Pause');
|
||||
});
|
||||
|
||||
it('mouse left/right-clicking behaves as expected on mute/unmute menu item', function () {
|
||||
it('mouse left/right-clicking behaves as expected on mute/unmute menu item', function() {
|
||||
var menuItem = menuItems.eq(1);
|
||||
// Left-click on mute
|
||||
menuItem.click();
|
||||
@@ -267,7 +267,7 @@
|
||||
expect(menuItem).toHaveText('Mute');
|
||||
});
|
||||
|
||||
it('mouse left/right-clicking behaves as expected on go to Exit full browser menu item', function () {
|
||||
it('mouse left/right-clicking behaves as expected on go to Exit full browser menu item', function() {
|
||||
var menuItem = menuItems.eq(2);
|
||||
// Left-click on Fill browser
|
||||
menuItem.click();
|
||||
@@ -289,7 +289,7 @@
|
||||
expect(menuItem).toHaveText('Fill browser');
|
||||
});
|
||||
|
||||
it('mouse left/right-clicking behaves as expected on speed submenu item', function () {
|
||||
it('mouse left/right-clicking behaves as expected on speed submenu item', function() {
|
||||
// Set speed to 0.75x
|
||||
state.videoSpeedControl.setSpeed('0.75');
|
||||
// Left-click on second submenu speed (1.0x)
|
||||
@@ -318,70 +318,70 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('Keyboard interactions', function () {
|
||||
beforeEach(function () {
|
||||
describe('Keyboard interactions', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
openMenu();
|
||||
});
|
||||
|
||||
it('focus the first item of the just opened menu on UP keydown', function () {
|
||||
it('focus the first item of the just opened menu on UP keydown', function() {
|
||||
menu.trigger(keyPressEvent($.ui.keyCode.UP));
|
||||
expect(menuSubmenuItem).toBeFocused();
|
||||
});
|
||||
|
||||
it('focus the last item of the just opened menu on DOWN keydown', function () {
|
||||
it('focus the last item of the just opened menu on DOWN keydown', function() {
|
||||
menu.trigger(keyPressEvent($.ui.keyCode.DOWN));
|
||||
expect(menuItems.first()).toBeFocused();
|
||||
});
|
||||
|
||||
it('open the submenu on ENTER keydown', function () {
|
||||
it('open the submenu on ENTER keydown', function() {
|
||||
openSubmenuKeyboard(menuSubmenuItem, $.ui.keyCode.ENTER);
|
||||
expect(menuSubmenuItem).toHaveClass('is-opened');
|
||||
expect(submenuItems.first()).toBeFocused();
|
||||
});
|
||||
|
||||
it('open the submenu on SPACE keydown', function () {
|
||||
it('open the submenu on SPACE keydown', function() {
|
||||
openSubmenuKeyboard(menuSubmenuItem, $.ui.keyCode.SPACE);
|
||||
expect(menuSubmenuItem).toHaveClass('is-opened');
|
||||
expect(submenuItems.first()).toBeFocused();
|
||||
});
|
||||
|
||||
it('open the submenu on RIGHT keydown', function () {
|
||||
it('open the submenu on RIGHT keydown', function() {
|
||||
openSubmenuKeyboard(menuSubmenuItem, $.ui.keyCode.RIGHT);
|
||||
expect(menuSubmenuItem).toHaveClass('is-opened');
|
||||
expect(submenuItems.first()).toBeFocused();
|
||||
});
|
||||
|
||||
it('close the menu on ESCAPE keydown', function () {
|
||||
it('close the menu on ESCAPE keydown', function() {
|
||||
menu.trigger(keyPressEvent($.ui.keyCode.ESCAPE));
|
||||
expect(menu).not.toHaveClass('is-opened');
|
||||
expect(overlay).not.toBeInDOM();
|
||||
});
|
||||
|
||||
it('close the submenu on ESCAPE keydown', function () {
|
||||
it('close the submenu on ESCAPE keydown', function() {
|
||||
openSubmenuKeyboard(menuSubmenuItem);
|
||||
menuSubmenuItem.trigger(keyPressEvent($.ui.keyCode.ESCAPE));
|
||||
expect(menuSubmenuItem).not.toHaveClass('is-opened');
|
||||
expect(overlay).not.toBeInDOM();
|
||||
});
|
||||
|
||||
it('close the submenu on LEFT keydown on submenu items', function () {
|
||||
it('close the submenu on LEFT keydown on submenu items', function() {
|
||||
closeSubmenuKeyboard(menuSubmenuItem);
|
||||
});
|
||||
|
||||
it('do nothing on RIGHT keydown on submenu item', function () {
|
||||
it('do nothing on RIGHT keydown on submenu item', function() {
|
||||
submenuItems.eq(1).focus().trigger(keyPressEvent($.ui.keyCode.RIGHT)); // Mute
|
||||
// Is still focused.
|
||||
expect(submenuItems.eq(1)).toBeFocused();
|
||||
});
|
||||
|
||||
it('do nothing on TAB keydown on menu item', function () {
|
||||
it('do nothing on TAB keydown on menu item', function() {
|
||||
submenuItems.eq(1).focus().trigger(keyPressEvent($.ui.keyCode.TAB)); // Mute
|
||||
// Is still focused.
|
||||
expect(submenuItems.eq(1)).toBeFocused();
|
||||
});
|
||||
|
||||
it('UP and DOWN keydown function as expected on menu/submenu items', function () {
|
||||
it('UP and DOWN keydown function as expected on menu/submenu items', function() {
|
||||
menuItems.eq(0).focus(); // Play
|
||||
expect(menuItems.eq(0)).toBeFocused();
|
||||
menuItems.eq(0).trigger(keyPressEvent($.ui.keyCode.DOWN));
|
||||
@@ -403,7 +403,7 @@
|
||||
expect(menuItems.eq(0)).toBeFocused(); // Play
|
||||
});
|
||||
|
||||
it('current item is still focused if all siblings are hidden', function () {
|
||||
it('current item is still focused if all siblings are hidden', function() {
|
||||
menuItems.eq(0).focus(); // Play
|
||||
expect(menuItems.eq(0)).toBeFocused(); // hide all siblings
|
||||
menuItems.eq(0).siblings().hide();
|
||||
@@ -413,7 +413,7 @@
|
||||
expect(menuItems.eq(0)).toBeFocused();
|
||||
});
|
||||
|
||||
it('ENTER keydown on menu/submenu item selects its data and closes menu', function () {
|
||||
it('ENTER keydown on menu/submenu item selects its data and closes menu', function() {
|
||||
menuItems.eq(2).focus().trigger(keyPressEvent($.ui.keyCode.ENTER)); // Fullscreen
|
||||
expect(menuItems.eq(2)).toHaveClass('is-selected');
|
||||
expect(menuItems.eq(2).siblings()).not.toHaveClass('is-selected');
|
||||
@@ -421,7 +421,7 @@
|
||||
expect(menuItems.eq(2)).toHaveText('Exit full browser');
|
||||
});
|
||||
|
||||
it('SPACE keydown on menu/submenu item selects its data and closes menu', function () {
|
||||
it('SPACE keydown on menu/submenu item selects its data and closes menu', function() {
|
||||
submenuItems.eq(2).focus().trigger(keyPressEvent($.ui.keyCode.SPACE)); // 1.25x
|
||||
expect(submenuItems.eq(2)).toHaveClass('is-selected');
|
||||
expect(submenuItems.eq(2).siblings()).not.toHaveClass('is-selected');
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
(function (WAIT_TIMEOUT) {
|
||||
(function(WAIT_TIMEOUT) {
|
||||
'use strict';
|
||||
|
||||
describe('VideoControl', function () {
|
||||
describe('VideoControl', function() {
|
||||
var state, oldOTBD;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine
|
||||
.createSpy('onTouchBasedDevice').and.returnValue(null);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
});
|
||||
|
||||
describe('constructor', function () {
|
||||
beforeEach(function () {
|
||||
describe('constructor', function() {
|
||||
beforeEach(function() {
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer();
|
||||
});
|
||||
|
||||
it('render the video controls', function () {
|
||||
it('render the video controls', function() {
|
||||
expect($('.video-controls')).toContainElement(
|
||||
[
|
||||
'.slider',
|
||||
@@ -38,479 +38,479 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('constructor with start-time', function () {
|
||||
describe('constructor with start-time', function() {
|
||||
it(
|
||||
'saved position is 0, timer slider and VCR set to start-time',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
savedVideoPosition: 0
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
savedVideoPosition: 0
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
return isFinite(duration) && duration > 0 && isFinite(state.videoPlayer.startTime);
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 1:00');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
}).always(done);
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
return isFinite(duration) && duration > 0 && isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 1:00');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it(
|
||||
'saved position is after start-time, ' +
|
||||
'timer slider and VCR set to saved position',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
savedVideoPosition: 15
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
savedVideoPosition: 15
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:15 / 1:00');
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:15 / 1:00');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(15);
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(15);
|
||||
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it(
|
||||
'saved position is negative, ' +
|
||||
'timer slider and VCR set to start-time',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
savedVideoPosition: -15
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
savedVideoPosition: -15
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 1:00');
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 1:00');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it(
|
||||
'saved position is not a number, ' +
|
||||
'timer slider and VCR set to start-time',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
savedVideoPosition: 'a'
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
savedVideoPosition: 'a'
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 1:00');
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 1:00');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it(
|
||||
'saved position is greater than end-time, ' +
|
||||
'timer slider and VCR set to start-time',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
savedVideoPosition: 10000
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
savedVideoPosition: 10000
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 1:00');
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 1:00');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('constructor with end-time', function () {
|
||||
describe('constructor with end-time', function() {
|
||||
it(
|
||||
'saved position is 0, timer slider and VCR set to 0:00 ' +
|
||||
'and ending at specified end-time',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
end: 20,
|
||||
savedVideoPosition: 0
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
end: 20,
|
||||
savedVideoPosition: 0
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:00 / 0:20');
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:00 / 0:20');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(0);
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(0);
|
||||
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it(
|
||||
'saved position is after start-time, ' +
|
||||
'timer slider and VCR set to saved position',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
end: 20,
|
||||
savedVideoPosition: 15
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
end: 20,
|
||||
savedVideoPosition: 15
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:15 / 0:20');
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:15 / 0:20');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(15);
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(15);
|
||||
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
// TODO: Fix!
|
||||
it(
|
||||
'saved position is negative, timer slider and VCR set to 0:00',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
end: 20,
|
||||
savedVideoPosition: -15
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
end: 20,
|
||||
savedVideoPosition: -15
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:00 / 0:20');
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:00 / 0:20');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(0);
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(0);
|
||||
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it(
|
||||
'saved position is not a number, ' +
|
||||
'timer slider and VCR set to 0:00',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
end: 20,
|
||||
savedVideoPosition: 'a'
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
end: 20,
|
||||
savedVideoPosition: 'a'
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:00 / 0:20');
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:00 / 0:20');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(0);
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(0);
|
||||
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
// TODO: Fix!
|
||||
it(
|
||||
'saved position is greater than end-time, ' +
|
||||
'timer slider and VCR set to 0:00',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
end: 20,
|
||||
savedVideoPosition: 10000
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
end: 20,
|
||||
savedVideoPosition: 10000
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:00 / 0:20');
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:00 / 0:20');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(0);
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(0);
|
||||
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('constructor with start-time and end-time', function () {
|
||||
describe('constructor with start-time and end-time', function() {
|
||||
it(
|
||||
'saved position is 0, timer slider and VCR set to appropriate start and end times',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
end: 20,
|
||||
savedVideoPosition: 0
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
end: 20,
|
||||
savedVideoPosition: 0
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 0:20');
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 0:20');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it(
|
||||
'saved position is after start-time, ' +
|
||||
'timer slider and VCR set to saved position',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
end: 20,
|
||||
savedVideoPosition: 15
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
end: 20,
|
||||
savedVideoPosition: 15
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:15 / 0:20');
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:15 / 0:20');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(15);
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(15);
|
||||
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it(
|
||||
'saved position is negative, ' +
|
||||
'timer slider and VCR set to start-time',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
end: 20,
|
||||
savedVideoPosition: -15
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
end: 20,
|
||||
savedVideoPosition: -15
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 0:20');
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 0:20');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it(
|
||||
'saved position is not a number, ' +
|
||||
'timer slider and VCR set to start-time',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
end: 20,
|
||||
savedVideoPosition: 'a'
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
end: 20,
|
||||
savedVideoPosition: 'a'
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 0:20');
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 0:20');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it(
|
||||
'saved position is greater than end-time, ' +
|
||||
'timer slider and VCR set to start-time',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration, sliderEl, expectedValue;
|
||||
var duration, sliderEl, expectedValue;
|
||||
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
end: 20,
|
||||
savedVideoPosition: 10000
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
window.VideoState = {};
|
||||
state = jasmine.initializePlayer({
|
||||
start: 10,
|
||||
end: 20,
|
||||
savedVideoPosition: 10000
|
||||
});
|
||||
sliderEl = state.videoProgressSlider.slider;
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(60);
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
return isFinite(duration) && duration > 0 &&
|
||||
isFinite(state.videoPlayer.startTime);
|
||||
}).then(function () {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 0:20');
|
||||
}).then(function() {
|
||||
expectedValue = $('.video-controls').find('.vidtime');
|
||||
expect(expectedValue).toHaveText('0:10 / 0:20');
|
||||
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
expectedValue = sliderEl.slider('option', 'value');
|
||||
expect(expectedValue).toBe(10);
|
||||
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
state.storage.clear();
|
||||
}).always(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('show', function () {
|
||||
it('show', function() {
|
||||
var controls;
|
||||
state = jasmine.initializePlayer();
|
||||
controls = state.el.find('.video-controls');
|
||||
@@ -520,19 +520,19 @@
|
||||
expect(controls).not.toHaveClass('is-hidden');
|
||||
});
|
||||
|
||||
it('can destroy itself', function () {
|
||||
it('can destroy itself', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
state.videoControl.destroy();
|
||||
expect(state.videoControl).toBeUndefined();
|
||||
});
|
||||
|
||||
it('can focus the first control', function (done) {
|
||||
it('can focus the first control', function(done) {
|
||||
var btnPlay;
|
||||
state = jasmine.initializePlayer({focusFirstControl: true});
|
||||
btnPlay = state.el.find('.video-controls .play');
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.el.hasClass('is-initialized');
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(btnPlay).toBeFocused();
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
(function (undefined) {
|
||||
(function(undefined) {
|
||||
'use strict';
|
||||
describe('VideoPlayer Events Bumper plugin', function () {
|
||||
describe('VideoPlayer Events Bumper plugin', function() {
|
||||
var Logger = window.Logger;
|
||||
var state, oldOTBD;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine
|
||||
.createSpy('onTouchBasedDevice')
|
||||
@@ -17,7 +17,7 @@
|
||||
spyOn(state.bumperState.videoEventsBumperPlugin, 'getDuration').and.returnValue(20);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
state.storage.clear();
|
||||
@@ -29,7 +29,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
it('can emit "edx.video.bumper.loaded" event', function () {
|
||||
it('can emit "edx.video.bumper.loaded" event', function() {
|
||||
state.el.trigger('ready');
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.loaded', {
|
||||
host_component_id: 'id',
|
||||
@@ -39,7 +39,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "edx.video.bumper.played" event', function () {
|
||||
it('can emit "edx.video.bumper.played" event', function() {
|
||||
state.el.trigger('play');
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.played', {
|
||||
host_component_id: 'id',
|
||||
@@ -50,7 +50,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "edx.video.bumper.stopped" event', function () {
|
||||
it('can emit "edx.video.bumper.stopped" event', function() {
|
||||
state.el.trigger('ended');
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.stopped', {
|
||||
host_component_id: 'id',
|
||||
@@ -71,7 +71,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "edx.video.bumper.skipped" event', function () {
|
||||
it('can emit "edx.video.bumper.skipped" event', function() {
|
||||
state.el.trigger('skip', [false]);
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.skipped', {
|
||||
host_component_id: 'id',
|
||||
@@ -82,7 +82,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "edx.video.bumper.dismissed" event', function () {
|
||||
it('can emit "edx.video.bumper.dismissed" event', function() {
|
||||
state.el.trigger('skip', [true]);
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.dismissed', {
|
||||
host_component_id: 'id',
|
||||
@@ -93,7 +93,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "edx.video.bumper.transcript.menu.shown" event', function () {
|
||||
it('can emit "edx.video.bumper.transcript.menu.shown" event', function() {
|
||||
state.el.trigger('language_menu:show');
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.transcript.menu.shown', {
|
||||
host_component_id: 'id',
|
||||
@@ -103,7 +103,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "edx.video.bumper.transcript.menu.hidden" event', function () {
|
||||
it('can emit "edx.video.bumper.transcript.menu.hidden" event', function() {
|
||||
state.el.trigger('language_menu:hide');
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.transcript.menu.hidden', {
|
||||
host_component_id: 'id',
|
||||
@@ -113,7 +113,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "edx.video.bumper.transcript.shown" event', function () {
|
||||
it('can emit "edx.video.bumper.transcript.shown" event', function() {
|
||||
state.el.trigger('captions:show');
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.transcript.shown', {
|
||||
host_component_id: 'id',
|
||||
@@ -124,7 +124,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "edx.video.bumper.transcript.hidden" event', function () {
|
||||
it('can emit "edx.video.bumper.transcript.hidden" event', function() {
|
||||
state.el.trigger('captions:hide');
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.video.bumper.transcript.hidden', {
|
||||
host_component_id: 'id',
|
||||
@@ -135,7 +135,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can destroy itself', function () {
|
||||
it('can destroy itself', function() {
|
||||
var plugin = state.bumperState.videoEventsBumperPlugin;
|
||||
spyOn($.fn, 'off').and.callThrough();
|
||||
plugin.destroy();
|
||||
@@ -153,5 +153,4 @@
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}).call(this);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(function (undefined) {
|
||||
(function(undefined) {
|
||||
'use strict';
|
||||
describe('VideoPlayer Events plugin', function () {
|
||||
describe('VideoPlayer Events plugin', function() {
|
||||
var state, oldOTBD, Logger = window.Logger;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine
|
||||
.createSpy('onTouchBasedDevice')
|
||||
@@ -14,7 +14,7 @@
|
||||
spyOn(state.videoEventsPlugin, 'getCurrentTime').and.returnValue(10);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
state.storage.clear();
|
||||
@@ -23,7 +23,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
it('can emit "load_video" event', function () {
|
||||
it('can emit "load_video" event', function() {
|
||||
state.el.trigger('ready');
|
||||
expect(Logger.log).toHaveBeenCalledWith('load_video', {
|
||||
id: 'id',
|
||||
@@ -31,7 +31,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "play_video" event when emitPlayVideoEvent is true', function () {
|
||||
it('can emit "play_video" event when emitPlayVideoEvent is true', function() {
|
||||
state.videoEventsPlugin.emitPlayVideoEvent = true;
|
||||
state.el.trigger('play');
|
||||
expect(Logger.log).toHaveBeenCalledWith('play_video', {
|
||||
@@ -42,13 +42,13 @@
|
||||
expect(state.videoEventsPlugin.emitPlayVideoEvent).toBeFalsy();
|
||||
});
|
||||
|
||||
it('can not emit "play_video" event when emitPlayVideoEvent is false', function () {
|
||||
it('can not emit "play_video" event when emitPlayVideoEvent is false', function() {
|
||||
state.videoEventsPlugin.emitPlayVideoEvent = false;
|
||||
state.el.trigger('play');
|
||||
expect(Logger.log).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('can emit "pause_video" event', function () {
|
||||
it('can emit "pause_video" event', function() {
|
||||
state.el.trigger('pause');
|
||||
expect(Logger.log).toHaveBeenCalledWith('pause_video', {
|
||||
id: 'id',
|
||||
@@ -58,7 +58,7 @@
|
||||
expect(state.videoEventsPlugin.emitPlayVideoEvent).toBeTruthy();
|
||||
});
|
||||
|
||||
it('can emit "speed_change_video" event', function () {
|
||||
it('can emit "speed_change_video" event', function() {
|
||||
state.el.trigger('speedchange', ['2.0', '1.0']);
|
||||
expect(Logger.log).toHaveBeenCalledWith('speed_change_video', {
|
||||
id: 'id',
|
||||
@@ -69,7 +69,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "seek_video" event', function () {
|
||||
it('can emit "seek_video" event', function() {
|
||||
state.el.trigger('seek', [1, 0, 'any']);
|
||||
expect(Logger.log).toHaveBeenCalledWith('seek_video', {
|
||||
id: 'id',
|
||||
@@ -80,7 +80,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "stop_video" event', function () {
|
||||
it('can emit "stop_video" event', function() {
|
||||
state.el.trigger('ended');
|
||||
expect(Logger.log).toHaveBeenCalledWith('stop_video', {
|
||||
id: 'id',
|
||||
@@ -99,7 +99,7 @@
|
||||
expect(state.videoEventsPlugin.emitPlayVideoEvent).toBeTruthy();
|
||||
});
|
||||
|
||||
it('can emit "skip_video" event', function () {
|
||||
it('can emit "skip_video" event', function() {
|
||||
state.el.trigger('skip', [false]);
|
||||
expect(Logger.log).toHaveBeenCalledWith('skip_video', {
|
||||
id: 'id',
|
||||
@@ -108,7 +108,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "do_not_show_again_video" event', function () {
|
||||
it('can emit "do_not_show_again_video" event', function() {
|
||||
state.el.trigger('skip', [true]);
|
||||
expect(Logger.log).toHaveBeenCalledWith('do_not_show_again_video', {
|
||||
id: 'id',
|
||||
@@ -117,7 +117,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "edx.video.language_menu.shown" event', function () {
|
||||
it('can emit "edx.video.language_menu.shown" event', function() {
|
||||
state.el.trigger('language_menu:show');
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.video.language_menu.shown', {
|
||||
id: 'id',
|
||||
@@ -125,7 +125,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "edx.video.language_menu.hidden" event', function () {
|
||||
it('can emit "edx.video.language_menu.hidden" event', function() {
|
||||
state.el.trigger('language_menu:hide');
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.video.language_menu.hidden', {
|
||||
id: 'id',
|
||||
@@ -134,7 +134,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "show_transcript" event', function () {
|
||||
it('can emit "show_transcript" event', function() {
|
||||
state.el.trigger('transcript:show');
|
||||
expect(Logger.log).toHaveBeenCalledWith('show_transcript', {
|
||||
id: 'id',
|
||||
@@ -143,7 +143,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "hide_transcript" event', function () {
|
||||
it('can emit "hide_transcript" event', function() {
|
||||
state.el.trigger('transcript:hide');
|
||||
expect(Logger.log).toHaveBeenCalledWith('hide_transcript', {
|
||||
id: 'id',
|
||||
@@ -152,7 +152,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "edx.video.closed_captions.shown" event', function () {
|
||||
it('can emit "edx.video.closed_captions.shown" event', function() {
|
||||
state.el.trigger('captions:show');
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.video.closed_captions.shown', {
|
||||
id: 'id',
|
||||
@@ -161,7 +161,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can emit "edx.video.closed_captions.hidden" event', function () {
|
||||
it('can emit "edx.video.closed_captions.hidden" event', function() {
|
||||
state.el.trigger('captions:hide');
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.video.closed_captions.hidden', {
|
||||
id: 'id',
|
||||
@@ -170,7 +170,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can destroy itself', function () {
|
||||
it('can destroy itself', function() {
|
||||
var plugin = state.videoEventsPlugin;
|
||||
spyOn($.fn, 'off').and.callThrough();
|
||||
state.videoEventsPlugin.destroy();
|
||||
@@ -193,5 +193,4 @@
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}).call(this);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(function (undefined) {
|
||||
describe('Video FocusGrabber', function () {
|
||||
(function(undefined) {
|
||||
describe('Video FocusGrabber', function() {
|
||||
var state;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
// https://github.com/pivotal/jasmine/issues/184
|
||||
//
|
||||
// This is a known issue. jQuery animations depend on setTimeout
|
||||
@@ -24,7 +24,7 @@
|
||||
spyOn(state.focusGrabber, 'enableFocusGrabber').and.callThrough();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
// Turn jQuery animations back on.
|
||||
jQuery.fx.off = true;
|
||||
state.storage.clear();
|
||||
@@ -33,22 +33,21 @@
|
||||
|
||||
it(
|
||||
'check existence of focus grabber elements and their position',
|
||||
function () {
|
||||
|
||||
var firstFGEl = state.el.find('.focus_grabber.first'),
|
||||
lastFGEl = state.el.find('.focus_grabber.last'),
|
||||
tcWrapperEl = state.el.find('.tc-wrapper');
|
||||
function() {
|
||||
var firstFGEl = state.el.find('.focus_grabber.first'),
|
||||
lastFGEl = state.el.find('.focus_grabber.last'),
|
||||
tcWrapperEl = state.el.find('.tc-wrapper');
|
||||
|
||||
// Existence check.
|
||||
expect(firstFGEl.length).toBe(1);
|
||||
expect(lastFGEl.length).toBe(1);
|
||||
expect(firstFGEl.length).toBe(1);
|
||||
expect(lastFGEl.length).toBe(1);
|
||||
|
||||
// Position check.
|
||||
expect(firstFGEl.index() + 1).toBe(tcWrapperEl.index());
|
||||
expect(lastFGEl.index() - 1).toBe(tcWrapperEl.index());
|
||||
});
|
||||
expect(firstFGEl.index() + 1).toBe(tcWrapperEl.index());
|
||||
expect(lastFGEl.index() - 1).toBe(tcWrapperEl.index());
|
||||
});
|
||||
|
||||
it('from the start, focus grabbers are disabled', function () {
|
||||
it('from the start, focus grabbers are disabled', function() {
|
||||
expect(state.focusGrabber.elFirst.attr('tabindex')).toBe('-1');
|
||||
expect(state.focusGrabber.elLast.attr('tabindex')).toBe('-1');
|
||||
});
|
||||
@@ -56,24 +55,22 @@
|
||||
it(
|
||||
'when first focus grabber is focused "mousemove" event is ' +
|
||||
'triggered, grabbers are disabled',
|
||||
function () {
|
||||
function() {
|
||||
state.focusGrabber.elFirst.triggerHandler('focus');
|
||||
|
||||
state.focusGrabber.elFirst.triggerHandler('focus');
|
||||
|
||||
expect('mousemove').toHaveBeenTriggeredOn(state.el);
|
||||
expect(state.focusGrabber.disableFocusGrabber).toHaveBeenCalled();
|
||||
});
|
||||
expect('mousemove').toHaveBeenTriggeredOn(state.el);
|
||||
expect(state.focusGrabber.disableFocusGrabber).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it(
|
||||
'when last focus grabber is focused "mousemove" event is ' +
|
||||
'triggered, grabbers are disabled',
|
||||
function () {
|
||||
function() {
|
||||
state.focusGrabber.elLast.triggerHandler('focus');
|
||||
|
||||
state.focusGrabber.elLast.triggerHandler('focus');
|
||||
|
||||
expect('mousemove').toHaveBeenTriggeredOn(state.el);
|
||||
expect(state.focusGrabber.disableFocusGrabber).toHaveBeenCalled();
|
||||
});
|
||||
expect('mousemove').toHaveBeenTriggeredOn(state.el);
|
||||
expect(state.focusGrabber.disableFocusGrabber).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Disabled on 18.11.2013 due to flakiness on local dev machine.
|
||||
//
|
||||
@@ -85,8 +82,8 @@
|
||||
//
|
||||
// TODO: Most likely, focusGrabber will be disabled in the future. This
|
||||
// test could become unneeded in the future.
|
||||
xit('after controls hide focus grabbers are enabled', function () {
|
||||
runs(function () {
|
||||
xit('after controls hide focus grabbers are enabled', function() {
|
||||
runs(function() {
|
||||
// Captions should not be "sticky" for the autohide mechanism
|
||||
// to work.
|
||||
state.videoCaption.hideCaptions(true);
|
||||
@@ -100,7 +97,7 @@
|
||||
// that there is clearly no race conditions for our expect below.
|
||||
waits(state.videoControl.fadeOutTimeout + 100);
|
||||
|
||||
runs(function () {
|
||||
runs(function() {
|
||||
expect(
|
||||
state.focusGrabber.enableFocusGrabber
|
||||
).toHaveBeenCalled();
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
(function () {
|
||||
(function() {
|
||||
'use strict';
|
||||
describe('VideoFullScreen', function () {
|
||||
describe('VideoFullScreen', function() {
|
||||
var state, oldOTBD;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine
|
||||
.createSpy('onTouchBasedDevice').and.returnValue(null);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
});
|
||||
|
||||
describe('constructor', function () {
|
||||
beforeEach(function () {
|
||||
describe('constructor', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
});
|
||||
|
||||
it('renders the fullscreen control', function () {
|
||||
it('renders the fullscreen control', function() {
|
||||
expect($('.add-fullscreen')).toExist();
|
||||
expect(state.videoFullScreen.fullScreenState).toBe(false);
|
||||
});
|
||||
|
||||
it('correctly adds ARIA attributes to fullscreen control', function () {
|
||||
it('correctly adds ARIA attributes to fullscreen control', function() {
|
||||
var fullScreenControl = $('.add-fullscreen');
|
||||
|
||||
expect(fullScreenControl).toHaveAttrs({
|
||||
@@ -34,7 +34,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly triggers the event handler to toggle fullscreen mode', function () {
|
||||
it('correctly triggers the event handler to toggle fullscreen mode', function() {
|
||||
spyOn(state.videoFullScreen, 'exit');
|
||||
spyOn(state.videoFullScreen, 'enter');
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
expect(state.videoFullScreen.exit).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('correctly updates ARIA on state change', function () {
|
||||
it('correctly updates ARIA on state change', function() {
|
||||
var fullScreenControl = $('.add-fullscreen');
|
||||
fullScreenControl.click();
|
||||
expect(fullScreenControl).toHaveAttrs({
|
||||
@@ -59,7 +59,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly can out of fullscreen by pressing esc', function () {
|
||||
it('correctly can out of fullscreen by pressing esc', function() {
|
||||
spyOn(state.videoCommands, 'execute');
|
||||
var esc = $.Event('keyup');
|
||||
esc.keyCode = 27;
|
||||
@@ -68,23 +68,23 @@
|
||||
expect(state.videoCommands.execute).toHaveBeenCalledWith('toggleFullScreen');
|
||||
});
|
||||
|
||||
it('can update video dimensions on state change', function () {
|
||||
it('can update video dimensions on state change', function() {
|
||||
state.el.trigger('fullscreen', [true]);
|
||||
expect(state.resizer.setMode).toHaveBeenCalledWith('both');
|
||||
state.el.trigger('fullscreen', [false]);
|
||||
expect(state.resizer.setMode).toHaveBeenCalledWith('width');
|
||||
});
|
||||
|
||||
it('can destroy itself', function () {
|
||||
it('can destroy itself', function() {
|
||||
state.videoFullScreen.destroy();
|
||||
expect($('.add-fullscreen')).not.toExist();
|
||||
expect(state.videoFullScreen).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('Controls height is actual on switch to fullscreen', function () {
|
||||
spyOn($.fn, 'height').and.callFake(function (val) {
|
||||
return _.isUndefined(val) ? 100: this;
|
||||
it('Controls height is actual on switch to fullscreen', function() {
|
||||
spyOn($.fn, 'height').and.callFake(function(val) {
|
||||
return _.isUndefined(val) ? 100 : this;
|
||||
});
|
||||
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(function () {
|
||||
(function() {
|
||||
'use strict';
|
||||
describe('VideoPlayPauseControl', function () {
|
||||
describe('VideoPlayPauseControl', function() {
|
||||
var state, oldOTBD;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine
|
||||
.createSpy('onTouchBasedDevice').and.returnValue(null);
|
||||
@@ -12,31 +12,31 @@
|
||||
spyOn(state.videoSaveStatePlugin, 'saveState');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
});
|
||||
|
||||
it('can render the control', function () {
|
||||
it('can render the control', function() {
|
||||
expect($('.video_control.play')).toExist();
|
||||
});
|
||||
|
||||
it('add ARIA attributes to play control', function () {
|
||||
it('add ARIA attributes to play control', function() {
|
||||
expect($('.video_control.play')).toHaveAttrs({
|
||||
'aria-disabled': 'false'
|
||||
});
|
||||
});
|
||||
|
||||
it('can update ARIA state on play', function () {
|
||||
it('can update ARIA state on play', function() {
|
||||
state.el.trigger('play');
|
||||
expect($('.video_control.pause')).toHaveAttrs({
|
||||
'aria-disabled': 'false'
|
||||
});
|
||||
});
|
||||
|
||||
it('can update ARIA state on video ends', function () {
|
||||
it('can update ARIA state on video ends', function() {
|
||||
state.el.trigger('play');
|
||||
state.el.trigger('ended');
|
||||
expect($('.video_control.play')).toHaveAttrs({
|
||||
@@ -44,17 +44,17 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can update state on pause', function () {
|
||||
it('can update state on pause', function() {
|
||||
state.el.trigger('pause');
|
||||
expect(state.videoSaveStatePlugin.saveState).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('can start video playing on click', function () {
|
||||
it('can start video playing on click', function() {
|
||||
$('.video_control.play').click();
|
||||
expect(state.videoCommands.execute).toHaveBeenCalledWith('togglePlayback');
|
||||
});
|
||||
|
||||
it('can destroy itself', function () {
|
||||
it('can destroy itself', function() {
|
||||
state.videoPlayPauseControl.destroy();
|
||||
expect(state.videoPlayPauseControl).toBeUndefined();
|
||||
});
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(function () {
|
||||
(function() {
|
||||
'use strict';
|
||||
describe('VideoPlayPlaceholder', function () {
|
||||
describe('VideoPlayPlaceholder', function() {
|
||||
var state, oldOTBD;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine
|
||||
.createSpy('onTouchBasedDevice').and.returnValue(['iPad']);
|
||||
@@ -12,7 +12,7 @@
|
||||
spyOn(state.videoCommands, 'execute');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
@@ -39,12 +39,12 @@
|
||||
}
|
||||
];
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
jasmine.stubRequests();
|
||||
spyOn(window.YT, 'Player').and.callThrough();
|
||||
});
|
||||
|
||||
it ('works correctly on calling proper methods', function () {
|
||||
it('works correctly on calling proper methods', function() {
|
||||
var btnPlay;
|
||||
|
||||
state = jasmine.initializePlayer();
|
||||
@@ -67,14 +67,14 @@
|
||||
});
|
||||
});
|
||||
|
||||
$.each(cases, function (index, data) {
|
||||
$.each(cases, function(index, data) {
|
||||
var message = [
|
||||
(data.isShown) ? 'is' : 'is not',
|
||||
' shown on',
|
||||
data.name
|
||||
].join('');
|
||||
|
||||
it(message, function () {
|
||||
it(message, function() {
|
||||
var btnPlay;
|
||||
|
||||
window.onTouchBasedDevice.and.returnValue(data.isTouch);
|
||||
@@ -89,61 +89,61 @@
|
||||
});
|
||||
});
|
||||
|
||||
$.each(['iPad', 'Android'], function (index, device) {
|
||||
$.each(['iPad', 'Android'], function(index, device) {
|
||||
it(
|
||||
'is shown on paused video on ' + device +
|
||||
' in HTML5 player',
|
||||
function ()
|
||||
function()
|
||||
{
|
||||
var btnPlay;
|
||||
var btnPlay;
|
||||
|
||||
window.onTouchBasedDevice.and.returnValue([device]);
|
||||
state = jasmine.initializePlayer();
|
||||
btnPlay = state.el.find('.btn-play');
|
||||
window.onTouchBasedDevice.and.returnValue([device]);
|
||||
state = jasmine.initializePlayer();
|
||||
btnPlay = state.el.find('.btn-play');
|
||||
|
||||
state.el.trigger('play');
|
||||
state.el.trigger('pause');
|
||||
expect(btnPlay).not.toHaveClass('is-hidden');
|
||||
});
|
||||
state.el.trigger('play');
|
||||
state.el.trigger('pause');
|
||||
expect(btnPlay).not.toHaveClass('is-hidden');
|
||||
});
|
||||
|
||||
it(
|
||||
'is hidden on playing video on ' + device +
|
||||
' in HTML5 player',
|
||||
function ()
|
||||
function()
|
||||
{
|
||||
var btnPlay;
|
||||
var btnPlay;
|
||||
|
||||
window.onTouchBasedDevice.and.returnValue([device]);
|
||||
state = jasmine.initializePlayer();
|
||||
btnPlay = state.el.find('.btn-play');
|
||||
window.onTouchBasedDevice.and.returnValue([device]);
|
||||
state = jasmine.initializePlayer();
|
||||
btnPlay = state.el.find('.btn-play');
|
||||
|
||||
state.el.trigger('play');
|
||||
expect(btnPlay).toHaveClass('is-hidden');
|
||||
});
|
||||
state.el.trigger('play');
|
||||
expect(btnPlay).toHaveClass('is-hidden');
|
||||
});
|
||||
|
||||
it(
|
||||
'is hidden on paused video on ' + device +
|
||||
' in YouTube player',
|
||||
function ()
|
||||
function()
|
||||
{
|
||||
var btnPlay;
|
||||
var btnPlay;
|
||||
|
||||
window.onTouchBasedDevice.and.returnValue([device]);
|
||||
state = jasmine.initializePlayerYouTube();
|
||||
btnPlay = state.el.find('.btn-play');
|
||||
window.onTouchBasedDevice.and.returnValue([device]);
|
||||
state = jasmine.initializePlayerYouTube();
|
||||
btnPlay = state.el.find('.btn-play');
|
||||
|
||||
state.el.trigger('play');
|
||||
state.el.trigger('pause');
|
||||
expect(btnPlay).toHaveClass('is-hidden');
|
||||
});
|
||||
state.el.trigger('play');
|
||||
state.el.trigger('pause');
|
||||
expect(btnPlay).toHaveClass('is-hidden');
|
||||
});
|
||||
});
|
||||
|
||||
it('starts play the video on click', function () {
|
||||
it('starts play the video on click', function() {
|
||||
$('.btn-play').click();
|
||||
expect(state.videoCommands.execute).toHaveBeenCalledWith('play');
|
||||
});
|
||||
|
||||
it('can destroy itself', function () {
|
||||
it('can destroy itself', function() {
|
||||
state.videoPlayPlaceholder.destroy();
|
||||
expect(state.videoPlayPlaceholder).toBeUndefined();
|
||||
});
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(function () {
|
||||
(function() {
|
||||
'use strict';
|
||||
describe('VideoPlaySkipControl', function () {
|
||||
describe('VideoPlaySkipControl', function() {
|
||||
var state, oldOTBD;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine
|
||||
.createSpy('onTouchBasedDevice').and.returnValue(null);
|
||||
@@ -12,7 +12,7 @@
|
||||
spyOn(state.bumperState.videoCommands, 'execute');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
state.storage.clear();
|
||||
if (state.bumperState && state.bumperState.videoPlayer) {
|
||||
@@ -24,29 +24,29 @@
|
||||
}
|
||||
});
|
||||
|
||||
it('can render the control', function () {
|
||||
it('can render the control', function() {
|
||||
expect($('.video_control.play')).toBeInDOM();
|
||||
});
|
||||
|
||||
it('can update state on play', function () {
|
||||
it('can update state on play', function() {
|
||||
state.el.trigger('play');
|
||||
expect($('.video_control.play')).not.toBeInDOM();
|
||||
expect($('.video_control.skip')).toBeInDOM();
|
||||
});
|
||||
|
||||
it('can start video playing on click', function () {
|
||||
it('can start video playing on click', function() {
|
||||
$('.video_control.play').click();
|
||||
expect(state.bumperState.videoCommands.execute).toHaveBeenCalledWith('play');
|
||||
});
|
||||
|
||||
it('can skip the video on click', function () {
|
||||
it('can skip the video on click', function() {
|
||||
state.el.trigger('play');
|
||||
spyOn(state.bumperState.videoPlayer, 'isPlaying').and.returnValue(true);
|
||||
$('.video_control.skip').first().click();
|
||||
expect(state.bumperState.videoCommands.execute).toHaveBeenCalledWith('skip');
|
||||
});
|
||||
|
||||
it('can destroy itself', function () {
|
||||
it('can destroy itself', function() {
|
||||
var plugin = state.bumperState.videoPlaySkipControl,
|
||||
el = plugin.el;
|
||||
spyOn($.fn, 'off').and.callThrough();
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
(function (requirejs, require, define, undefined) {
|
||||
'use strict';
|
||||
(function(requirejs, require, define, undefined) {
|
||||
'use strict';
|
||||
|
||||
require(
|
||||
require(
|
||||
['video/03_video_player.js'],
|
||||
function (VideoPlayer) {
|
||||
describe('VideoPlayer', function () {
|
||||
function(VideoPlayer) {
|
||||
describe('VideoPlayer', function() {
|
||||
var state, oldOTBD, empty_arguments;
|
||||
|
||||
(function () {
|
||||
(function() {
|
||||
empty_arguments = arguments;
|
||||
})();
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice')
|
||||
.and.returnValue(null);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
window.Video.previousState = null;
|
||||
@@ -29,40 +29,40 @@ function (VideoPlayer) {
|
||||
}
|
||||
});
|
||||
|
||||
describe('constructor', function () {
|
||||
describe('always', function () {
|
||||
beforeEach(function () {
|
||||
describe('constructor', function() {
|
||||
describe('always', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
state.videoEl = $('video, iframe');
|
||||
});
|
||||
|
||||
it('instanticate current time to zero', function () {
|
||||
it('instanticate current time to zero', function() {
|
||||
expect(state.videoPlayer.currentTime).toEqual(0);
|
||||
});
|
||||
|
||||
it('set the element', function () {
|
||||
it('set the element', function() {
|
||||
expect(state.el).toHaveId('video_id');
|
||||
});
|
||||
|
||||
it('create video control', function () {
|
||||
it('create video control', function() {
|
||||
expect(state.videoControl).toBeDefined();
|
||||
expect(state.videoControl.el).toHaveClass('video-controls');
|
||||
});
|
||||
|
||||
it('create video caption', function () {
|
||||
it('create video caption', function() {
|
||||
expect(state.videoCaption).toBeDefined();
|
||||
expect(state.speed).toEqual('1.50');
|
||||
expect(state.config.transcriptTranslationUrl)
|
||||
.toEqual('/transcript/translation/__lang__');
|
||||
});
|
||||
|
||||
it('create video speed control', function () {
|
||||
it('create video speed control', function() {
|
||||
expect(state.videoSpeedControl).toBeDefined();
|
||||
expect(state.videoSpeedControl.el).toHaveClass('speeds');
|
||||
expect(state.speed).toEqual('1.50');
|
||||
});
|
||||
|
||||
it('create video progress slider', function () {
|
||||
it('create video progress slider', function() {
|
||||
expect(state.videoProgressSlider).toBeDefined();
|
||||
expect(state.videoProgressSlider.el).toHaveClass('slider');
|
||||
});
|
||||
@@ -73,7 +73,7 @@ function (VideoPlayer) {
|
||||
// previous version of Video.
|
||||
});
|
||||
|
||||
it('create Youtube player', function () {
|
||||
it('create Youtube player', function() {
|
||||
var events;
|
||||
|
||||
jasmine.stubRequests();
|
||||
@@ -82,10 +82,10 @@ function (VideoPlayer) {
|
||||
state.videoEl = $('video, iframe');
|
||||
|
||||
events = {
|
||||
onReady: state.videoPlayer.onReady,
|
||||
onStateChange: state.videoPlayer.onStateChange,
|
||||
onReady: state.videoPlayer.onReady,
|
||||
onStateChange: state.videoPlayer.onStateChange,
|
||||
onPlaybackQualityChange: state.videoPlayer.onPlaybackQualityChange,
|
||||
onError: state.videoPlayer.onError
|
||||
onError: state.videoPlayer.onError
|
||||
};
|
||||
|
||||
expect(YT.Player).toHaveBeenCalledWith('id', {
|
||||
@@ -104,7 +104,7 @@ function (VideoPlayer) {
|
||||
});
|
||||
});
|
||||
|
||||
it('create Flash player', function () {
|
||||
it('create Flash player', function() {
|
||||
var player;
|
||||
|
||||
spyOn($.fn, 'trigger');
|
||||
@@ -138,9 +138,9 @@ function (VideoPlayer) {
|
||||
// available globally. It is defined within the scope of Require
|
||||
// JS.
|
||||
|
||||
describe('when on a touch based device', function () {
|
||||
$.each(['iPad', 'Android'], function (index, device) {
|
||||
it('create video volume control on' + device, function () {
|
||||
describe('when on a touch based device', function() {
|
||||
$.each(['iPad', 'Android'], function(index, device) {
|
||||
it('create video volume control on' + device, function() {
|
||||
window.onTouchBasedDevice.and.returnValue([device]);
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
@@ -151,23 +151,23 @@ function (VideoPlayer) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when not on a touch based device', function () {
|
||||
describe('when not on a touch based device', function() {
|
||||
var oldOTBD;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
state.videoEl = $('video, iframe');
|
||||
});
|
||||
|
||||
it('controls are in paused state', function () {
|
||||
it('controls are in paused state', function() {
|
||||
expect(state.videoPlayer.isPlaying()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('onReady', function () {
|
||||
beforeEach(function () {
|
||||
describe('onReady', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
state.videoEl = $('video, iframe');
|
||||
@@ -175,24 +175,24 @@ function (VideoPlayer) {
|
||||
state.videoPlayer.onReady();
|
||||
});
|
||||
|
||||
it('autoplay the first video', function () {
|
||||
it('autoplay the first video', function() {
|
||||
expect(state.videoPlayer.play).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
||||
it('invalid endTime is reset to null', function () {
|
||||
it('invalid endTime is reset to null', function() {
|
||||
expect(state.videoPlayer.endTime).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onReady YouTube', function () {
|
||||
beforeEach(function () {
|
||||
describe('onReady YouTube', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayerYouTube();
|
||||
|
||||
state.videoEl = $('video, iframe');
|
||||
});
|
||||
|
||||
it('multiple speeds and flash mode, change back to html5 mode', function () {
|
||||
it('multiple speeds and flash mode, change back to html5 mode', function() {
|
||||
var playbackRates = state.videoPlayer.player.getAvailablePlaybackRates();
|
||||
|
||||
state.currentPlayerMode = 'flash';
|
||||
@@ -202,9 +202,9 @@ function (VideoPlayer) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('onStateChange Youtube', function(){
|
||||
describe('when the video is ended', function () {
|
||||
beforeEach(function () {
|
||||
describe('onStateChange Youtube', function() {
|
||||
describe('when the video is ended', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayerYouTube();
|
||||
|
||||
state.videoEl = $('video, iframe');
|
||||
@@ -214,20 +214,20 @@ function (VideoPlayer) {
|
||||
});
|
||||
});
|
||||
|
||||
it('pause the video control', function () {
|
||||
it('pause the video control', function() {
|
||||
expect($('.video_control')).toHaveClass('play');
|
||||
});
|
||||
|
||||
it('trigger pause and ended events', function () {
|
||||
it('trigger pause and ended events', function() {
|
||||
expect($.fn.trigger).toHaveBeenCalledWith('pause', empty_arguments);
|
||||
expect($.fn.trigger).toHaveBeenCalledWith('ended', empty_arguments);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('onStateChange', function () {
|
||||
describe('when the video is unstarted', function () {
|
||||
beforeEach(function () {
|
||||
describe('onStateChange', function() {
|
||||
describe('when the video is unstarted', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
state.videoEl = $('video, iframe');
|
||||
spyOn($.fn, 'trigger').and.callThrough();
|
||||
@@ -237,19 +237,19 @@ function (VideoPlayer) {
|
||||
});
|
||||
});
|
||||
|
||||
it('pause the video control', function () {
|
||||
it('pause the video control', function() {
|
||||
expect($('.video_control')).toHaveClass('play');
|
||||
});
|
||||
|
||||
it('pause the video caption', function () {
|
||||
it('pause the video caption', function() {
|
||||
expect($.fn.trigger).toHaveBeenCalledWith('pause', empty_arguments);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the video is playing', function () {
|
||||
describe('when the video is playing', function() {
|
||||
var oldState;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
// Create the first instance of the player.
|
||||
state = jasmine.initializePlayer();
|
||||
oldState = state;
|
||||
@@ -269,26 +269,26 @@ function (VideoPlayer) {
|
||||
});
|
||||
});
|
||||
|
||||
it('set update interval', function () {
|
||||
it('set update interval', function() {
|
||||
expect(window.setInterval).toHaveBeenCalledWith(
|
||||
state.videoPlayer.update, 200
|
||||
);
|
||||
expect(state.videoPlayer.updateInterval).toEqual(100);
|
||||
});
|
||||
|
||||
it('play the video control', function () {
|
||||
it('play the video control', function() {
|
||||
expect($('.video_control')).toHaveClass('pause');
|
||||
});
|
||||
|
||||
it('play the video caption', function () {
|
||||
it('play the video caption', function() {
|
||||
expect($.fn.trigger).toHaveBeenCalledWith('play', empty_arguments);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the video is paused', function () {
|
||||
describe('when the video is paused', function() {
|
||||
var currentUpdateIntrval;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
state.videoEl = $('video, iframe');
|
||||
@@ -305,21 +305,21 @@ function (VideoPlayer) {
|
||||
});
|
||||
});
|
||||
|
||||
it('clear update interval', function () {
|
||||
it('clear update interval', function() {
|
||||
expect(state.videoPlayer.updateInterval).toBeUndefined();
|
||||
});
|
||||
|
||||
it('pause the video control', function () {
|
||||
it('pause the video control', function() {
|
||||
expect($('.video_control')).toHaveClass('play');
|
||||
});
|
||||
|
||||
it('pause the video caption', function () {
|
||||
it('pause the video caption', function() {
|
||||
expect($.fn.trigger).toHaveBeenCalledWith('pause', empty_arguments);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the video is ended', function () {
|
||||
beforeEach(function () {
|
||||
describe('when the video is ended', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
state.videoEl = $('video, iframe');
|
||||
@@ -329,45 +329,45 @@ function (VideoPlayer) {
|
||||
});
|
||||
});
|
||||
|
||||
it('pause the video control', function () {
|
||||
it('pause the video control', function() {
|
||||
expect($('.video_control')).toHaveClass('play');
|
||||
});
|
||||
|
||||
it('pause the video caption', function () {
|
||||
it('pause the video caption', function() {
|
||||
expect($.fn.trigger).toHaveBeenCalledWith('ended', empty_arguments);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSeek Youtube', function(){
|
||||
beforeEach(function () {
|
||||
describe('onSeek Youtube', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayerYouTube();
|
||||
state.videoEl = $('video, iframe');
|
||||
});
|
||||
|
||||
describe('when the video is playing', function () {
|
||||
beforeEach(function(){
|
||||
state.videoPlayer.onStateChange({
|
||||
data: YT.PlayerState.PLAYING
|
||||
});
|
||||
});
|
||||
describe('when the video is playing', function() {
|
||||
beforeEach(function() {
|
||||
state.videoPlayer.onStateChange({
|
||||
data: YT.PlayerState.PLAYING
|
||||
});
|
||||
});
|
||||
|
||||
it('Video has started playing', function () {
|
||||
expect($('.video_control')).toHaveClass('pause');
|
||||
});
|
||||
it('Video has started playing', function() {
|
||||
expect($('.video_control')).toHaveClass('pause');
|
||||
});
|
||||
|
||||
it('seek the player', function () {
|
||||
state.videoPlayer.seekTo(10);
|
||||
expect(state.videoPlayer.currentTime).toBe(10);
|
||||
});
|
||||
});
|
||||
it('seek the player', function() {
|
||||
state.videoPlayer.seekTo(10);
|
||||
expect(state.videoPlayer.currentTime).toBe(10);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSeek', function () {
|
||||
beforeEach(function () {
|
||||
describe('onSeek', function() {
|
||||
beforeEach(function() {
|
||||
// jasmine.Clock can't be used to fake out debounce with newer versions of underscore
|
||||
spyOn(_, 'debounce').and.callFake(function (func) {
|
||||
return function () {
|
||||
spyOn(_, 'debounce').and.callFake(function(func) {
|
||||
return function() {
|
||||
func.apply(this, arguments);
|
||||
};
|
||||
});
|
||||
@@ -376,8 +376,8 @@ function (VideoPlayer) {
|
||||
spyOn(state.videoPlayer, 'duration').and.returnValue(120);
|
||||
});
|
||||
|
||||
describe('when the video is playing', function () {
|
||||
beforeEach(function (done) {
|
||||
describe('when the video is playing', function() {
|
||||
beforeEach(function(done) {
|
||||
state.videoPlayer.play();
|
||||
|
||||
jasmine.waitUntil(function() {
|
||||
@@ -386,7 +386,7 @@ function (VideoPlayer) {
|
||||
});
|
||||
|
||||
|
||||
it('call runTimer in seekTo on player', function () {
|
||||
it('call runTimer in seekTo on player', function() {
|
||||
spyOn(state.videoPlayer, 'stopTimer').and.callThrough();
|
||||
spyOn(state.videoPlayer, 'runTimer').and.callThrough();
|
||||
state.videoPlayer.seekTo(10);
|
||||
@@ -395,44 +395,44 @@ function (VideoPlayer) {
|
||||
expect(state.videoPlayer.runTimer).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('seek the player', function () {
|
||||
it('seek the player', function() {
|
||||
spyOn(state.videoPlayer.player, 'seekTo').and.callThrough();
|
||||
state.videoProgressSlider.onSlide(
|
||||
jQuery.Event('slide'), { value: 30 }
|
||||
jQuery.Event('slide'), {value: 30}
|
||||
);
|
||||
expect(state.videoPlayer.currentTime).toBe(30);
|
||||
expect(state.videoPlayer.player.seekTo).toHaveBeenCalledWith(30, true);
|
||||
});
|
||||
|
||||
it('call updatePlayTime on player', function () {
|
||||
it('call updatePlayTime on player', function() {
|
||||
spyOn(state.videoPlayer, 'updatePlayTime').and.callThrough();
|
||||
state.videoProgressSlider.onSlide(
|
||||
jQuery.Event('slide'), { value: 30 }
|
||||
jQuery.Event('slide'), {value: 30}
|
||||
);
|
||||
expect(state.videoPlayer.currentTime).toBe(30);
|
||||
expect(state.videoPlayer.updatePlayTime).toHaveBeenCalledWith(30, true);
|
||||
});
|
||||
});
|
||||
|
||||
it('when the player is not playing: set the current time', function () {
|
||||
it('when the player is not playing: set the current time', function() {
|
||||
state.videoProgressSlider.onSlide(
|
||||
jQuery.Event('slide'), { value: 20 }
|
||||
jQuery.Event('slide'), {value: 20}
|
||||
);
|
||||
state.videoPlayer.pause();
|
||||
expect(state.videoPlayer.currentTime).toBe(20);
|
||||
state.videoProgressSlider.onSlide(
|
||||
jQuery.Event('slide'), { value: 10 }
|
||||
jQuery.Event('slide'), {value: 10}
|
||||
);
|
||||
expect(state.videoPlayer.currentTime).toBe(10);
|
||||
});
|
||||
|
||||
describe('when the video is not playing', function () {
|
||||
beforeEach(function () {
|
||||
describe('when the video is not playing', function() {
|
||||
beforeEach(function() {
|
||||
spyOn(state.videoPlayer, 'setPlaybackRate')
|
||||
.and.callThrough();
|
||||
});
|
||||
|
||||
it('video has a correct speed', function () {
|
||||
it('video has a correct speed', function() {
|
||||
state.speed = '2.0';
|
||||
state.videoPlayer.onPlay();
|
||||
expect(state.videoPlayer.setPlaybackRate)
|
||||
@@ -444,26 +444,26 @@ function (VideoPlayer) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('onVolumeChange', function () {
|
||||
beforeEach(function () {
|
||||
describe('onVolumeChange', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
state.videoPlayer.onReady();
|
||||
state.videoEl = $('video, iframe');
|
||||
});
|
||||
|
||||
it('set the volume on player', function () {
|
||||
it('set the volume on player', function() {
|
||||
spyOn(state.videoPlayer.player, 'setVolume');
|
||||
state.videoPlayer.onVolumeChange(60);
|
||||
expect(state.videoPlayer.player.setVolume)
|
||||
.toHaveBeenCalledWith(60);
|
||||
});
|
||||
|
||||
describe('when the video is not playing', function () {
|
||||
beforeEach(function () {
|
||||
describe('when the video is not playing', function() {
|
||||
beforeEach(function() {
|
||||
state.videoPlayer.player.setVolume('1');
|
||||
});
|
||||
|
||||
it('video has a correct volume', function () {
|
||||
it('video has a correct volume', function() {
|
||||
spyOn(state.videoPlayer.player, 'setVolume');
|
||||
state.videoVolumeControl.volume = 26;
|
||||
state.el.trigger('play');
|
||||
@@ -473,8 +473,8 @@ function (VideoPlayer) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', function () {
|
||||
beforeEach(function () {
|
||||
describe('update', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
state.videoEl = $('video, iframe');
|
||||
@@ -484,44 +484,44 @@ function (VideoPlayer) {
|
||||
|
||||
describe(
|
||||
'when the current time is unavailable from the player',
|
||||
function ()
|
||||
function()
|
||||
{
|
||||
beforeEach(function () {
|
||||
state.videoPlayer.player.getCurrentTime = function () {
|
||||
return NaN;
|
||||
};
|
||||
state.videoPlayer.update();
|
||||
});
|
||||
beforeEach(function() {
|
||||
state.videoPlayer.player.getCurrentTime = function() {
|
||||
return NaN;
|
||||
};
|
||||
state.videoPlayer.update();
|
||||
});
|
||||
|
||||
it('does not trigger updatePlayTime event', function () {
|
||||
expect(state.videoPlayer.updatePlayTime)
|
||||
it('does not trigger updatePlayTime event', function() {
|
||||
expect(state.videoPlayer.updatePlayTime)
|
||||
.not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe(
|
||||
'when the current time is available from the player',
|
||||
function ()
|
||||
function()
|
||||
{
|
||||
beforeEach(function () {
|
||||
state.videoPlayer.player.getCurrentTime = function () {
|
||||
return 60;
|
||||
};
|
||||
state.videoPlayer.update();
|
||||
});
|
||||
beforeEach(function() {
|
||||
state.videoPlayer.player.getCurrentTime = function() {
|
||||
return 60;
|
||||
};
|
||||
state.videoPlayer.update();
|
||||
});
|
||||
|
||||
it('trigger updatePlayTime event', function () {
|
||||
expect(state.videoPlayer.updatePlayTime)
|
||||
it('trigger updatePlayTime event', function() {
|
||||
expect(state.videoPlayer.updatePlayTime)
|
||||
.toHaveBeenCalledWith(60);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Disabled 1/13/14 due to flakiness observed in master
|
||||
xdescribe('update with start & end time', function () {
|
||||
xdescribe('update with start & end time', function() {
|
||||
var START_TIME = 1, END_TIME = 2;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer(
|
||||
{
|
||||
start: START_TIME,
|
||||
@@ -539,41 +539,41 @@ function (VideoPlayer) {
|
||||
|
||||
it(
|
||||
'video is paused on first endTime, start & end time are reset',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration;
|
||||
var duration;
|
||||
|
||||
state.videoProgressSlider.notifyThroughHandleEnd.calls.reset();
|
||||
state.videoPlayer.pause.calls.reset();
|
||||
state.videoPlayer.play();
|
||||
state.videoProgressSlider.notifyThroughHandleEnd.calls.reset();
|
||||
state.videoPlayer.pause.calls.reset();
|
||||
state.videoPlayer.play();
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = Math.round(state.videoPlayer.currentTime);
|
||||
return state.videoPlayer.pause.calls.count() === 1;
|
||||
}).then(function () {
|
||||
expect(state.videoPlayer.startTime).toBe(0);
|
||||
expect(state.videoPlayer.endTime).toBe(null);
|
||||
jasmine.waitUntil(function() {
|
||||
duration = Math.round(state.videoPlayer.currentTime);
|
||||
return state.videoPlayer.pause.calls.count() === 1;
|
||||
}).then(function() {
|
||||
expect(state.videoPlayer.startTime).toBe(0);
|
||||
expect(state.videoPlayer.endTime).toBe(null);
|
||||
|
||||
expect(duration).toBe(END_TIME);
|
||||
expect(duration).toBe(END_TIME);
|
||||
|
||||
expect(state.videoProgressSlider.notifyThroughHandleEnd)
|
||||
expect(state.videoProgressSlider.notifyThroughHandleEnd)
|
||||
.toHaveBeenCalledWith({end: true});
|
||||
}).always(done);
|
||||
});
|
||||
}).always(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updatePlayTime', function () {
|
||||
beforeEach(function () {
|
||||
describe('updatePlayTime', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayerYouTube();
|
||||
state.videoEl = $('video, iframe');
|
||||
spyOn(state.videoCaption, 'updatePlayTime').and.callThrough();
|
||||
spyOn(state.videoProgressSlider, 'updatePlayTime').and.callThrough();
|
||||
});
|
||||
|
||||
it('update the video playback time', function (done) {
|
||||
it('update the video playback time', function(done) {
|
||||
var duration = 0;
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
if (duration > 0) {
|
||||
@@ -581,7 +581,7 @@ function (VideoPlayer) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
state.videoPlayer.goToStartTime = false;
|
||||
state.videoPlayer.updatePlayTime(60);
|
||||
|
||||
@@ -589,10 +589,10 @@ function (VideoPlayer) {
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it('update the playback time on caption', function (done) {
|
||||
jasmine.waitUntil(function () {
|
||||
it('update the playback time on caption', function(done) {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.duration() > 0;
|
||||
}, 1000).then(function () {
|
||||
}, 1000).then(function() {
|
||||
state.videoPlayer.goToStartTime = false;
|
||||
state.videoPlayer.updatePlayTime(60);
|
||||
|
||||
@@ -601,14 +601,14 @@ function (VideoPlayer) {
|
||||
}).always(done);
|
||||
});
|
||||
|
||||
it('update the playback time on progress slider', function (done) {
|
||||
it('update the playback time on progress slider', function(done) {
|
||||
var duration = 0;
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return duration > 0;
|
||||
}, 1000).then(function () {
|
||||
}, 1000).then(function() {
|
||||
state.videoPlayer.goToStartTime = false;
|
||||
state.videoPlayer.updatePlayTime(60);
|
||||
|
||||
@@ -624,65 +624,65 @@ function (VideoPlayer) {
|
||||
// Disabled 1/13/14 due to flakiness observed in master
|
||||
xdescribe(
|
||||
'updatePlayTime when start & end times are defined',
|
||||
function ()
|
||||
function()
|
||||
{
|
||||
var START_TIME = 1,
|
||||
END_TIME = 2;
|
||||
var START_TIME = 1,
|
||||
END_TIME = 2;
|
||||
|
||||
beforeEach(function () {
|
||||
state = jasmine.initializePlayer(
|
||||
{
|
||||
start: START_TIME,
|
||||
end: END_TIME
|
||||
}
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer(
|
||||
{
|
||||
start: START_TIME,
|
||||
end: END_TIME
|
||||
}
|
||||
);
|
||||
|
||||
state.videoEl = $('video, iframe');
|
||||
state.videoEl = $('video, iframe');
|
||||
|
||||
spyOn(state.videoPlayer, 'updatePlayTime').and.callThrough();
|
||||
spyOn(state.videoPlayer.player, 'seekTo').and.callThrough();
|
||||
spyOn(state.videoProgressSlider, 'updateStartEndTimeRegion')
|
||||
spyOn(state.videoPlayer, 'updatePlayTime').and.callThrough();
|
||||
spyOn(state.videoPlayer.player, 'seekTo').and.callThrough();
|
||||
spyOn(state.videoProgressSlider, 'updateStartEndTimeRegion')
|
||||
.and.callThrough();
|
||||
});
|
||||
});
|
||||
|
||||
it(
|
||||
it(
|
||||
'when duration becomes available, updatePlayTime() is called',
|
||||
function (done)
|
||||
function(done)
|
||||
{
|
||||
var duration;
|
||||
var duration;
|
||||
|
||||
expect(state.videoPlayer.initialSeekToStartTime).toBeTruthy();
|
||||
expect(state.videoPlayer.seekToStartTimeOldSpeed).toBe('void');
|
||||
expect(state.videoPlayer.initialSeekToStartTime).toBeTruthy();
|
||||
expect(state.videoPlayer.seekToStartTimeOldSpeed).toBe('void');
|
||||
|
||||
state.videoPlayer.play();
|
||||
state.videoPlayer.play();
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
duration = state.videoPlayer.duration();
|
||||
jasmine.waitUntil(function() {
|
||||
duration = state.videoPlayer.duration();
|
||||
|
||||
return state.videoPlayer.isPlaying() &&
|
||||
return state.videoPlayer.isPlaying() &&
|
||||
state.videoPlayer.initialSeekToStartTime === false;
|
||||
}).then(function () {
|
||||
expect(state.videoPlayer.startTime).toBe(START_TIME);
|
||||
expect(state.videoPlayer.endTime).toBe(END_TIME);
|
||||
}).then(function() {
|
||||
expect(state.videoPlayer.startTime).toBe(START_TIME);
|
||||
expect(state.videoPlayer.endTime).toBe(END_TIME);
|
||||
|
||||
expect(state.videoPlayer.player.seekTo)
|
||||
expect(state.videoPlayer.player.seekTo)
|
||||
.toHaveBeenCalledWith(START_TIME);
|
||||
|
||||
expect(state.videoProgressSlider.updateStartEndTimeRegion)
|
||||
expect(state.videoProgressSlider.updateStartEndTimeRegion)
|
||||
.toHaveBeenCalledWith({duration: duration});
|
||||
|
||||
expect(state.videoPlayer.seekToStartTimeOldSpeed)
|
||||
expect(state.videoPlayer.seekToStartTimeOldSpeed)
|
||||
.toBe(state.speed);
|
||||
}).always(done);
|
||||
}).always(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('updatePlayTime with invalid endTime', function () {
|
||||
beforeEach(function () {
|
||||
describe('updatePlayTime with invalid endTime', function() {
|
||||
beforeEach(function() {
|
||||
state = {
|
||||
el: $('#video_id'),
|
||||
videoPlayer: {
|
||||
duration: function () {
|
||||
duration: function() {
|
||||
// The video will be 60 seconds long.
|
||||
return 60;
|
||||
},
|
||||
@@ -690,7 +690,7 @@ function (VideoPlayer) {
|
||||
startTime: undefined,
|
||||
endTime: undefined,
|
||||
player: {
|
||||
seekTo: function () {}
|
||||
seekTo: function() {}
|
||||
},
|
||||
figureOutStartEndTime: jasmine.createSpy(),
|
||||
figureOutStartingTime: jasmine.createSpy().and.returnValue(0)
|
||||
@@ -706,35 +706,35 @@ function (VideoPlayer) {
|
||||
endTime: 10000
|
||||
},
|
||||
currentPlayerMode: 'html5',
|
||||
trigger: function () {},
|
||||
trigger: function() {},
|
||||
browserIsFirefox: false,
|
||||
isFlashMode: jasmine.createSpy().and.returnValue(false)
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
describe('toggleFullScreen', function () {
|
||||
describe('when the video player is not full screen', function () {
|
||||
beforeEach(function () {
|
||||
describe('toggleFullScreen', function() {
|
||||
describe('when the video player is not full screen', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
state.videoEl = $('video, iframe');
|
||||
spyOn($.fn, 'trigger').and.callThrough();
|
||||
$('.add-fullscreen').click();
|
||||
});
|
||||
|
||||
it('add the video-fullscreen class', function () {
|
||||
it('add the video-fullscreen class', function() {
|
||||
expect(state.el).toHaveClass('video-fullscreen');
|
||||
});
|
||||
|
||||
it('tell VideoCaption to resize', function () {
|
||||
it('tell VideoCaption to resize', function() {
|
||||
expect($.fn.trigger).toHaveBeenCalledWith('fullscreen', [true]);
|
||||
expect(state.resizer.setMode).toHaveBeenCalledWith('both');
|
||||
expect(state.resizer.delta.substract).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the video player already full screen', function () {
|
||||
beforeEach(function () {
|
||||
describe('when the video player already full screen', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
state.videoEl = $('video, iframe');
|
||||
spyOn($.fn, 'trigger').and.callThrough();
|
||||
@@ -745,11 +745,11 @@ function (VideoPlayer) {
|
||||
$('.add-fullscreen').click();
|
||||
});
|
||||
|
||||
it('remove the video-fullscreen class', function () {
|
||||
it('remove the video-fullscreen class', function() {
|
||||
expect(state.el).not.toHaveClass('video-fullscreen');
|
||||
});
|
||||
|
||||
it('tell VideoCaption to resize', function () {
|
||||
it('tell VideoCaption to resize', function() {
|
||||
expect($.fn.trigger).toHaveBeenCalledWith('fullscreen', [false]);
|
||||
expect(state.resizer.setMode)
|
||||
.toHaveBeenCalledWith('width');
|
||||
@@ -758,8 +758,8 @@ function (VideoPlayer) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('duration', function () {
|
||||
beforeEach(function () {
|
||||
describe('duration', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
state.videoEl = $('video, iframe');
|
||||
@@ -768,13 +768,13 @@ function (VideoPlayer) {
|
||||
state.videoPlayer.duration();
|
||||
});
|
||||
|
||||
it('delegate to the player', function () {
|
||||
it('delegate to the player', function() {
|
||||
expect(state.videoPlayer.player.getDuration).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getDuration', function () {
|
||||
beforeEach(function () {
|
||||
describe('getDuration', function() {
|
||||
beforeEach(function() {
|
||||
// We need to make sure that metadata is returned via an AJAX
|
||||
// request. Without the jasmine.stubRequests() below we will
|
||||
// get the error:
|
||||
@@ -793,15 +793,15 @@ function (VideoPlayer) {
|
||||
state.videoPlayer.player.getDuration.and.returnValue(0);
|
||||
});
|
||||
|
||||
it('getDuration is called as a fall-back', function () {
|
||||
it('getDuration is called as a fall-back', function() {
|
||||
state.videoPlayer.duration();
|
||||
|
||||
expect(state.getDuration).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('volume', function () {
|
||||
beforeEach(function () {
|
||||
describe('volume', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
state.videoEl = $('video, iframe');
|
||||
@@ -809,33 +809,33 @@ function (VideoPlayer) {
|
||||
spyOn(state.videoPlayer.player, 'getVolume').and.callThrough();
|
||||
});
|
||||
|
||||
it('set the player volume', function () {
|
||||
it('set the player volume', function() {
|
||||
var expectedValue = 60,
|
||||
realValue;
|
||||
realValue;
|
||||
|
||||
state.videoPlayer.player.setVolume(60);
|
||||
realValue = Math.round(state.videoPlayer.player.getVolume()*100);
|
||||
realValue = Math.round(state.videoPlayer.player.getVolume() * 100);
|
||||
|
||||
expect(realValue).toEqual(expectedValue);
|
||||
});
|
||||
});
|
||||
|
||||
describe('on Touch devices', function () {
|
||||
it('`is-touch` class name is added to container', function () {
|
||||
describe('on Touch devices', function() {
|
||||
it('`is-touch` class name is added to container', function() {
|
||||
$.each(
|
||||
['iPad', 'Android', 'iPhone'],
|
||||
function (index, device)
|
||||
function(index, device)
|
||||
{
|
||||
window.onTouchBasedDevice.and.returnValue([device]);
|
||||
state = jasmine.initializePlayer();
|
||||
window.onTouchBasedDevice.and.returnValue([device]);
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
state.videoEl = $('video, iframe');
|
||||
state.videoEl = $('video, iframe');
|
||||
|
||||
expect(state.el).toHaveClass('is-touch');
|
||||
});
|
||||
expect(state.el).toHaveClass('is-touch');
|
||||
});
|
||||
});
|
||||
|
||||
it('modules are not initialized on iPhone', function () {
|
||||
it('modules are not initialized on iPhone', function() {
|
||||
window.onTouchBasedDevice.and.returnValue(['iPhone']);
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
@@ -846,16 +846,16 @@ function (VideoPlayer) {
|
||||
state.videoSpeedControl, state.videoVolumeControl
|
||||
];
|
||||
|
||||
$.each(modules, function (index, module) {
|
||||
$.each(modules, function(index, module) {
|
||||
expect(module).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
$.each(['iPad', 'Android'], function (index, device) {
|
||||
$.each(['iPad', 'Android'], function(index, device) {
|
||||
var message = 'controls become visible after playing starts ' +
|
||||
'on ' + device;
|
||||
|
||||
it(message, function (done) {
|
||||
it(message, function(done) {
|
||||
var controls;
|
||||
|
||||
window.onTouchBasedDevice.and.returnValue([device]);
|
||||
@@ -864,17 +864,17 @@ function (VideoPlayer) {
|
||||
state.videoEl = $('video, iframe');
|
||||
controls = state.el.find('.video-controls');
|
||||
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
return state.el.hasClass('is-initialized');
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(controls).toHaveClass('is-hidden');
|
||||
state.videoPlayer.play();
|
||||
jasmine.waitUntil(function () {
|
||||
jasmine.waitUntil(function() {
|
||||
// Firefox does not return duration for videos until they have reached the end.
|
||||
// var duration = state.videoPlayer.duration();
|
||||
// return duration > 0 && state.videoPlayer.isPlaying();
|
||||
return state.videoPlayer.isPlaying();
|
||||
}).then(function () {
|
||||
}).then(function() {
|
||||
expect(controls).not.toHaveClass('is-hidden');
|
||||
}).always(done);
|
||||
});
|
||||
@@ -882,8 +882,8 @@ function (VideoPlayer) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSpeedChange', function () {
|
||||
beforeEach(function () {
|
||||
describe('onSpeedChange', function() {
|
||||
beforeEach(function() {
|
||||
state = {
|
||||
el: $(document),
|
||||
speed: '1.50',
|
||||
@@ -899,14 +899,14 @@ function (VideoPlayer) {
|
||||
};
|
||||
});
|
||||
|
||||
describe('always', function () {
|
||||
it('convert the current time to the new speed', function () {
|
||||
describe('always', function() {
|
||||
it('convert the current time to the new speed', function() {
|
||||
state.isFlashMode.and.returnValue(true);
|
||||
VideoPlayer.prototype.onSpeedChange.call(state, '0.75', false);
|
||||
expect(state.videoPlayer.currentTime).toBe('120.000');
|
||||
});
|
||||
|
||||
it('set video speed to the new speed', function () {
|
||||
it('set video speed to the new speed', function() {
|
||||
VideoPlayer.prototype.onSpeedChange.call(state, '0.75', false);
|
||||
expect(state.setSpeed).toHaveBeenCalledWith('0.75');
|
||||
expect(state.videoPlayer.setPlaybackRate)
|
||||
@@ -915,8 +915,8 @@ function (VideoPlayer) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('setPlaybackRate', function () {
|
||||
beforeEach(function () {
|
||||
describe('setPlaybackRate', function() {
|
||||
beforeEach(function() {
|
||||
state = {
|
||||
youtubeId: jasmine.createSpy().and.returnValue('videoId'),
|
||||
isFlashMode: jasmine.createSpy().and.returnValue(false),
|
||||
@@ -938,7 +938,7 @@ function (VideoPlayer) {
|
||||
};
|
||||
});
|
||||
|
||||
it('in Flash mode and video is playing', function () {
|
||||
it('in Flash mode and video is playing', function() {
|
||||
state.isFlashMode.and.returnValue(true);
|
||||
state.isHtml5Mode.and.returnValue(false);
|
||||
state.videoPlayer.isPlaying.and.returnValue(true);
|
||||
@@ -948,7 +948,7 @@ function (VideoPlayer) {
|
||||
.toHaveBeenCalledWith('videoId', 60);
|
||||
});
|
||||
|
||||
it('in Flash mode and video not started', function () {
|
||||
it('in Flash mode and video not started', function() {
|
||||
state.isFlashMode.and.returnValue(true);
|
||||
state.isHtml5Mode.and.returnValue(false);
|
||||
state.videoPlayer.isPlaying.and.returnValue(false);
|
||||
@@ -964,13 +964,13 @@ function (VideoPlayer) {
|
||||
.toHaveBeenCalledWith('videoId', 60);
|
||||
});
|
||||
|
||||
it('in HTML5 mode', function () {
|
||||
it('in HTML5 mode', function() {
|
||||
state.isYoutubeType.and.returnValue(false);
|
||||
VideoPlayer.prototype.setPlaybackRate.call(state, '0.75');
|
||||
expect(state.videoPlayer.player.setPlaybackRate).toHaveBeenCalledWith('0.75');
|
||||
});
|
||||
|
||||
it('Youtube video in FF, with new speed equal 1.0', function () {
|
||||
it('Youtube video in FF, with new speed equal 1.0', function() {
|
||||
state.browserIsFirefox = true;
|
||||
|
||||
state.videoPlayer.isPlaying.and.returnValue(false);
|
||||
@@ -982,5 +982,4 @@ function (VideoPlayer) {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
(function (WAIT_TIMEOUT) {
|
||||
(function(WAIT_TIMEOUT) {
|
||||
'use strict';
|
||||
describe('VideoPoster', function () {
|
||||
describe('VideoPoster', function() {
|
||||
var state, oldOTBD;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine
|
||||
.createSpy('onTouchBasedDevice').and.returnValue(null);
|
||||
state = jasmine.initializePlayer('video_with_bumper.html');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
state.storage.clear();
|
||||
if (state.bumperState && state.bumperState.videoPlayer) {
|
||||
@@ -22,19 +22,19 @@
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
});
|
||||
|
||||
it('can render the poster', function () {
|
||||
it('can render the poster', function() {
|
||||
expect($('.poster')).toExist();
|
||||
expect($('.btn-play')).toExist();
|
||||
});
|
||||
|
||||
it('can start playing the video on click', function (done) {
|
||||
it('can start playing the video on click', function(done) {
|
||||
$('.btn-play').click();
|
||||
jasmine.waitUntil(function() {
|
||||
return state.el.hasClass('is-playing');
|
||||
}).done(done);
|
||||
});
|
||||
|
||||
it('destroy itself on "play" event', function () {
|
||||
it('destroy itself on "play" event', function() {
|
||||
$('.btn-play').click();
|
||||
expect($('.poster')).not.toExist();
|
||||
});
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
(function (undefined) {
|
||||
describe('VideoProgressSlider', function () {
|
||||
(function(undefined) {
|
||||
describe('VideoProgressSlider', function() {
|
||||
var state, oldOTBD;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice')
|
||||
.and.returnValue(null);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
});
|
||||
|
||||
describe('constructor', function () {
|
||||
describe('on a non-touch based device', function () {
|
||||
beforeEach(function () {
|
||||
describe('constructor', function() {
|
||||
describe('on a non-touch based device', function() {
|
||||
beforeEach(function() {
|
||||
spyOn($.fn, 'slider').and.callThrough();
|
||||
|
||||
state = jasmine.initializePlayer();
|
||||
});
|
||||
|
||||
it('build the slider', function () {
|
||||
it('build the slider', function() {
|
||||
expect($('.slider')).toContain(state.videoProgressSlider.slider);
|
||||
expect($.fn.slider).toHaveBeenCalledWith({
|
||||
range: 'min',
|
||||
@@ -34,12 +34,12 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('build the seek handle', function () {
|
||||
it('build the seek handle', function() {
|
||||
expect($('.ui-slider-handle'))
|
||||
.toContain(state.videoProgressSlider.handle);
|
||||
});
|
||||
|
||||
it('add ARIA attributes to time control', function () {
|
||||
it('add ARIA attributes to time control', function() {
|
||||
var timeControl = $('div.slider > .progress-handle');
|
||||
|
||||
expect(timeControl).toHaveAttrs({
|
||||
@@ -52,9 +52,8 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('on a touch-based device', function () {
|
||||
it('does not build the slider on iPhone', function () {
|
||||
|
||||
describe('on a touch-based device', function() {
|
||||
it('does not build the slider on iPhone', function() {
|
||||
window.onTouchBasedDevice.and.returnValue(['iPhone']);
|
||||
|
||||
state = jasmine.initializePlayer();
|
||||
@@ -64,8 +63,8 @@
|
||||
// We can't expect $.fn.slider not to have been called,
|
||||
// because sliders are used in other parts of Video.
|
||||
});
|
||||
$.each(['iPad', 'Android'], function (index, device) {
|
||||
it('build the slider on ' + device, function () {
|
||||
$.each(['iPad', 'Android'], function(index, device) {
|
||||
it('build the slider on ' + device, function() {
|
||||
window.onTouchBasedDevice.and.returnValue([device]);
|
||||
|
||||
state = jasmine.initializePlayer();
|
||||
@@ -76,21 +75,21 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('play', function () {
|
||||
beforeEach(function () {
|
||||
describe('play', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
});
|
||||
|
||||
describe('when the slider was already built', function () {
|
||||
describe('when the slider was already built', function() {
|
||||
var spy;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
spy = spyOn(state.videoProgressSlider, 'buildSlider');
|
||||
spy.and.callThrough();
|
||||
state.videoPlayer.play();
|
||||
});
|
||||
|
||||
it('does not build the slider', function () {
|
||||
it('does not build the slider', function() {
|
||||
expect(spy.calls.count()).toEqual(0);
|
||||
});
|
||||
});
|
||||
@@ -98,25 +97,25 @@
|
||||
// Currently, the slider is not rebuilt if it does not exist.
|
||||
});
|
||||
|
||||
describe('updatePlayTime', function () {
|
||||
beforeEach(function () {
|
||||
describe('updatePlayTime', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
});
|
||||
|
||||
describe('when frozen', function () {
|
||||
beforeEach(function () {
|
||||
describe('when frozen', function() {
|
||||
beforeEach(function() {
|
||||
spyOn($.fn, 'slider').and.callThrough();
|
||||
state.videoProgressSlider.frozen = true;
|
||||
state.videoProgressSlider.updatePlayTime(20, 120);
|
||||
});
|
||||
|
||||
it('does not update the slider', function () {
|
||||
it('does not update the slider', function() {
|
||||
expect($.fn.slider).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when not frozen', function () {
|
||||
beforeEach(function () {
|
||||
describe('when not frozen', function() {
|
||||
beforeEach(function() {
|
||||
spyOn($.fn, 'slider').and.callThrough();
|
||||
state.videoProgressSlider.frozen = false;
|
||||
state.videoProgressSlider.updatePlayTime({
|
||||
@@ -125,27 +124,27 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('update the max value of the slider', function () {
|
||||
it('update the max value of the slider', function() {
|
||||
expect($.fn.slider).toHaveBeenCalledWith(
|
||||
'option', 'max', 120
|
||||
);
|
||||
});
|
||||
|
||||
it('update current value of the slider', function () {
|
||||
it('update current value of the slider', function() {
|
||||
expect($.fn.slider).toHaveBeenCalledWith(
|
||||
'option', 'value', 20
|
||||
);
|
||||
});
|
||||
|
||||
it('required aria values updated', function () {
|
||||
it('required aria values updated', function() {
|
||||
expect(state.videoProgressSlider.handle.attr('aria-valuenow')).toBe('20');
|
||||
expect(state.videoProgressSlider.handle.attr('aria-valuemax')).toBe('120');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSlide', function () {
|
||||
beforeEach(function () {
|
||||
describe('onSlide', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
spyOn($.fn, 'slider').and.callThrough();
|
||||
@@ -153,27 +152,26 @@
|
||||
});
|
||||
|
||||
// Disabled 12/30/13 due to flakiness in master
|
||||
xit('freeze the slider', function () {
|
||||
xit('freeze the slider', function() {
|
||||
state.videoProgressSlider.onSlide(
|
||||
jQuery.Event('slide'), { value: 20 }
|
||||
jQuery.Event('slide'), {value: 20}
|
||||
);
|
||||
|
||||
expect(state.videoProgressSlider.frozen).toBeTruthy();
|
||||
});
|
||||
|
||||
// Disabled 12/30/13 due to flakiness in master
|
||||
xit('trigger seek event', function () {
|
||||
xit('trigger seek event', function() {
|
||||
state.videoProgressSlider.onSlide(
|
||||
jQuery.Event('slide'), { value: 20 }
|
||||
jQuery.Event('slide'), {value: 20}
|
||||
);
|
||||
|
||||
expect(state.videoPlayer.onSlideSeek).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onStop', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
describe('onStop', function() {
|
||||
beforeEach(function() {
|
||||
jasmine.clock().install();
|
||||
|
||||
state = jasmine.initializePlayer();
|
||||
@@ -181,32 +179,32 @@
|
||||
spyOn(state.videoPlayer, 'onSlideSeek').and.callThrough();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
|
||||
// Disabled 12/30/13 due to flakiness in master
|
||||
xit('freeze the slider', function () {
|
||||
xit('freeze the slider', function() {
|
||||
state.videoProgressSlider.onStop(
|
||||
jQuery.Event('stop'), { value: 20 }
|
||||
jQuery.Event('stop'), {value: 20}
|
||||
);
|
||||
|
||||
expect(state.videoProgressSlider.frozen).toBeTruthy();
|
||||
});
|
||||
|
||||
// Disabled 12/30/13 due to flakiness in master
|
||||
xit('trigger seek event', function () {
|
||||
xit('trigger seek event', function() {
|
||||
state.videoProgressSlider.onStop(
|
||||
jQuery.Event('stop'), { value: 20 }
|
||||
jQuery.Event('stop'), {value: 20}
|
||||
);
|
||||
|
||||
expect(state.videoPlayer.onSlideSeek).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Disabled 12/30/13 due to flakiness in master
|
||||
xit('set timeout to unfreeze the slider', function () {
|
||||
xit('set timeout to unfreeze the slider', function() {
|
||||
state.videoProgressSlider.onStop(
|
||||
jQuery.Event('stop'), { value: 20 }
|
||||
jQuery.Event('stop'), {value: 20}
|
||||
);
|
||||
|
||||
jasmine.clock().tick(200);
|
||||
@@ -215,31 +213,31 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('getRangeParams' , function () {
|
||||
it('getRangeParams', function() {
|
||||
var testCases = [
|
||||
{
|
||||
startTime: 10,
|
||||
endTime: 20,
|
||||
duration: 150
|
||||
},
|
||||
{
|
||||
startTime: 90,
|
||||
endTime: 100,
|
||||
duration: 100
|
||||
},
|
||||
{
|
||||
startTime: 0,
|
||||
endTime: 200,
|
||||
duration: 200
|
||||
}
|
||||
];
|
||||
{
|
||||
startTime: 10,
|
||||
endTime: 20,
|
||||
duration: 150
|
||||
},
|
||||
{
|
||||
startTime: 90,
|
||||
endTime: 100,
|
||||
duration: 100
|
||||
},
|
||||
{
|
||||
startTime: 0,
|
||||
endTime: 200,
|
||||
duration: 200
|
||||
}
|
||||
];
|
||||
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
$.each(testCases, function (index, testCase) {
|
||||
var step = 100/testCase.duration,
|
||||
left = testCase.startTime*step,
|
||||
width = testCase.endTime*step - left,
|
||||
$.each(testCases, function(index, testCase) {
|
||||
var step = 100 / testCase.duration,
|
||||
left = testCase.startTime * step,
|
||||
width = testCase.endTime * step - left,
|
||||
expectedParams = {
|
||||
left: left + '%',
|
||||
width: width + '%'
|
||||
@@ -252,8 +250,8 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('notifyThroughHandleEnd', function () {
|
||||
beforeEach(function () {
|
||||
describe('notifyThroughHandleEnd', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
spyOnEvent(state.videoProgressSlider.handle, 'focus');
|
||||
@@ -261,7 +259,7 @@
|
||||
.and.callThrough();
|
||||
});
|
||||
|
||||
it('params.end = true', function () {
|
||||
it('params.end = true', function() {
|
||||
state.videoProgressSlider.notifyThroughHandleEnd({end: true});
|
||||
|
||||
expect(state.videoProgressSlider.handle.attr('title'))
|
||||
@@ -272,7 +270,7 @@
|
||||
);
|
||||
});
|
||||
|
||||
it('params.end = false', function () {
|
||||
it('params.end = false', function() {
|
||||
state.videoProgressSlider.notifyThroughHandleEnd({end: false});
|
||||
|
||||
expect(state.videoProgressSlider.handle.attr('title'))
|
||||
@@ -283,18 +281,17 @@
|
||||
);
|
||||
});
|
||||
|
||||
it('is called when video plays', function (done) {
|
||||
it('is called when video plays', function(done) {
|
||||
state.videoPlayer.play();
|
||||
jasmine.waitUntil(function() {
|
||||
return state.videoPlayer.isPlaying();
|
||||
}).done(function() {
|
||||
expect(state.videoProgressSlider.notifyThroughHandleEnd).toHaveBeenCalledWith({end: false});
|
||||
}).always(done);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('getTimeDescription', function () {
|
||||
it('getTimeDescription', function() {
|
||||
var cases = {
|
||||
'0': '0 seconds',
|
||||
'1': '1 second',
|
||||
@@ -304,7 +301,7 @@
|
||||
'121': '2 minutes 1 second',
|
||||
|
||||
'3670': '1 hour 1 minute 10 seconds',
|
||||
'21541': '5 hours 59 minutes 1 second',
|
||||
'21541': '5 hours 59 minutes 1 second'
|
||||
},
|
||||
getTimeDescription;
|
||||
|
||||
@@ -317,13 +314,11 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can destroy itself', function () {
|
||||
it('can destroy itself', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
state.videoProgressSlider.destroy();
|
||||
expect(state.videoProgressSlider).toBeUndefined();
|
||||
expect($('.slider')).toBeEmpty();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}).call(this);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(function (undefined) {
|
||||
describe('VideoQualityControl', function () {
|
||||
(function(undefined) {
|
||||
describe('VideoQualityControl', function() {
|
||||
var state, qualityControl, videoPlayer, player;
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
if (state.storage) {
|
||||
state.storage.clear();
|
||||
@@ -10,34 +10,34 @@
|
||||
state.videoPlayer.destroy();
|
||||
});
|
||||
|
||||
describe('constructor, YouTube mode', function () {
|
||||
beforeEach(function () {
|
||||
state = jasmine.initializePlayerYouTube();
|
||||
describe('constructor, YouTube mode', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayerYouTube();
|
||||
qualityControl = state.videoQualityControl;
|
||||
videoPlayer = state.videoPlayer;
|
||||
player = videoPlayer.player;
|
||||
|
||||
// Define empty methods in YouTube stub
|
||||
player.quality = 'large';
|
||||
player.setPlaybackQuality.and.callFake(function (quality){
|
||||
player.setPlaybackQuality.and.callFake(function(quality) {
|
||||
player.quality = quality;
|
||||
});
|
||||
});
|
||||
|
||||
it('contains the quality control and is initially hidden',
|
||||
function () {
|
||||
expect(qualityControl.el).toHaveClass(
|
||||
function() {
|
||||
expect(qualityControl.el).toHaveClass(
|
||||
'quality-control is-hidden'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('add ARIA attributes to quality control', function () {
|
||||
it('add ARIA attributes to quality control', function() {
|
||||
expect(qualityControl.el).toHaveAttrs({
|
||||
'aria-disabled': 'false'
|
||||
});
|
||||
});
|
||||
|
||||
it('bind the quality control', function () {
|
||||
it('bind the quality control', function() {
|
||||
expect(qualityControl.el).toHandleWith('click',
|
||||
qualityControl.toggleQuality
|
||||
);
|
||||
@@ -45,7 +45,7 @@
|
||||
expect(state.el).toHandle('play');
|
||||
});
|
||||
|
||||
it('calls fetchAvailableQualities only once', function () {
|
||||
it('calls fetchAvailableQualities only once', function() {
|
||||
expect(player.getAvailableQualityLevels.calls.count())
|
||||
.toEqual(0);
|
||||
|
||||
@@ -56,30 +56,30 @@
|
||||
.toEqual(1);
|
||||
});
|
||||
|
||||
it('initializes with a quality equal to large', function () {
|
||||
it('initializes with a quality equal to large', function() {
|
||||
videoPlayer.onPlay();
|
||||
|
||||
expect(player.setPlaybackQuality).toHaveBeenCalledWith('large');
|
||||
});
|
||||
|
||||
it('shows the quality control on play if HD is available',
|
||||
function () {
|
||||
videoPlayer.onPlay();
|
||||
function() {
|
||||
videoPlayer.onPlay();
|
||||
|
||||
expect(qualityControl.el).not.toHaveClass('is-hidden');
|
||||
});
|
||||
expect(qualityControl.el).not.toHaveClass('is-hidden');
|
||||
});
|
||||
|
||||
it('leaves quality control hidden on play if HD is not available',
|
||||
function () {
|
||||
player.getAvailableQualityLevels.and.returnValue(
|
||||
function() {
|
||||
player.getAvailableQualityLevels.and.returnValue(
|
||||
['large', 'medium', 'small']
|
||||
);
|
||||
|
||||
videoPlayer.onPlay();
|
||||
expect(qualityControl.el).toHaveClass('is-hidden');
|
||||
});
|
||||
videoPlayer.onPlay();
|
||||
expect(qualityControl.el).toHaveClass('is-hidden');
|
||||
});
|
||||
|
||||
it('switch to HD if it is available', function () {
|
||||
it('switch to HD if it is available', function() {
|
||||
videoPlayer.onPlay();
|
||||
|
||||
qualityControl.quality = 'large';
|
||||
@@ -93,27 +93,27 @@
|
||||
});
|
||||
|
||||
it('quality control is active if HD is available',
|
||||
function () {
|
||||
player.getAvailableQualityLevels.and.returnValue(
|
||||
function() {
|
||||
player.getAvailableQualityLevels.and.returnValue(
|
||||
['highres', 'hd1080', 'hd720']
|
||||
);
|
||||
|
||||
qualityControl.quality = 'highres';
|
||||
qualityControl.quality = 'highres';
|
||||
|
||||
videoPlayer.onPlay();
|
||||
expect(qualityControl.el).toHaveClass('active');
|
||||
});
|
||||
videoPlayer.onPlay();
|
||||
expect(qualityControl.el).toHaveClass('active');
|
||||
});
|
||||
|
||||
it('can destroy itself', function () {
|
||||
it('can destroy itself', function() {
|
||||
state.videoQualityControl.destroy();
|
||||
expect(state.videoQualityControl).toBeUndefined();
|
||||
expect($('.quality-control')).not.toExist();
|
||||
});
|
||||
});
|
||||
|
||||
describe('constructor, HTML5 mode', function () {
|
||||
it('does not contain the quality control', function () {
|
||||
state = jasmine.initializePlayer();
|
||||
describe('constructor, HTML5 mode', function() {
|
||||
it('does not contain the quality control', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
expect(state.el.find('.quality-control').length).toBe(0);
|
||||
});
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(function (undefined) {
|
||||
(function(undefined) {
|
||||
'use strict';
|
||||
describe('VideoPlayer Save State plugin', function () {
|
||||
describe('VideoPlayer Save State plugin', function() {
|
||||
var state, oldOTBD;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine
|
||||
.createSpy('onTouchBasedDevice')
|
||||
@@ -15,8 +15,7 @@
|
||||
spyOn(state.storage, 'setItem');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
state.storage.clear();
|
||||
@@ -25,7 +24,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
describe('saveState function', function () {
|
||||
describe('saveState function', function() {
|
||||
var videoPlayerCurrentTime, newCurrentTime, speed;
|
||||
|
||||
// We make sure that `currentTime` is a float. We need to test
|
||||
@@ -41,12 +40,12 @@
|
||||
newCurrentTime = 5.4;
|
||||
speed = '0.75';
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
state.videoPlayer.currentTime = videoPlayerCurrentTime;
|
||||
spyOn(window.Time, 'formatFull').and.callThrough();
|
||||
});
|
||||
|
||||
it('data is not an object, async is true', function () {
|
||||
it('data is not an object, async is true', function() {
|
||||
itSpec({
|
||||
asyncVal: true,
|
||||
speedVal: undefined,
|
||||
@@ -58,7 +57,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('data contains speed, async is false', function () {
|
||||
it('data contains speed, async is false', function() {
|
||||
itSpec({
|
||||
asyncVal: false,
|
||||
speedVal: speed,
|
||||
@@ -72,7 +71,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('data contains float position, async is true', function () {
|
||||
it('data contains float position, async is true', function() {
|
||||
itSpec({
|
||||
asyncVal: true,
|
||||
speedVal: undefined,
|
||||
@@ -86,7 +85,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('data contains speed and rounded position, async is false', function () {
|
||||
it('data contains speed and rounded position, async is false', function() {
|
||||
itSpec({
|
||||
asyncVal: false,
|
||||
speedVal: speed,
|
||||
@@ -102,7 +101,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('data contains empty object, async is true', function () {
|
||||
it('data contains empty object, async is true', function() {
|
||||
itSpec({
|
||||
asyncVal: true,
|
||||
speedVal: undefined,
|
||||
@@ -112,7 +111,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('data contains position 0, async is true', function () {
|
||||
it('data contains position 0, async is true', function() {
|
||||
itSpec({
|
||||
asyncVal: true,
|
||||
speedVal: undefined,
|
||||
@@ -127,11 +126,11 @@
|
||||
});
|
||||
|
||||
function itSpec(value) {
|
||||
var asyncVal = value.asyncVal,
|
||||
speedVal = value.speedVal,
|
||||
var asyncVal = value.asyncVal,
|
||||
speedVal = value.speedVal,
|
||||
positionVal = value.positionVal,
|
||||
data = value.data,
|
||||
ajaxData = value.ajaxData;
|
||||
data = value.data,
|
||||
ajaxData = value.ajaxData;
|
||||
|
||||
state.videoSaveStatePlugin.saveState(asyncVal, data);
|
||||
|
||||
@@ -162,7 +161,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
it('can save state on speed change', function () {
|
||||
it('can save state on speed change', function() {
|
||||
state.el.trigger('speedchange', ['2.0']);
|
||||
expect($.ajax).toHaveBeenCalledWith({
|
||||
url: state.config.saveStateUrl,
|
||||
@@ -173,7 +172,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can save state on page unload', function () {
|
||||
it('can save state on page unload', function() {
|
||||
$.ajax.calls.reset();
|
||||
state.videoSaveStatePlugin.onUnload();
|
||||
expect($.ajax).toHaveBeenCalledWith({
|
||||
@@ -185,7 +184,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can save state on pause', function () {
|
||||
it('can save state on pause', function() {
|
||||
state.el.trigger('pause');
|
||||
expect($.ajax).toHaveBeenCalledWith({
|
||||
url: state.config.saveStateUrl,
|
||||
@@ -196,12 +195,12 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can save state on language change', function () {
|
||||
it('can save state on language change', function() {
|
||||
state.el.trigger('language_menu:change', ['ua']);
|
||||
expect(state.storage.setItem).toHaveBeenCalledWith('language', 'ua');
|
||||
});
|
||||
|
||||
it('can save youtube availability', function () {
|
||||
it('can save youtube availability', function() {
|
||||
$.ajax.calls.reset();
|
||||
|
||||
// Test the cases where we shouldn't send anything at all -- client
|
||||
@@ -236,7 +235,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can destroy itself', function () {
|
||||
it('can destroy itself', function() {
|
||||
var plugin = state.videoSaveStatePlugin;
|
||||
spyOn($.fn, 'off').and.callThrough();
|
||||
state.videoSaveStatePlugin.destroy();
|
||||
@@ -252,5 +251,4 @@
|
||||
expect($.fn.off).toHaveBeenCalledWith('unload', plugin.onUnload);
|
||||
});
|
||||
});
|
||||
|
||||
}).call(this);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(function () {
|
||||
(function() {
|
||||
'use strict';
|
||||
describe('VideoSkipControl', function () {
|
||||
describe('VideoSkipControl', function() {
|
||||
var state, oldOTBD;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine
|
||||
.createSpy('onTouchBasedDevice').and.returnValue(null);
|
||||
@@ -12,7 +12,7 @@
|
||||
spyOn(state.bumperState.videoCommands, 'execute').and.callThrough();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
state.storage.clear();
|
||||
if (state.bumperState && state.bumperState.videoPlayer) {
|
||||
@@ -24,13 +24,13 @@
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
});
|
||||
|
||||
it('can render the control when video starts playing', function () {
|
||||
it('can render the control when video starts playing', function() {
|
||||
expect($('.skip-control')).not.toExist();
|
||||
state.el.trigger('play');
|
||||
expect($('.skip-control')).toExist();
|
||||
});
|
||||
|
||||
it('can skip the video on click', function () {
|
||||
it('can skip the video on click', function() {
|
||||
spyOn(state.bumperState.videoBumper, 'skipAndDoNotShowAgain');
|
||||
state.el.trigger('play');
|
||||
$('.skip-control').click();
|
||||
@@ -38,7 +38,7 @@
|
||||
expect(state.bumperState.videoBumper.skipAndDoNotShowAgain).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('can destroy itself', function () {
|
||||
it('can destroy itself', function() {
|
||||
state.bumperState.videoPlaySkipControl.destroy();
|
||||
expect(state.bumperState.videoPlaySkipControl).toBeUndefined();
|
||||
});
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
(function (undefined) {
|
||||
(function(undefined) {
|
||||
'use strict';
|
||||
describe('VideoSpeedControl', function () {
|
||||
describe('VideoSpeedControl', function() {
|
||||
var state, oldOTBD;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice')
|
||||
.and.returnValue(null);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
});
|
||||
|
||||
describe('constructor', function () {
|
||||
describe('always', function () {
|
||||
beforeEach(function () {
|
||||
describe('constructor', function() {
|
||||
describe('always', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
});
|
||||
|
||||
it('add the video speed control to player', function () {
|
||||
it('add the video speed control to player', function() {
|
||||
var secondaryControls = $('.secondary-controls'),
|
||||
li = secondaryControls.find('.video-speeds li');
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
);
|
||||
expect(li.length).toBe(state.speeds.length);
|
||||
|
||||
$.each(li.toArray().reverse(), function (index, link) {
|
||||
$.each(li.toArray().reverse(), function(index, link) {
|
||||
expect($(link).attr('data-speed')).toEqual(state.speeds[index]);
|
||||
expect($(link).find('.speed-option').text()).toBe(
|
||||
state.speeds[index] + 'x'
|
||||
@@ -44,9 +44,9 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('when running on touch based device', function () {
|
||||
$.each(['iPad', 'Android'], function (index, device) {
|
||||
it('is not rendered on' + device, function () {
|
||||
describe('when running on touch based device', function() {
|
||||
$.each(['iPad', 'Android'], function(index, device) {
|
||||
it('is not rendered on' + device, function() {
|
||||
window.onTouchBasedDevice.and.returnValue([device]);
|
||||
state = jasmine.initializePlayer();
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('when running on non-touch based device', function () {
|
||||
describe('when running on non-touch based device', function() {
|
||||
var speedControl, speedEntries, speedButton, speedsContainer,
|
||||
KEY = $.ui.keyCode,
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
return $.Event('keydown', {keyCode: key});
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
speedControl = $('.speeds');
|
||||
speedButton = $('.speed-button');
|
||||
@@ -72,67 +72,67 @@
|
||||
});
|
||||
|
||||
it('open/close the speed menu on mouseenter/mouseleave',
|
||||
function () {
|
||||
speedControl.mouseenter();
|
||||
expect(speedControl).toHaveClass('is-opened');
|
||||
speedControl.mouseleave();
|
||||
expect(speedControl).not.toHaveClass('is-opened');
|
||||
});
|
||||
function() {
|
||||
speedControl.mouseenter();
|
||||
expect(speedControl).toHaveClass('is-opened');
|
||||
speedControl.mouseleave();
|
||||
expect(speedControl).not.toHaveClass('is-opened');
|
||||
});
|
||||
|
||||
it('do not close the speed menu on mouseleave if a speed ' +
|
||||
'entry has focus', function () {
|
||||
'entry has focus', function() {
|
||||
// Open speed meenu. Focus is on last speed entry.
|
||||
speedControl.trigger(keyPressEvent(KEY.ENTER));
|
||||
speedControl.mouseenter().mouseleave();
|
||||
expect(speedControl).toHaveClass('is-opened');
|
||||
});
|
||||
|
||||
it('close the speed menu on outside click', function () {
|
||||
it('close the speed menu on outside click', function() {
|
||||
speedControl.trigger(keyPressEvent(KEY.ENTER));
|
||||
$(window).click();
|
||||
expect(speedControl).not.toHaveClass('is-opened');
|
||||
});
|
||||
|
||||
it('open the speed menu on ENTER keydown', function () {
|
||||
it('open the speed menu on ENTER keydown', function() {
|
||||
speedControl.trigger(keyPressEvent(KEY.ENTER));
|
||||
expect(speedControl).toHaveClass('is-opened');
|
||||
expect(speedEntries.last()).toBeFocused();
|
||||
});
|
||||
|
||||
it('open the speed menu on SPACE keydown', function () {
|
||||
it('open the speed menu on SPACE keydown', function() {
|
||||
speedControl.trigger(keyPressEvent(KEY.SPACE));
|
||||
expect(speedControl).toHaveClass('is-opened');
|
||||
expect(speedEntries.last()).toBeFocused();
|
||||
});
|
||||
|
||||
it('open the speed menu on UP keydown', function () {
|
||||
it('open the speed menu on UP keydown', function() {
|
||||
speedControl.trigger(keyPressEvent(KEY.UP));
|
||||
expect(speedControl).toHaveClass('is-opened');
|
||||
expect(speedEntries.last()).toBeFocused();
|
||||
});
|
||||
|
||||
it('close the speed menu on ESCAPE keydown', function () {
|
||||
it('close the speed menu on ESCAPE keydown', function() {
|
||||
speedControl.trigger(keyPressEvent(KEY.ESCAPE));
|
||||
expect(speedControl).not.toHaveClass('is-opened');
|
||||
});
|
||||
|
||||
it('UP and DOWN keydown function as expected on speed entries',
|
||||
function () {
|
||||
var speed_0_75 = speedEntries.filter(':contains("0.75x")'),
|
||||
speed_1_0 = speedEntries.filter(':contains("1.0x")');
|
||||
function() {
|
||||
var speed_0_75 = speedEntries.filter(':contains("0.75x")'),
|
||||
speed_1_0 = speedEntries.filter(':contains("1.0x")');
|
||||
|
||||
// First open menu
|
||||
speedControl.trigger(keyPressEvent(KEY.UP));
|
||||
expect(speed_0_75).toBeFocused();
|
||||
speedControl.trigger(keyPressEvent(KEY.UP));
|
||||
expect(speed_0_75).toBeFocused();
|
||||
|
||||
speed_0_75.trigger(keyPressEvent(KEY.UP));
|
||||
expect(speed_1_0).toBeFocused();
|
||||
speed_0_75.trigger(keyPressEvent(KEY.UP));
|
||||
expect(speed_1_0).toBeFocused();
|
||||
|
||||
speed_1_0.trigger(keyPressEvent(KEY.DOWN));
|
||||
expect(speed_0_75).toBeFocused();
|
||||
});
|
||||
speed_1_0.trigger(keyPressEvent(KEY.DOWN));
|
||||
expect(speed_0_75).toBeFocused();
|
||||
});
|
||||
|
||||
it('ESC keydown on speed entry closes menu', function () {
|
||||
it('ESC keydown on speed entry closes menu', function() {
|
||||
// First open menu. Focus is on last speed entry.
|
||||
speedControl.trigger(keyPressEvent(KEY.UP));
|
||||
speedEntries.last().trigger(keyPressEvent(KEY.ESCAPE));
|
||||
@@ -144,53 +144,53 @@
|
||||
});
|
||||
|
||||
it('ENTER keydown on speed entry selects speed and closes menu',
|
||||
function () {
|
||||
function() {
|
||||
// First open menu.
|
||||
speedControl.trigger(keyPressEvent(KEY.UP));
|
||||
speedControl.trigger(keyPressEvent(KEY.UP));
|
||||
// Focus on 1.50x speed
|
||||
speedEntries.eq(0).focus();
|
||||
speedEntries.eq(0).trigger(keyPressEvent(KEY.ENTER));
|
||||
speedEntries.eq(0).focus();
|
||||
speedEntries.eq(0).trigger(keyPressEvent(KEY.ENTER));
|
||||
|
||||
// Menu is closed, focus has been returned to speed
|
||||
// control and video speed is 1.50x.
|
||||
expect(speedButton).toBeFocused();
|
||||
expect($('.video-speeds li[data-speed="1.50"]'))
|
||||
expect(speedButton).toBeFocused();
|
||||
expect($('.video-speeds li[data-speed="1.50"]'))
|
||||
.toHaveClass('is-active');
|
||||
expect($('.speeds .value')).toHaveHtml('1.50x');
|
||||
});
|
||||
expect($('.speeds .value')).toHaveHtml('1.50x');
|
||||
});
|
||||
|
||||
it('SPACE keydown on speed entry selects speed and closes menu',
|
||||
function () {
|
||||
function() {
|
||||
// First open menu.
|
||||
speedControl.trigger(keyPressEvent(KEY.UP));
|
||||
speedControl.trigger(keyPressEvent(KEY.UP));
|
||||
// Focus on 1.50x speed
|
||||
speedEntries.eq(0).focus();
|
||||
speedEntries.eq(0).trigger(keyPressEvent(KEY.SPACE));
|
||||
speedEntries.eq(0).focus();
|
||||
speedEntries.eq(0).trigger(keyPressEvent(KEY.SPACE));
|
||||
|
||||
// Menu is closed, focus has been returned to speed
|
||||
// control and video speed is 1.50x.
|
||||
expect(speedButton).toBeFocused();
|
||||
expect($('.video-speeds li[data-speed="1.50"]'))
|
||||
expect(speedButton).toBeFocused();
|
||||
expect($('.video-speeds li[data-speed="1.50"]'))
|
||||
.toHaveClass('is-active');
|
||||
expect($('.speeds .value')).toHaveHtml('1.50x');
|
||||
});
|
||||
expect($('.speeds .value')).toHaveHtml('1.50x');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('changeVideoSpeed', function () {
|
||||
describe('changeVideoSpeed', function() {
|
||||
// This is an unnecessary test. The internal browser API, and
|
||||
// YouTube API detect (and do not do anything) if there is a
|
||||
// request for a speed that is already set.
|
||||
//
|
||||
// describe("when new speed is the same") ...
|
||||
|
||||
describe('when new speed is not the same', function () {
|
||||
beforeEach(function () {
|
||||
describe('when new speed is not the same', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
state.videoSpeedControl.setSpeed(1.0);
|
||||
});
|
||||
|
||||
it('trigger speedChange event', function () {
|
||||
it('trigger speedChange event', function() {
|
||||
spyOnEvent(state.el, 'speedchange');
|
||||
|
||||
$('li[data-speed="0.75"] .speed-option').click();
|
||||
@@ -200,14 +200,14 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSpeedChange', function () {
|
||||
beforeEach(function () {
|
||||
describe('onSpeedChange', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
$('li[data-speed="1.0"]').addClass('is-active').attr('aria-pressed', 'true');
|
||||
state.videoSpeedControl.setSpeed(0.75);
|
||||
});
|
||||
|
||||
it('set the new speed as active', function () {
|
||||
it('set the new speed as active', function() {
|
||||
expect($('li[data-speed="1.0"]')).not.toHaveClass('is-active');
|
||||
expect($('li[data-speed="1.0"] .speed-option').attr('aria-pressed')).not.toEqual('true');
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
it('can destroy itself', function () {
|
||||
it('can destroy itself', function() {
|
||||
state = jasmine.initializePlayer();
|
||||
state.videoSpeedControl.destroy();
|
||||
expect(state.videoSpeedControl).toBeUndefined();
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
(function (requirejs, require, define, undefined) {
|
||||
require(
|
||||
(function(requirejs, require, define, undefined) {
|
||||
require(
|
||||
['video/00_video_storage.js'],
|
||||
function (VideoStorage) {
|
||||
describe('VideoStorage', function () {
|
||||
function(VideoStorage) {
|
||||
describe('VideoStorage', function() {
|
||||
var namespace = 'test_storage',
|
||||
id = 'video_id';
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
VideoStorage(namespace, id).clear();
|
||||
});
|
||||
|
||||
describe('initialize', function () {
|
||||
it('with namespace and id', function () {
|
||||
describe('initialize', function() {
|
||||
it('with namespace and id', function() {
|
||||
var storage = VideoStorage(namespace, id);
|
||||
|
||||
expect(window[namespace]).toBeDefined();
|
||||
expect(window[namespace][id]).toBeDefined();
|
||||
});
|
||||
|
||||
it('without namespace and id', function () {
|
||||
it('without namespace and id', function() {
|
||||
spyOn(Number.prototype, 'toString').and.returnValue('0.abcdedg');
|
||||
var storage = VideoStorage();
|
||||
|
||||
@@ -27,10 +27,10 @@ function (VideoStorage) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('methods: ', function () {
|
||||
describe('methods: ', function() {
|
||||
var data, storage;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
data = {
|
||||
item_2: 'value_2'
|
||||
};
|
||||
@@ -42,7 +42,7 @@ function (VideoStorage) {
|
||||
storage = VideoStorage(namespace, id);
|
||||
});
|
||||
|
||||
it('setItem', function () {
|
||||
it('setItem', function() {
|
||||
var expected = $.extend(true, {}, data, {item_4: 'value_4'});
|
||||
|
||||
expected[id]['item_3'] = 'value_3';
|
||||
@@ -51,7 +51,7 @@ function (VideoStorage) {
|
||||
expect(window[namespace]).toEqual(expected);
|
||||
});
|
||||
|
||||
it('getItem', function () {
|
||||
it('getItem', function() {
|
||||
var data = window[namespace],
|
||||
getItem = storage.getItem;
|
||||
|
||||
@@ -60,7 +60,7 @@ function (VideoStorage) {
|
||||
expect(getItem('item_3')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('removeItem', function () {
|
||||
it('removeItem', function() {
|
||||
var data = window[namespace],
|
||||
removeItem = storage.removeItem;
|
||||
|
||||
@@ -70,7 +70,7 @@ function (VideoStorage) {
|
||||
expect(data['item_2']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('clear', function () {
|
||||
it('clear', function() {
|
||||
var expected = {};
|
||||
|
||||
expected[id] = {};
|
||||
|
||||
@@ -1,328 +1,325 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
describe('VideoVolumeControl', function () {
|
||||
var state, oldOTBD, volumeControl;
|
||||
(function() {
|
||||
'use strict';
|
||||
describe('VideoVolumeControl', function() {
|
||||
var state, oldOTBD, volumeControl;
|
||||
|
||||
var KEY = $.ui.keyCode,
|
||||
var KEY = $.ui.keyCode,
|
||||
|
||||
keyPressEvent = function(key) {
|
||||
return $.Event('keydown', { keyCode: key });
|
||||
};
|
||||
keyPressEvent = function(key) {
|
||||
return $.Event('keydown', {keyCode: key});
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice')
|
||||
beforeEach(function() {
|
||||
oldOTBD = window.onTouchBasedDevice;
|
||||
window.onTouchBasedDevice = jasmine.createSpy('onTouchBasedDevice')
|
||||
.and.returnValue(null);
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
$('source').remove();
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
});
|
||||
afterEach(function() {
|
||||
$('source').remove();
|
||||
window.onTouchBasedDevice = oldOTBD;
|
||||
state.storage.clear();
|
||||
state.videoPlayer.destroy();
|
||||
});
|
||||
|
||||
it('Volume level has correct value even if cookie is broken', function () {
|
||||
$.cookie.and.returnValue('broken_cookie');
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
expect(volumeControl.volume).toEqual(100);
|
||||
});
|
||||
|
||||
describe('constructor', function () {
|
||||
beforeEach(function () {
|
||||
spyOn($.fn, 'slider').and.callThrough();
|
||||
$.cookie.and.returnValue('75');
|
||||
it('Volume level has correct value even if cookie is broken', function() {
|
||||
$.cookie.and.returnValue('broken_cookie');
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
});
|
||||
|
||||
it('initialize volume to 75%', function () {
|
||||
expect(volumeControl.volume).toEqual(75);
|
||||
});
|
||||
|
||||
it('render the volume control', function () {
|
||||
expect($('.volume')).toExist();
|
||||
});
|
||||
|
||||
it('create the slider', function () {
|
||||
expect($.fn.slider.calls.argsFor(2)).toEqual([{
|
||||
orientation: 'vertical',
|
||||
range: 'min',
|
||||
min: 0,
|
||||
max: 100,
|
||||
slide: jasmine.any(Function)
|
||||
}]);
|
||||
expect($.fn.slider).toHaveBeenCalledWith(
|
||||
'value', volumeControl.volume
|
||||
);
|
||||
});
|
||||
|
||||
it('add ARIA attributes to live region', function () {
|
||||
var liveRegion = $('.video-live-region');
|
||||
|
||||
expect(liveRegion).toHaveAttrs({
|
||||
'aria-live': 'polite'
|
||||
});
|
||||
});
|
||||
|
||||
it('add ARIA attributes to volume control', function () {
|
||||
var button = $('.volume .control');
|
||||
|
||||
expect(button).toHaveAttrs({
|
||||
'aria-disabled': 'false'
|
||||
});
|
||||
});
|
||||
|
||||
it('bind the volume control', function () {
|
||||
var button = $('.volume .control');
|
||||
|
||||
expect(button).toHandle('keydown');
|
||||
expect(button).toHandle('mousedown');
|
||||
expect($('.volume')).not.toHaveClass('is-opened');
|
||||
|
||||
$('.volume').mouseenter();
|
||||
expect($('.volume')).toHaveClass('is-opened');
|
||||
|
||||
$('.volume').mouseleave();
|
||||
expect($('.volume')).not.toHaveClass('is-opened');
|
||||
});
|
||||
});
|
||||
|
||||
describe('setVolume', function () {
|
||||
beforeEach(function () {
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
|
||||
jasmine.addMatchers({
|
||||
assertLiveRegionState: function () {
|
||||
return {
|
||||
compare: function (actual, volume, expectation) {
|
||||
var region = $('.video-live-region');
|
||||
|
||||
var getExpectedText = function (text) {
|
||||
return text + ' Volume.';
|
||||
};
|
||||
|
||||
actual.setVolume(volume, true, true);
|
||||
return {
|
||||
pass: region.text() === getExpectedText(expectation)
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('update is not called, if new volume equals current', function () {
|
||||
volumeControl.volume = 60;
|
||||
spyOn(volumeControl, 'updateSliderView');
|
||||
volumeControl.setVolume(60, false, true);
|
||||
expect(volumeControl.updateSliderView).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('volume is changed on sliding', function () {
|
||||
volumeControl.onSlideHandler(null, {value: 99});
|
||||
expect(volumeControl.volume).toBe(99);
|
||||
});
|
||||
|
||||
describe('when the new volume is more than 0', function () {
|
||||
beforeEach(function () {
|
||||
volumeControl.setVolume(60, false, true);
|
||||
});
|
||||
|
||||
it('set the player volume', function () {
|
||||
expect(volumeControl.volume).toEqual(60);
|
||||
});
|
||||
|
||||
it('remove muted class', function () {
|
||||
expect($('.volume')).not.toHaveClass('is-muted');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the new volume is more than 0, but was 0', function () {
|
||||
it('remove muted class', function () {
|
||||
volumeControl.setVolume(0, false, true);
|
||||
expect($('.volume')).toHaveClass('is-muted');
|
||||
state.el.trigger('volumechange', [20]);
|
||||
expect($('.volume')).not.toHaveClass('is-muted');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the new volume is 0', function () {
|
||||
beforeEach(function () {
|
||||
volumeControl.setVolume(0, false, true);
|
||||
});
|
||||
|
||||
it('set the player volume', function () {
|
||||
expect(volumeControl.volume).toEqual(0);
|
||||
});
|
||||
|
||||
it('add muted class', function () {
|
||||
expect($('.volume')).toHaveClass('is-muted');
|
||||
});
|
||||
});
|
||||
|
||||
it('when the new volume is Muted', function () {
|
||||
expect(volumeControl).assertLiveRegionState(0, 'Muted');
|
||||
});
|
||||
|
||||
it('when the new volume is in ]0,20]', function () {
|
||||
expect(volumeControl).assertLiveRegionState(10, 'Very low');
|
||||
});
|
||||
|
||||
it('when the new volume is in ]20,40]', function () {
|
||||
expect(volumeControl).assertLiveRegionState(30, 'Low');
|
||||
});
|
||||
|
||||
it('when the new volume is in ]40,60]', function () {
|
||||
expect(volumeControl).assertLiveRegionState(50, 'Average');
|
||||
});
|
||||
|
||||
it('when the new volume is in ]60,80]', function () {
|
||||
expect(volumeControl).assertLiveRegionState(70, 'Loud');
|
||||
});
|
||||
|
||||
it('when the new volume is in ]80,100[', function () {
|
||||
expect(volumeControl).assertLiveRegionState(90, 'Very loud');
|
||||
});
|
||||
|
||||
it('when the new volume is Maximum', function () {
|
||||
expect(volumeControl).assertLiveRegionState(100, 'Maximum');
|
||||
});
|
||||
});
|
||||
|
||||
describe('increaseVolume', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
});
|
||||
|
||||
it('volume is increased correctly', function () {
|
||||
var button = $('.volume .control');
|
||||
volumeControl.volume = 60;
|
||||
|
||||
// adjust the volume
|
||||
button.focus();
|
||||
button.trigger(keyPressEvent(KEY.UP));
|
||||
expect(volumeControl.volume).toEqual(80);
|
||||
});
|
||||
|
||||
it('volume level is not changed if it is already max', function () {
|
||||
volumeControl.volume = 100;
|
||||
volumeControl.increaseVolume();
|
||||
expect(volumeControl.volume).toEqual(100);
|
||||
});
|
||||
});
|
||||
|
||||
describe('decreaseVolume', function () {
|
||||
describe('constructor', function() {
|
||||
beforeEach(function() {
|
||||
spyOn($.fn, 'slider').and.callThrough();
|
||||
$.cookie.and.returnValue('75');
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
it('initialize volume to 75%', function() {
|
||||
expect(volumeControl.volume).toEqual(75);
|
||||
});
|
||||
|
||||
it('render the volume control', function() {
|
||||
expect($('.volume')).toExist();
|
||||
});
|
||||
|
||||
it('create the slider', function() {
|
||||
expect($.fn.slider.calls.argsFor(2)).toEqual([{
|
||||
orientation: 'vertical',
|
||||
range: 'min',
|
||||
min: 0,
|
||||
max: 100,
|
||||
slide: jasmine.any(Function)
|
||||
}]);
|
||||
expect($.fn.slider).toHaveBeenCalledWith(
|
||||
'value', volumeControl.volume
|
||||
);
|
||||
});
|
||||
|
||||
it('add ARIA attributes to live region', function() {
|
||||
var liveRegion = $('.video-live-region');
|
||||
|
||||
expect(liveRegion).toHaveAttrs({
|
||||
'aria-live': 'polite'
|
||||
});
|
||||
});
|
||||
|
||||
it('add ARIA attributes to volume control', function() {
|
||||
var button = $('.volume .control');
|
||||
|
||||
expect(button).toHaveAttrs({
|
||||
'aria-disabled': 'false'
|
||||
});
|
||||
});
|
||||
|
||||
it('bind the volume control', function() {
|
||||
var button = $('.volume .control');
|
||||
|
||||
expect(button).toHandle('keydown');
|
||||
expect(button).toHandle('mousedown');
|
||||
expect($('.volume')).not.toHaveClass('is-opened');
|
||||
|
||||
$('.volume').mouseenter();
|
||||
expect($('.volume')).toHaveClass('is-opened');
|
||||
|
||||
$('.volume').mouseleave();
|
||||
expect($('.volume')).not.toHaveClass('is-opened');
|
||||
});
|
||||
});
|
||||
|
||||
it('volume is decreased correctly', function () {
|
||||
var button = $('.volume .control');
|
||||
volumeControl.volume = 60;
|
||||
describe('setVolume', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
|
||||
jasmine.addMatchers({
|
||||
assertLiveRegionState: function() {
|
||||
return {
|
||||
compare: function(actual, volume, expectation) {
|
||||
var region = $('.video-live-region');
|
||||
|
||||
var getExpectedText = function(text) {
|
||||
return text + ' Volume.';
|
||||
};
|
||||
|
||||
actual.setVolume(volume, true, true);
|
||||
return {
|
||||
pass: region.text() === getExpectedText(expectation)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('update is not called, if new volume equals current', function() {
|
||||
volumeControl.volume = 60;
|
||||
spyOn(volumeControl, 'updateSliderView');
|
||||
volumeControl.setVolume(60, false, true);
|
||||
expect(volumeControl.updateSliderView).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('volume is changed on sliding', function() {
|
||||
volumeControl.onSlideHandler(null, {value: 99});
|
||||
expect(volumeControl.volume).toBe(99);
|
||||
});
|
||||
|
||||
describe('when the new volume is more than 0', function() {
|
||||
beforeEach(function() {
|
||||
volumeControl.setVolume(60, false, true);
|
||||
});
|
||||
|
||||
it('set the player volume', function() {
|
||||
expect(volumeControl.volume).toEqual(60);
|
||||
});
|
||||
|
||||
it('remove muted class', function() {
|
||||
expect($('.volume')).not.toHaveClass('is-muted');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the new volume is more than 0, but was 0', function() {
|
||||
it('remove muted class', function() {
|
||||
volumeControl.setVolume(0, false, true);
|
||||
expect($('.volume')).toHaveClass('is-muted');
|
||||
state.el.trigger('volumechange', [20]);
|
||||
expect($('.volume')).not.toHaveClass('is-muted');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the new volume is 0', function() {
|
||||
beforeEach(function() {
|
||||
volumeControl.setVolume(0, false, true);
|
||||
});
|
||||
|
||||
it('set the player volume', function() {
|
||||
expect(volumeControl.volume).toEqual(0);
|
||||
});
|
||||
|
||||
it('add muted class', function() {
|
||||
expect($('.volume')).toHaveClass('is-muted');
|
||||
});
|
||||
});
|
||||
|
||||
it('when the new volume is Muted', function() {
|
||||
expect(volumeControl).assertLiveRegionState(0, 'Muted');
|
||||
});
|
||||
|
||||
it('when the new volume is in ]0,20]', function() {
|
||||
expect(volumeControl).assertLiveRegionState(10, 'Very low');
|
||||
});
|
||||
|
||||
it('when the new volume is in ]20,40]', function() {
|
||||
expect(volumeControl).assertLiveRegionState(30, 'Low');
|
||||
});
|
||||
|
||||
it('when the new volume is in ]40,60]', function() {
|
||||
expect(volumeControl).assertLiveRegionState(50, 'Average');
|
||||
});
|
||||
|
||||
it('when the new volume is in ]60,80]', function() {
|
||||
expect(volumeControl).assertLiveRegionState(70, 'Loud');
|
||||
});
|
||||
|
||||
it('when the new volume is in ]80,100[', function() {
|
||||
expect(volumeControl).assertLiveRegionState(90, 'Very loud');
|
||||
});
|
||||
|
||||
it('when the new volume is Maximum', function() {
|
||||
expect(volumeControl).assertLiveRegionState(100, 'Maximum');
|
||||
});
|
||||
});
|
||||
|
||||
describe('increaseVolume', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
});
|
||||
|
||||
it('volume is increased correctly', function() {
|
||||
var button = $('.volume .control');
|
||||
volumeControl.volume = 60;
|
||||
|
||||
// adjust the volume
|
||||
button.focus();
|
||||
button.trigger(keyPressEvent(KEY.DOWN));
|
||||
expect(volumeControl.volume).toEqual(40);
|
||||
button.focus();
|
||||
button.trigger(keyPressEvent(KEY.UP));
|
||||
expect(volumeControl.volume).toEqual(80);
|
||||
});
|
||||
|
||||
it('volume level is not changed if it is already max', function() {
|
||||
volumeControl.volume = 100;
|
||||
volumeControl.increaseVolume();
|
||||
expect(volumeControl.volume).toEqual(100);
|
||||
});
|
||||
});
|
||||
|
||||
it('volume level is not changed if it is already min', function () {
|
||||
volumeControl.volume = 0;
|
||||
volumeControl.decreaseVolume();
|
||||
expect(volumeControl.volume).toEqual(0);
|
||||
});
|
||||
});
|
||||
describe('decreaseVolume', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
});
|
||||
|
||||
describe('toggleMute', function () {
|
||||
beforeEach(function () {
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
});
|
||||
|
||||
describe('when the current volume is more than 0', function () {
|
||||
beforeEach(function () {
|
||||
it('volume is decreased correctly', function() {
|
||||
var button = $('.volume .control');
|
||||
volumeControl.volume = 60;
|
||||
volumeControl.button.trigger('mousedown');
|
||||
|
||||
// adjust the volume
|
||||
button.focus();
|
||||
button.trigger(keyPressEvent(KEY.DOWN));
|
||||
expect(volumeControl.volume).toEqual(40);
|
||||
});
|
||||
|
||||
it('save the previous volume', function () {
|
||||
expect(volumeControl.storedVolume).toEqual(60);
|
||||
});
|
||||
|
||||
it('set the player volume', function () {
|
||||
it('volume level is not changed if it is already min', function() {
|
||||
volumeControl.volume = 0;
|
||||
volumeControl.decreaseVolume();
|
||||
expect(volumeControl.volume).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the current volume is 0', function () {
|
||||
beforeEach(function () {
|
||||
volumeControl.volume = 0;
|
||||
volumeControl.storedVolume = 60;
|
||||
volumeControl.button.trigger('mousedown');
|
||||
describe('toggleMute', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
});
|
||||
|
||||
it('set the player volume to previous volume', function () {
|
||||
describe('when the current volume is more than 0', function() {
|
||||
beforeEach(function() {
|
||||
volumeControl.volume = 60;
|
||||
volumeControl.button.trigger('mousedown');
|
||||
});
|
||||
|
||||
it('save the previous volume', function() {
|
||||
expect(volumeControl.storedVolume).toEqual(60);
|
||||
});
|
||||
|
||||
it('set the player volume', function() {
|
||||
expect(volumeControl.volume).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the current volume is 0', function() {
|
||||
beforeEach(function() {
|
||||
volumeControl.volume = 0;
|
||||
volumeControl.storedVolume = 60;
|
||||
volumeControl.button.trigger('mousedown');
|
||||
});
|
||||
|
||||
it('set the player volume to previous volume', function() {
|
||||
expect(volumeControl.volume).toEqual(60);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('keyDownHandler', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
});
|
||||
|
||||
var assertVolumeIsNotChanged = function(eventObject) {
|
||||
volumeControl.volume = 60;
|
||||
state.el.trigger(jQuery.Event('keydown', eventObject));
|
||||
expect(volumeControl.volume).toEqual(60);
|
||||
};
|
||||
|
||||
it('nothing happens if ALT+keyUp are pushed down', function() {
|
||||
assertVolumeIsNotChanged({
|
||||
keyCode: KEY.UP,
|
||||
altKey: true
|
||||
});
|
||||
});
|
||||
|
||||
it('nothing happens if SHIFT+keyUp are pushed down', function() {
|
||||
assertVolumeIsNotChanged({
|
||||
keyCode: KEY.UP,
|
||||
shiftKey: true
|
||||
});
|
||||
});
|
||||
|
||||
it('nothing happens if SHIFT+keyDown are pushed down', function() {
|
||||
assertVolumeIsNotChanged({
|
||||
keyCode: KEY.DOWN,
|
||||
shiftKey: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('keyDownButtonHandler', function() {
|
||||
beforeEach(function() {
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
});
|
||||
|
||||
it('nothing happens if ALT+ENTER are pushed down', function() {
|
||||
var isMuted = volumeControl.getMuteStatus();
|
||||
$('.volume .control').trigger(jQuery.Event('keydown', {
|
||||
keyCode: KEY.ENTER,
|
||||
altKey: true
|
||||
}));
|
||||
expect(volumeControl.getMuteStatus()).toEqual(isMuted);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('keyDownHandler', function () {
|
||||
beforeEach(function () {
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
});
|
||||
|
||||
var assertVolumeIsNotChanged = function (eventObject) {
|
||||
volumeControl.volume = 60;
|
||||
state.el.trigger(jQuery.Event("keydown", eventObject));
|
||||
expect(volumeControl.volume).toEqual(60);
|
||||
};
|
||||
|
||||
it('nothing happens if ALT+keyUp are pushed down', function () {
|
||||
assertVolumeIsNotChanged({
|
||||
keyCode: KEY.UP,
|
||||
altKey: true
|
||||
});
|
||||
});
|
||||
|
||||
it('nothing happens if SHIFT+keyUp are pushed down', function () {
|
||||
assertVolumeIsNotChanged({
|
||||
keyCode: KEY.UP,
|
||||
shiftKey: true
|
||||
});
|
||||
});
|
||||
|
||||
it('nothing happens if SHIFT+keyDown are pushed down', function () {
|
||||
assertVolumeIsNotChanged({
|
||||
keyCode: KEY.DOWN,
|
||||
shiftKey: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('keyDownButtonHandler', function () {
|
||||
beforeEach(function () {
|
||||
state = jasmine.initializePlayer();
|
||||
volumeControl = state.videoVolumeControl;
|
||||
});
|
||||
|
||||
it('nothing happens if ALT+ENTER are pushed down', function () {
|
||||
var isMuted = volumeControl.getMuteStatus();
|
||||
$('.volume .control').trigger(jQuery.Event("keydown", {
|
||||
keyCode: KEY.ENTER,
|
||||
altKey: true
|
||||
}));
|
||||
expect(volumeControl.getMuteStatus()).toEqual(isMuted);
|
||||
});
|
||||
});
|
||||
});
|
||||
}).call(this);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
(function () {
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('XBlockToXModuleShim', function () {
|
||||
describe('definition', function () {
|
||||
it('XBlockToXModuleShim is defined, and is a function', function () {
|
||||
describe('XBlockToXModuleShim', function() {
|
||||
describe('definition', function() {
|
||||
it('XBlockToXModuleShim is defined, and is a function', function() {
|
||||
expect($.isFunction(XBlockToXModuleShim)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('implementation', function () {
|
||||
describe('implementation', function() {
|
||||
var el,
|
||||
videoModule = {
|
||||
'module': 'video_module'
|
||||
@@ -18,7 +18,7 @@
|
||||
removeNone,
|
||||
removeVideo;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
el = $('<div />');
|
||||
|
||||
if (window.None) {
|
||||
@@ -47,7 +47,7 @@
|
||||
spyOnEvent($(document), 'XModule.loaded.display');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
el = null;
|
||||
|
||||
if (removeNone) {
|
||||
@@ -58,14 +58,14 @@
|
||||
}
|
||||
});
|
||||
|
||||
it('if element module is of type None, nothing happens', function () {
|
||||
it('if element module is of type None, nothing happens', function() {
|
||||
el.data('type', 'None');
|
||||
|
||||
expect(XBlockToXModuleShim(null, el)).toBeUndefined();
|
||||
expect(window.None).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('if element module is of type Video, Video module constructor is called', function () {
|
||||
it('if element module is of type Video, Video module constructor is called', function() {
|
||||
el.data('type', 'Video');
|
||||
|
||||
expect(XBlockToXModuleShim(null, el)).toEqual(videoModule);
|
||||
@@ -75,7 +75,7 @@
|
||||
expect('XModule.loaded.display').not.toHaveBeenTriggeredOn(document);
|
||||
});
|
||||
|
||||
it('if element has class "xmodule_edit"', function () {
|
||||
it('if element has class "xmodule_edit"', function() {
|
||||
el.data('type', 'Video')
|
||||
.addClass('xmodule_edit');
|
||||
XBlockToXModuleShim(null, el);
|
||||
@@ -84,7 +84,7 @@
|
||||
expect('XModule.loaded.display').not.toHaveBeenTriggeredOn($(document));
|
||||
});
|
||||
|
||||
it('if element has class "xmodule_display"', function () {
|
||||
it('if element has class "xmodule_display"', function() {
|
||||
el.data('type', 'Video')
|
||||
.addClass('xmodule_display');
|
||||
XBlockToXModuleShim(null, el);
|
||||
@@ -93,7 +93,7 @@
|
||||
expect(displayCallback).toHaveBeenCalledWith(jasmine.any($.Event), el, videoModule);
|
||||
});
|
||||
|
||||
it('if element has classes "xmodule_edit", and "xmodule_display"', function () {
|
||||
it('if element has classes "xmodule_edit", and "xmodule_display"', function() {
|
||||
el.data('type', 'Video')
|
||||
.addClass('xmodule_edit')
|
||||
.addClass('xmodule_display');
|
||||
@@ -102,7 +102,7 @@
|
||||
expect('XModule.loaded.display').toHaveBeenTriggeredOn($(document));
|
||||
});
|
||||
|
||||
it('element is of an unknown Module type, console.error() is called if it is defined', function () {
|
||||
it('element is of an unknown Module type, console.error() is called if it is defined', function() {
|
||||
var oldConsole = window.console;
|
||||
|
||||
if (window.console && window.console.error) {
|
||||
@@ -121,9 +121,9 @@
|
||||
window.console = oldConsole;
|
||||
});
|
||||
|
||||
it('element is of an unknown Module type, JavaScript throws if console.error() is not defined', function () {
|
||||
it('element is of an unknown Module type, JavaScript throws if console.error() is not defined', function() {
|
||||
var oldConsole = window.console,
|
||||
testFunction = function () {
|
||||
testFunction = function() {
|
||||
return XBlockToXModuleShim(null, el);
|
||||
};
|
||||
|
||||
@@ -140,55 +140,55 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('XModule.Descriptor', function () {
|
||||
describe('definition', function () {
|
||||
it('XModule is defined, and is a plain object', function () {
|
||||
describe('XModule.Descriptor', function() {
|
||||
describe('definition', function() {
|
||||
it('XModule is defined, and is a plain object', function() {
|
||||
expect($.isPlainObject(XModule)).toBe(true);
|
||||
});
|
||||
|
||||
it('XModule.Descriptor is defined, and is a function', function () {
|
||||
it('XModule.Descriptor is defined, and is a function', function() {
|
||||
expect($.isFunction(XModule.Descriptor)).toBe(true);
|
||||
});
|
||||
|
||||
it('XModule.Descriptor has a complete prototype', function () {
|
||||
it('XModule.Descriptor has a complete prototype', function() {
|
||||
expect($.isFunction(XModule.Descriptor.prototype.onUpdate)).toBe(true);
|
||||
expect($.isFunction(XModule.Descriptor.prototype.update)).toBe(true);
|
||||
expect($.isFunction(XModule.Descriptor.prototype.save)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('implementation', function () {
|
||||
describe('implementation', function() {
|
||||
var el, obj, callback, length;
|
||||
|
||||
// This is a dummy callback.
|
||||
callback = function () {
|
||||
callback = function() {
|
||||
var x = 1;
|
||||
|
||||
return x + 1;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
el = 'dummy object';
|
||||
obj = new XModule.Descriptor(el);
|
||||
|
||||
spyOn(obj, 'save').and.callThrough();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
el = null;
|
||||
obj = null;
|
||||
|
||||
length = undefined;
|
||||
});
|
||||
|
||||
it('Descriptor is a proper constructor function', function () {
|
||||
it('Descriptor is a proper constructor function', function() {
|
||||
expect(obj.hasOwnProperty('element')).toBe(true);
|
||||
expect(obj.element).toBe(el);
|
||||
|
||||
expect(obj.hasOwnProperty('update')).toBe(true);
|
||||
});
|
||||
|
||||
it('Descriptor.onUpdate called for the first time', function () {
|
||||
it('Descriptor.onUpdate called for the first time', function() {
|
||||
expect(obj.hasOwnProperty('callbacks')).toBe(false);
|
||||
obj.onUpdate(callback);
|
||||
expect(obj.hasOwnProperty('callbacks')).toBe(true);
|
||||
@@ -199,7 +199,7 @@
|
||||
expect(obj.callbacks[length - 1]).toBe(callback);
|
||||
});
|
||||
|
||||
it('Descriptor.onUpdate called for Nth time', function () {
|
||||
it('Descriptor.onUpdate called for Nth time', function() {
|
||||
// In this test it doesn't matter what obj.callbacks
|
||||
// consists of.
|
||||
obj.callbacks = ['test1', 'test2', 'test3'];
|
||||
@@ -211,13 +211,13 @@
|
||||
expect(obj.callbacks[length - 1]).toBe(callback);
|
||||
});
|
||||
|
||||
it('Descriptor.save returns a blank object', function () {
|
||||
it('Descriptor.save returns a blank object', function() {
|
||||
// NOTE: In the future the implementation of .save()
|
||||
// method may change!
|
||||
expect(obj.save()).toEqual({});
|
||||
});
|
||||
|
||||
it('Descriptor.update triggers all callbacks with whatever .save() returns', function () {
|
||||
it('Descriptor.update triggers all callbacks with whatever .save() returns', function() {
|
||||
var callback1 = jasmine.createSpy('callback1'),
|
||||
callback2 = jasmine.createSpy('callback2'),
|
||||
testValue = 'test 123';
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* ~ Chinese Proverb
|
||||
*/
|
||||
|
||||
window.ImageInput = (function ($, undefined) {
|
||||
window.ImageInput = (function($, undefined) {
|
||||
var ImageInput = ImageInputConstructor;
|
||||
|
||||
ImageInput.prototype = {
|
||||
|
||||
@@ -85,7 +85,7 @@ var cktsim = (function() {
|
||||
this.abstol = new Array(this.N);
|
||||
this.solution = new Array(this.N);
|
||||
this.rhs = new Array(this.N);
|
||||
for (var i = this.N - 1; i >= 0; --i) {
|
||||
for (var i = this.N - 1; i >= 0; --i) {
|
||||
this.soln_max[i] = 0.0;
|
||||
this.abstol[i] = this.ntypes[i] == T_VOLTAGE ? v_abstol : i_abstol;
|
||||
this.solution[i] = 0.0;
|
||||
@@ -97,7 +97,7 @@ var cktsim = (function() {
|
||||
this.devices[i].load_linear(this)
|
||||
}
|
||||
|
||||
// Check for voltage source loops.
|
||||
// Check for voltage source loops.
|
||||
var n_vsrc = this.voltage_sources.length;
|
||||
if (n_vsrc > 0) { // At least one voltage source
|
||||
var GV = mat_make(n_vsrc, this.N); // Loop check
|
||||
@@ -110,11 +110,11 @@ var cktsim = (function() {
|
||||
if (rGV < n_vsrc) {
|
||||
alert('Warning!!! Circuit has a voltage source loop or a source or current probe shorted by a wire, please remove the source or the wire causing the short.');
|
||||
alert('Warning!!! Simulator might produce meaningless results or no result with illegal circuits.');
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// load circuit from JSON netlist (see schematic.js)
|
||||
@@ -209,7 +209,7 @@ var cktsim = (function() {
|
||||
if (this.ntypes[i] == T_VOLTAGE)
|
||||
abssum_rhs += Math.abs(rhs[i]);
|
||||
|
||||
if ((iter > 0) && (use_limiting == false) && (abssum_old < abssum_rhs)) {
|
||||
if ((iter > 0) && (use_limiting == false) && (abssum_old < abssum_rhs)) {
|
||||
// Old rhsnorm was better, undo last iter and turn on limiting
|
||||
for (var i = this.N - 1; i >= 0; --i)
|
||||
soln[i] -= d_sol[i];
|
||||
@@ -222,7 +222,7 @@ var cktsim = (function() {
|
||||
// If norm going down for ten iters, stop limiting
|
||||
if (abssum_rhs < abssum_old)
|
||||
down_count += 1;
|
||||
else
|
||||
else
|
||||
down_count = 0;
|
||||
if (down_count > 10) {
|
||||
use_limiting = false;
|
||||
@@ -230,14 +230,14 @@ var cktsim = (function() {
|
||||
}
|
||||
|
||||
// Update norm of rhs
|
||||
abssum_old = abssum_rhs;
|
||||
abssum_old = abssum_rhs;
|
||||
}
|
||||
|
||||
// Update the worst case abssum for comparison.
|
||||
if ((iter == 0) || (abssum_rhs > abssum_compare))
|
||||
abssum_compare = abssum_rhs;
|
||||
|
||||
// Check residue convergence, but loosely, and give up
|
||||
// Check residue convergence, but loosely, and give up
|
||||
// on last iteration
|
||||
if ( (iter < (maxiters - 1)) &&
|
||||
(abssum_rhs > (res_check_abs+res_check_rel*abssum_compare)))
|
||||
@@ -263,7 +263,7 @@ var cktsim = (function() {
|
||||
}
|
||||
|
||||
if (converged == true) {
|
||||
for (var i = this.N - 1; i >= 0; --i)
|
||||
for (var i = this.N - 1; i >= 0; --i)
|
||||
if (Math.abs(soln[i]) > this.soln_max[i])
|
||||
this.soln_max[i] = Math.abs(soln[i]);
|
||||
return iter+1;
|
||||
@@ -338,7 +338,7 @@ var cktsim = (function() {
|
||||
mat_v_mult(ckt.C, soln, ckt.q, 1.0);
|
||||
// -rhs = c - dqdt
|
||||
for (var i = ckt.N-1; i >= 0; --i) {
|
||||
var dqdt = ckt.alpha0*ckt.q[i] + ckt.alpha1*ckt.oldq[i] +
|
||||
var dqdt = ckt.alpha0*ckt.q[i] + ckt.alpha1*ckt.oldq[i] +
|
||||
ckt.alpha2*ckt.old2q[i];
|
||||
rhs[i] = ckt.beta0[i]*ckt.c[i] + ckt.beta1[i]*ckt.oldc[i] - dqdt;
|
||||
}
|
||||
@@ -386,7 +386,7 @@ var cktsim = (function() {
|
||||
lte_step_ratio = Math.min(lte_step_ratio, max_growth_factor);
|
||||
if (lte_step_ratio > 1.2) /* Increase timestep due to lte. */
|
||||
new_step = (ckt.time - ckt.oldt) * lte_step_ratio / 1.2;
|
||||
else
|
||||
else
|
||||
new_step = (ckt.time - ckt.oldt);
|
||||
new_step = Math.min(new_step, ckt.max_step);
|
||||
}
|
||||
@@ -398,9 +398,9 @@ var cktsim = (function() {
|
||||
no_dc = false;
|
||||
if ((this.diddc == false) && (no_dc == false)) {
|
||||
if (this.dc() == undefined) { // DC failed, realloc mats and vects.
|
||||
alert('DC failed, trying transient analysis from zero.');
|
||||
alert('DC failed, trying transient analysis from zero.');
|
||||
this.finalized = false; // Reset the finalization.
|
||||
if (this.finalize() == false)
|
||||
if (this.finalize() == false)
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -438,7 +438,7 @@ var cktsim = (function() {
|
||||
|
||||
// Non-algebraic variables and probe variables get lte
|
||||
this.ltecheck = new Array(this.N);
|
||||
for (var i = N; i >= 0; --i)
|
||||
for (var i = N; i >= 0; --i)
|
||||
this.ltecheck[i] = (this.ar[i] == 0);
|
||||
|
||||
for (var name in this.node_map) {
|
||||
@@ -478,10 +478,10 @@ var cktsim = (function() {
|
||||
this.old3sol[i] = this.solution[i];
|
||||
this.old2sol[i] = this.solution[i];
|
||||
this.oldsol[i] = this.solution[i];
|
||||
this.old3q[i] = this.q[i];
|
||||
this.old2q[i] = this.q[i];
|
||||
this.oldq[i] = this.q[i];
|
||||
this.oldc[i] = this.c[i];
|
||||
this.old3q[i] = this.q[i];
|
||||
this.old2q[i] = this.q[i];
|
||||
this.oldq[i] = this.q[i];
|
||||
this.oldc[i] = this.c[i];
|
||||
}
|
||||
|
||||
var beta0,beta1;
|
||||
@@ -506,8 +506,8 @@ var cktsim = (function() {
|
||||
this.old2t = this.oldt - (tstart-this.oldt)
|
||||
this.oldt = tstart - (this.time - this.oldt);
|
||||
this.time = tstart;
|
||||
beta0 = 1.0;
|
||||
beta1 = 0.0;
|
||||
beta0 = 1.0;
|
||||
beta1 = 0.0;
|
||||
} else { // Take a regular step
|
||||
// Save the time, and rotate time wheel
|
||||
response[this.N].push(this.time);
|
||||
@@ -525,7 +525,7 @@ var cktsim = (function() {
|
||||
|
||||
// Use trap (average old and new crnts.
|
||||
beta0 = 0.5;
|
||||
beta1 = 0.5;
|
||||
beta1 = 0.5;
|
||||
}
|
||||
|
||||
// For trap rule, turn off current avging for algebraic eqns
|
||||
@@ -547,24 +547,24 @@ var cktsim = (function() {
|
||||
this.beta0[i] = 1.0;
|
||||
this.beta1[i] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Use Newton to compute the solution.
|
||||
var iterations = this.find_solution(load_tran,max_tran_iters);
|
||||
|
||||
// If NR succeeds and stepsize is at min, accept and newstep=maxgrowth*minstep.
|
||||
// Else if Newton Fails, shrink step by a factor and try again
|
||||
// Else LTE picks new step, if bigger accept current step and go on.
|
||||
if ((iterations != undefined) &&
|
||||
if ((iterations != undefined) &&
|
||||
(step_index <= 0 || (this.time-this.oldt) < (1+reltol)*this.min_step)) {
|
||||
if (step_index > 0) new_step = time_step_increase_factor*this.min_step;
|
||||
break;
|
||||
} else if (iterations == undefined) { // NR nonconvergence, shrink by factor
|
||||
this.time = this.oldt +
|
||||
this.time = this.oldt +
|
||||
(this.time - this.oldt)/nr_step_decrease_factor;
|
||||
} else { // Check the LTE and shrink step if needed.
|
||||
new_step = pick_step(this, step_index);
|
||||
if (new_step < (1.0 - reltol)*(this.time - this.oldt)) {
|
||||
this.time = this.oldt + new_step; // Try again
|
||||
this.time = this.oldt + new_step; // Try again
|
||||
}
|
||||
else
|
||||
break; // LTE okay, new_step for next step
|
||||
@@ -687,7 +687,7 @@ var cktsim = (function() {
|
||||
this.devices.push(d);
|
||||
d.name = name;
|
||||
if (name) {
|
||||
if (this.device_map[name] === undefined)
|
||||
if (this.device_map[name] === undefined)
|
||||
this.device_map[name] = d;
|
||||
else {
|
||||
alert('Warning: two circuit elements share the same name ' + name);
|
||||
@@ -793,8 +793,8 @@ var cktsim = (function() {
|
||||
//
|
||||
// Support for creating conductance and capacitance matrices associated with
|
||||
// modified nodal analysis (unknowns are node voltages and inductor and voltage
|
||||
// source currents).
|
||||
// The linearized circuit is written as
|
||||
// source currents).
|
||||
// The linearized circuit is written as
|
||||
// C d/dt x = G x + rhs
|
||||
// x - vector of node voltages and element currents
|
||||
// rhs - vector of source values
|
||||
@@ -870,10 +870,10 @@ var cktsim = (function() {
|
||||
|
||||
// Allocate an NxM matrix
|
||||
function mat_make(N,M) {
|
||||
var mat = new Array(N);
|
||||
for (var i = N - 1; i >= 0; --i) {
|
||||
var mat = new Array(N);
|
||||
for (var i = N - 1; i >= 0; --i) {
|
||||
mat[i] = new Array(M);
|
||||
for (var j = M - 1; j >= 0; --j) {
|
||||
for (var j = M - 1; j >= 0; --j) {
|
||||
mat[i][j] = 0.0;
|
||||
}
|
||||
}
|
||||
@@ -1009,7 +1009,7 @@ var cktsim = (function() {
|
||||
// now eliminate this column for all subsequent rows
|
||||
for (var i = row + 1; i < Nr; i++) {
|
||||
temp = M[i][col]/M[row][col]; // multiplier for current row
|
||||
if (temp != 0) // subtract
|
||||
if (temp != 0) // subtract
|
||||
for (var j = col; j < Nc; j++) M[i][j] -= M[row][j]*temp;
|
||||
}
|
||||
// Now move on to the next row
|
||||
@@ -1021,7 +1021,7 @@ var cktsim = (function() {
|
||||
return the_rank;
|
||||
}
|
||||
|
||||
// Solve Mx=b and return vector x using R^TQ^T factorization.
|
||||
// Solve Mx=b and return vector x using R^TQ^T factorization.
|
||||
// Multiplication by R^T implicit, should be null-space free soln.
|
||||
// M should have the extra column!
|
||||
// Almost everything is in-lined for speed, sigh.
|
||||
@@ -1038,7 +1038,7 @@ var cktsim = (function() {
|
||||
|
||||
var mat_scale = 0; // Sets the scale for comparison to zero.
|
||||
var max_nonzero_row = Nr-1; // Assumes M nonsingular.
|
||||
for (var row = 0; row < Nr; row++) {
|
||||
for (var row = 0; row < Nr; row++) {
|
||||
// Find largest row with largest 2-norm
|
||||
var max_row = row;
|
||||
var maxsumsq = 0;
|
||||
@@ -1077,7 +1077,7 @@ var cktsim = (function() {
|
||||
for (var rowp = row + 1; rowp < Nr; rowp++) { // Update.
|
||||
var Mrp = M[rowp];
|
||||
var inner = 0;
|
||||
for (var col = Nc-2; col >= 0; --col) // Project
|
||||
for (var col = Nc-2; col >= 0; --col) // Project
|
||||
inner += Mr[col]*Mrp[col];
|
||||
for (var col = Nc-1; col >= 0; --col) // Ortho (rhs also)
|
||||
Mrp[col] -= inner *Mr[col];
|
||||
@@ -1122,7 +1122,7 @@ var cktsim = (function() {
|
||||
|
||||
// if no value found, generate a small conductance to gnd
|
||||
// otherwise swap current row with pivot row
|
||||
if (max_v == 0) M[col][col] = eps;
|
||||
if (max_v == 0) M[col][col] = eps;
|
||||
else {
|
||||
temp = M[col];
|
||||
M[col] = M[max_col];
|
||||
@@ -1588,12 +1588,12 @@ var cktsim = (function() {
|
||||
|
||||
// Source voltage added to b.
|
||||
VSource.prototype.load_dc = function(ckt,soln,rhs) {
|
||||
ckt.add_to_rhs(this.branch,this.src.dc,rhs);
|
||||
ckt.add_to_rhs(this.branch,this.src.dc,rhs);
|
||||
}
|
||||
|
||||
// Load time-dependent value for voltage source for tran
|
||||
VSource.prototype.load_tran = function(ckt,soln,rhs,time) {
|
||||
ckt.add_to_rhs(this.branch,this.src.value(time),rhs);
|
||||
ckt.add_to_rhs(this.branch,this.src.value(time),rhs);
|
||||
}
|
||||
|
||||
// return time of next breakpoint for the device
|
||||
@@ -1756,7 +1756,7 @@ var cktsim = (function() {
|
||||
Capacitor.prototype.constructor = Capacitor;
|
||||
|
||||
Capacitor.prototype.load_linear = function(ckt) {
|
||||
// MNA stamp for capacitance matrix
|
||||
// MNA stamp for capacitance matrix
|
||||
ckt.add_capacitance(this.n1,this.n2,this.value);
|
||||
}
|
||||
|
||||
@@ -1808,7 +1808,7 @@ var cktsim = (function() {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Simple Voltage-Controlled Voltage Source Op Amp model
|
||||
// Simple Voltage-Controlled Voltage Source Op Amp model
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1900,7 +1900,7 @@ var cktsim = (function() {
|
||||
gmgs *= vds;
|
||||
}
|
||||
ckt.add_to_rhs(d,-ids,rhs); // current flows into the drain
|
||||
ckt.add_to_rhs(s, ids,rhs); // and out the source
|
||||
ckt.add_to_rhs(s, ids,rhs); // and out the source
|
||||
ckt.add_conductance(d,s,gds);
|
||||
ckt.add_to_G(s,s, gmgs);
|
||||
ckt.add_to_G(d,s,-gmgs);
|
||||
@@ -1939,7 +1939,7 @@ var cktsim = (function() {
|
||||
|
||||
// Copyright (C) 2011 Massachusetts Institute of Technology
|
||||
|
||||
// add schematics to a document with
|
||||
// add schematics to a document with
|
||||
//
|
||||
// <input type="hidden" class="schematic" name="unique_form_id" value="JSON netlist..." .../>
|
||||
//
|
||||
@@ -2786,7 +2786,7 @@ schematic = (function() {
|
||||
if (ckt === null) return;
|
||||
var results = ckt.ac(npts,fstart,fstop,ac_source_name);
|
||||
|
||||
if (typeof results == 'string')
|
||||
if (typeof results == 'string')
|
||||
this.message(results);
|
||||
else {
|
||||
var x_values = results['_frequencies_'];
|
||||
@@ -2913,7 +2913,7 @@ schematic = (function() {
|
||||
var results = ckt.tran(ckt.parse_number(sch.tran_npts), 0,
|
||||
ckt.parse_number(sch.tran_tstop), probe_names, false);
|
||||
|
||||
if (typeof results == 'string')
|
||||
if (typeof results == 'string')
|
||||
sch.message(results);
|
||||
else {
|
||||
if (sch.submit_analyses != undefined) {
|
||||
@@ -3885,7 +3885,7 @@ schematic = (function() {
|
||||
child = document.createElement('img');
|
||||
label = document.createElement('span');
|
||||
hidden = document.createElement('span');
|
||||
|
||||
|
||||
tool.style.backgroundImage = 'none';
|
||||
tool.setAttribute('title', tip);
|
||||
label.innerHTML = tip;
|
||||
@@ -4173,7 +4173,7 @@ schematic = (function() {
|
||||
if (x == x_min) {
|
||||
c.moveTo(temp,top_margin);
|
||||
c.lineTo(temp,end);
|
||||
} else
|
||||
} else
|
||||
c.dashedLineTo(temp,top_margin,temp,end,grid_pattern);
|
||||
c.stroke();
|
||||
|
||||
@@ -4219,7 +4219,7 @@ schematic = (function() {
|
||||
if (y == y_min) {
|
||||
c.moveTo(left_margin,temp);
|
||||
c.lineTo(left_margin + pwidth,temp);
|
||||
} else
|
||||
} else
|
||||
c.dashedLineTo(left_margin,temp,left_margin + pwidth,temp,grid_pattern);
|
||||
c.stroke();
|
||||
|
||||
@@ -5137,7 +5137,7 @@ schematic = (function() {
|
||||
this.location = nx + ',' + ny;
|
||||
|
||||
// add ourselves to the connection list for the new location
|
||||
if (parent.sch)
|
||||
if (parent.sch)
|
||||
parent.sch.update_connection_point(this,old_location);
|
||||
}
|
||||
|
||||
@@ -6069,7 +6069,7 @@ schematic = (function() {
|
||||
var first = true;
|
||||
var value = '';
|
||||
for (var label in fields) {
|
||||
if (label == 'name')
|
||||
if (label == 'name')
|
||||
c.properties['name'] = fields['name'].value;
|
||||
else if (label == 'value') {
|
||||
// if unknown source type
|
||||
@@ -6115,7 +6115,7 @@ schematic = (function() {
|
||||
this.draw_text(c,'\u2588\u2588\u2588',-8,8,4,annotation_size,element_style);
|
||||
c.globalAlpha = 1.0;
|
||||
|
||||
// display the element current
|
||||
// display the element current
|
||||
var i = engineering_notation(v,2) + 'A';
|
||||
this.draw_text(c,i,-3,5,5,annotation_size,annotation_style);
|
||||
// draw arrow for current
|
||||
@@ -6193,4 +6193,4 @@ schematic = (function() {
|
||||
'component_slider': component_slider
|
||||
}
|
||||
return module;
|
||||
}());
|
||||
}());
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(function (undefined) {
|
||||
(function(undefined) {
|
||||
'use strict';
|
||||
|
||||
// [module Collapsible]
|
||||
@@ -35,14 +35,14 @@
|
||||
short_custom = el.find('.shortform-custom');
|
||||
|
||||
// Set up each one individually.
|
||||
short_custom.each(function (index, elt) {
|
||||
short_custom.each(function(index, elt) {
|
||||
var close_text, open_text;
|
||||
|
||||
open_text = $(elt).data('open-text');
|
||||
close_text = $(elt).data('close-text');
|
||||
$(elt).append("<a href='#' class='full-custom'>" + open_text + "</a>");
|
||||
$(elt).append("<a href='#' class='full-custom'>" + open_text + '</a>');
|
||||
|
||||
$(elt).find('.full-custom').click(function (event) {
|
||||
$(elt).find('.full-custom').click(function(event) {
|
||||
Collapsible.toggleFull(event, open_text, close_text);
|
||||
});
|
||||
});
|
||||
@@ -51,8 +51,8 @@
|
||||
el.find('.collapsible header + section').hide();
|
||||
|
||||
// Set up triggers.
|
||||
el.find('.full').click(function (event) {
|
||||
Collapsible.toggleFull(event, "See full output", "Hide output");
|
||||
el.find('.full').click(function(event) {
|
||||
Collapsible.toggleFull(event, 'See full output', 'Hide output');
|
||||
});
|
||||
el.find('.collapsible header a').click(Collapsible.toggleHint);
|
||||
}
|
||||
|
||||
@@ -1,110 +1,108 @@
|
||||
var setupFullScreenModal = function() {
|
||||
|
||||
// Setup full screen image modal.
|
||||
// Executed from HTMLModule in display.js.
|
||||
$("a.modal-content").each(function() {
|
||||
var smallImageObject = $(this).children();
|
||||
var largeImageSRC = $(this).attr('href');
|
||||
|
||||
$('a.modal-content').each(function() {
|
||||
var smallImageObject = $(this).children();
|
||||
var largeImageSRC = $(this).attr('href');
|
||||
|
||||
// if contents of zoomable link is image and large image link exists: setup modal
|
||||
if (smallImageObject.is('img') && largeImageSRC) {
|
||||
var data = {
|
||||
"smallHTML": $(this).html(),
|
||||
"largeALT": smallImageObject.attr('alt'),
|
||||
"largeSRC": largeImageSRC
|
||||
};
|
||||
var html = _.template($("#image-modal-tpl").text())(data);
|
||||
$(this).replaceWith(html);
|
||||
}
|
||||
});
|
||||
$('.wrapper-modal-image .image-wrapper img').each(function() {
|
||||
var draggie = new Draggabilly(this, {containment: true});
|
||||
draggie.disable();
|
||||
$(this).closest('.image-modal').data("draggie", draggie);
|
||||
});
|
||||
if (smallImageObject.is('img') && largeImageSRC) {
|
||||
var data = {
|
||||
'smallHTML': $(this).html(),
|
||||
'largeALT': smallImageObject.attr('alt'),
|
||||
'largeSRC': largeImageSRC
|
||||
};
|
||||
var html = _.template($('#image-modal-tpl').text())(data);
|
||||
$(this).replaceWith(html);
|
||||
}
|
||||
});
|
||||
$('.wrapper-modal-image .image-wrapper img').each(function() {
|
||||
var draggie = new Draggabilly(this, {containment: true});
|
||||
draggie.disable();
|
||||
$(this).closest('.image-modal').data('draggie', draggie);
|
||||
});
|
||||
|
||||
// Opening and closing image modal on clicks
|
||||
$(".wrapper-modal-image .image-link").click(function() {
|
||||
$(this).siblings(".image-modal").addClass('image-is-fit-to-screen');
|
||||
$('body').css('overflow', 'hidden');
|
||||
});
|
||||
|
||||
$('.wrapper-modal-image .image-link').click(function() {
|
||||
$(this).siblings('.image-modal').addClass('image-is-fit-to-screen');
|
||||
$('body').css('overflow', 'hidden');
|
||||
});
|
||||
|
||||
// variable to detect when modal is being "hovered".
|
||||
// Done this way as jquery doesn't support the :hover psudo-selector as expected.
|
||||
var imageModalImageHover = false;
|
||||
$(".wrapper-modal-image .image-content img, .wrapper-modal-image .image-content .image-controls").hover(function() {
|
||||
imageModalImageHover = true;
|
||||
}, function() {
|
||||
imageModalImageHover = false;
|
||||
});
|
||||
|
||||
var imageModalImageHover = false;
|
||||
$('.wrapper-modal-image .image-content img, .wrapper-modal-image .image-content .image-controls').hover(function() {
|
||||
imageModalImageHover = true;
|
||||
}, function() {
|
||||
imageModalImageHover = false;
|
||||
});
|
||||
|
||||
// prevent image control button links from scrolling
|
||||
$(".modal-ui-icon").click(function(event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
//Define function to close modal
|
||||
function closeModal(imageModal) {
|
||||
imageModal.removeClass('image-is-fit-to-screen').removeClass('image-is-zoomed');
|
||||
$(".wrapper-modal-image .image-content .image-controls .modal-ui-icon.action-zoom-in").removeClass('is-disabled').attr('aria-disabled', false);
|
||||
$(".wrapper-modal-image .image-content .image-controls .modal-ui-icon.action-zoom-out").addClass('is-disabled').attr('aria-disabled', true);
|
||||
var currentDraggie = imageModal.data("draggie");
|
||||
currentDraggie.disable();
|
||||
$('body').css('overflow', 'auto');
|
||||
}
|
||||
|
||||
// Click outside of modal to close it.
|
||||
$(".wrapper-modal-image .image-modal").click(function() {
|
||||
if (!imageModalImageHover){
|
||||
closeModal($(this));
|
||||
$('.modal-ui-icon').click(function(event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
// Define function to close modal
|
||||
function closeModal(imageModal) {
|
||||
imageModal.removeClass('image-is-fit-to-screen').removeClass('image-is-zoomed');
|
||||
$('.wrapper-modal-image .image-content .image-controls .modal-ui-icon.action-zoom-in').removeClass('is-disabled').attr('aria-disabled', false);
|
||||
$('.wrapper-modal-image .image-content .image-controls .modal-ui-icon.action-zoom-out').addClass('is-disabled').attr('aria-disabled', true);
|
||||
var currentDraggie = imageModal.data('draggie');
|
||||
currentDraggie.disable();
|
||||
$('body').css('overflow', 'auto');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Click outside of modal to close it.
|
||||
$('.wrapper-modal-image .image-modal').click(function() {
|
||||
if (!imageModalImageHover) {
|
||||
closeModal($(this));
|
||||
}
|
||||
});
|
||||
|
||||
// Click close icon to close modal.
|
||||
$(".wrapper-modal-image .image-content .action-remove").click(function() {
|
||||
closeModal($(this).closest(".image-modal"));
|
||||
});
|
||||
$('.wrapper-modal-image .image-content .action-remove').click(function() {
|
||||
closeModal($(this).closest('.image-modal'));
|
||||
});
|
||||
|
||||
// zooming image in modal and allow it to be dragged
|
||||
// Make sure it always starts zero position for below calcs to work
|
||||
$(".wrapper-modal-image .image-content .image-controls .modal-ui-icon").click(function() {
|
||||
if (!$(this).hasClass('is-disabled')) {
|
||||
var mask = $(this).closest(".image-content");
|
||||
|
||||
var imageModal = $(this).closest(".image-modal");
|
||||
var img = imageModal.find("img");
|
||||
var currentDraggie = imageModal.data("draggie");
|
||||
|
||||
if ($(this).hasClass('action-zoom-in')) {
|
||||
imageModal.removeClass('image-is-fit-to-screen').addClass('image-is-zoomed');
|
||||
|
||||
var imgWidth = img.width();
|
||||
var imgHeight = img.height();
|
||||
|
||||
var imgContainerOffsetLeft = imgWidth - mask.width();
|
||||
var imgContainerOffsetTop = imgHeight - mask.height();
|
||||
var imgContainerWidth = imgWidth + imgContainerOffsetLeft;
|
||||
var imgContainerHeight = imgHeight + imgContainerOffsetTop;
|
||||
|
||||
$('.wrapper-modal-image .image-content .image-controls .modal-ui-icon').click(function() {
|
||||
if (!$(this).hasClass('is-disabled')) {
|
||||
var mask = $(this).closest('.image-content');
|
||||
|
||||
var imageModal = $(this).closest('.image-modal');
|
||||
var img = imageModal.find('img');
|
||||
var currentDraggie = imageModal.data('draggie');
|
||||
|
||||
if ($(this).hasClass('action-zoom-in')) {
|
||||
imageModal.removeClass('image-is-fit-to-screen').addClass('image-is-zoomed');
|
||||
|
||||
var imgWidth = img.width();
|
||||
var imgHeight = img.height();
|
||||
|
||||
var imgContainerOffsetLeft = imgWidth - mask.width();
|
||||
var imgContainerOffsetTop = imgHeight - mask.height();
|
||||
var imgContainerWidth = imgWidth + imgContainerOffsetLeft;
|
||||
var imgContainerHeight = imgHeight + imgContainerOffsetTop;
|
||||
|
||||
// Set the width and height of the image's container so that the dimensions are equal to the image dimensions + view area dimensions to limit dragging
|
||||
// Set image container top and left to center image at load.
|
||||
img.parent().css({
|
||||
left: -imgContainerOffsetLeft,
|
||||
top: -imgContainerOffsetTop,
|
||||
width: imgContainerWidth,
|
||||
height: imgContainerHeight
|
||||
});
|
||||
img.css({top: imgContainerOffsetTop / 2, left: imgContainerOffsetLeft / 2});
|
||||
|
||||
currentDraggie.enable();
|
||||
|
||||
} else if ($(this).hasClass('action-zoom-out')) {
|
||||
imageModal.removeClass('image-is-zoomed').addClass('image-is-fit-to-screen');
|
||||
|
||||
currentDraggie.disable();
|
||||
}
|
||||
|
||||
$(".wrapper-modal-image .image-content .image-controls .modal-ui-icon").toggleClass('is-disabled').attr('aria-disabled', $(this).hasClass('is-disabled'));
|
||||
}
|
||||
});
|
||||
img.parent().css({
|
||||
left: -imgContainerOffsetLeft,
|
||||
top: -imgContainerOffsetTop,
|
||||
width: imgContainerWidth,
|
||||
height: imgContainerHeight
|
||||
});
|
||||
img.css({top: imgContainerOffsetTop / 2, left: imgContainerOffsetLeft / 2});
|
||||
|
||||
currentDraggie.enable();
|
||||
} else if ($(this).hasClass('action-zoom-out')) {
|
||||
imageModal.removeClass('image-is-zoomed').addClass('image-is-fit-to-screen');
|
||||
|
||||
currentDraggie.disable();
|
||||
}
|
||||
|
||||
$('.wrapper-modal-image .image-content .image-controls .modal-ui-icon').toggleClass('is-disabled').attr('aria-disabled', $(this).hasClass('is-disabled'));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
(function() {
|
||||
'use strict';
|
||||
/**
|
||||
* This function will process all the attributes from the DOM element passed, taking all of
|
||||
@@ -8,25 +8,23 @@
|
||||
* @constructor
|
||||
* @param {jQuery} element DOM element with the lti container.
|
||||
*/
|
||||
this.LTI = function (element) {
|
||||
this.LTI = function(element) {
|
||||
var dataAttrs = $(element).find('.lti').data(),
|
||||
askToSendUsername = (dataAttrs.askToSendUsername === 'True'),
|
||||
askToSendEmail = (dataAttrs.askToSendEmail === 'True');
|
||||
|
||||
// When the lti button is clicked, provide users the option to
|
||||
// accept or reject sending their information to a third party
|
||||
$(element).on('click', '.link_lti_new_window', function () {
|
||||
if(askToSendUsername && askToSendEmail) {
|
||||
return confirm(gettext("Click OK to have your username and e-mail address sent to a 3rd party application.\n\nClick Cancel to return to this page without sending your information."));
|
||||
$(element).on('click', '.link_lti_new_window', function() {
|
||||
if (askToSendUsername && askToSendEmail) {
|
||||
return confirm(gettext('Click OK to have your username and e-mail address sent to a 3rd party application.\n\nClick Cancel to return to this page without sending your information.'));
|
||||
} else if (askToSendUsername) {
|
||||
return confirm(gettext("Click OK to have your username sent to a 3rd party application.\n\nClick Cancel to return to this page without sending your information."));
|
||||
return confirm(gettext('Click OK to have your username sent to a 3rd party application.\n\nClick Cancel to return to this page without sending your information.'));
|
||||
} else if (askToSendEmail) {
|
||||
return confirm(gettext("Click OK to have your e-mail address sent to a 3rd party application.\n\nClick Cancel to return to this page without sending your information."));
|
||||
return confirm(gettext('Click OK to have your e-mail address sent to a 3rd party application.\n\nClick Cancel to return to this page without sending your information.'));
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
window.Poll = function (el) {
|
||||
RequireJS.require(['PollMain'], function (PollMain) {
|
||||
window.Poll = function(el) {
|
||||
RequireJS.require(['PollMain'], function(PollMain) {
|
||||
new PollMain(el);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,56 +1,55 @@
|
||||
(function (requirejs, require, define) {
|
||||
define('PollMain', [], function () {
|
||||
(function(requirejs, require, define) {
|
||||
define('PollMain', [], function() {
|
||||
PollMain.prototype = {
|
||||
|
||||
PollMain.prototype = {
|
||||
'showAnswerGraph': function(poll_answers, total) {
|
||||
var _this, totalValue;
|
||||
|
||||
'showAnswerGraph': function (poll_answers, total) {
|
||||
var _this, totalValue;
|
||||
totalValue = parseFloat(total);
|
||||
if (isFinite(totalValue) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
totalValue = parseFloat(total);
|
||||
if (isFinite(totalValue) === false) {
|
||||
return;
|
||||
}
|
||||
_this = this;
|
||||
|
||||
_this = this;
|
||||
$.each(poll_answers, function(index, value) {
|
||||
var numValue, percentValue;
|
||||
|
||||
$.each(poll_answers, function (index, value) {
|
||||
var numValue, percentValue;
|
||||
numValue = parseFloat(value);
|
||||
if (isFinite(numValue) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
numValue = parseFloat(value);
|
||||
if (isFinite(numValue) === false) {
|
||||
return;
|
||||
}
|
||||
percentValue = (numValue / totalValue) * 100.0;
|
||||
|
||||
percentValue = (numValue / totalValue) * 100.0;
|
||||
_this.answersObj[index].statsEl.show();
|
||||
_this.answersObj[index].numberEl.html('' + value + ' (' + percentValue.toFixed(1) + '%)');
|
||||
_this.answersObj[index].percentEl.css({
|
||||
'width': '' + percentValue.toFixed(1) + '%'
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_this.answersObj[index].statsEl.show();
|
||||
_this.answersObj[index].numberEl.html('' + value + ' (' + percentValue.toFixed(1) + '%)');
|
||||
_this.answersObj[index].percentEl.css({
|
||||
'width': '' + percentValue.toFixed(1) + '%'
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
'submitAnswer': function (answer, answerObj) {
|
||||
var _this;
|
||||
'submitAnswer': function(answer, answerObj) {
|
||||
var _this;
|
||||
|
||||
// Make sure that the user can answer a question only once.
|
||||
if (this.questionAnswered === true) {
|
||||
return;
|
||||
}
|
||||
this.questionAnswered = true;
|
||||
if (this.questionAnswered === true) {
|
||||
return;
|
||||
}
|
||||
this.questionAnswered = true;
|
||||
|
||||
_this = this;
|
||||
_this = this;
|
||||
|
||||
console.log('submit answer');
|
||||
console.log('submit answer');
|
||||
|
||||
answerObj.buttonEl.addClass('answered');
|
||||
answerObj.buttonEl.addClass('answered');
|
||||
|
||||
// Send the data to the server as an AJAX request. Attach a callback that will
|
||||
// be fired on server's response.
|
||||
$.postWithPrefix(
|
||||
_this.ajax_url + '/' + answer, {},
|
||||
function (response) {
|
||||
$.postWithPrefix(
|
||||
_this.ajax_url + '/' + answer, {},
|
||||
function(response) {
|
||||
console.log('success! response = ');
|
||||
console.log(response);
|
||||
|
||||
@@ -62,29 +61,28 @@ PollMain.prototype = {
|
||||
|
||||
// Initialize Conditional constructors.
|
||||
if (_this.wrapperSectionEl !== null) {
|
||||
$(_this.wrapperSectionEl).find('.xmodule_ConditionalModule').each(function (index, value) {
|
||||
$(_this.wrapperSectionEl).find('.xmodule_ConditionalModule').each(function(index, value) {
|
||||
new window.Conditional(value, _this.id.replace(/^poll_/, ''));
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}, // End-of: 'submitAnswer': function (answer, answerEl) {
|
||||
}, // End-of: 'submitAnswer': function (answer, answerEl) {
|
||||
|
||||
|
||||
'submitReset': function () {
|
||||
var _this;
|
||||
'submitReset': function() {
|
||||
var _this;
|
||||
|
||||
_this = this;
|
||||
_this = this;
|
||||
|
||||
console.log('submit reset');
|
||||
console.log('submit reset');
|
||||
|
||||
// Send the data to the server as an AJAX request. Attach a callback that will
|
||||
// be fired on server's response.
|
||||
$.postWithPrefix(
|
||||
$.postWithPrefix(
|
||||
this.ajax_url + '/' + 'reset_poll',
|
||||
{},
|
||||
function (response) {
|
||||
function(response) {
|
||||
console.log('success! response = ');
|
||||
console.log(response);
|
||||
|
||||
@@ -103,200 +101,200 @@ PollMain.prototype = {
|
||||
// Initialize Conditional constructors. We will specify the third parameter as 'true'
|
||||
// notifying the constructor that this is a reset operation.
|
||||
if (_this.wrapperSectionEl !== null) {
|
||||
$(_this.wrapperSectionEl).find('.xmodule_ConditionalModule').each(function (index, value) {
|
||||
$(_this.wrapperSectionEl).find('.xmodule_ConditionalModule').each(function(index, value) {
|
||||
new window.Conditional(value, _this.id.replace(/^poll_/, ''));
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
}, // End-of: 'submitAnswer': function (answer, answerEl) {
|
||||
}, // End-of: 'submitAnswer': function (answer, answerEl) {
|
||||
|
||||
'postInit': function () {
|
||||
var _this;
|
||||
'postInit': function() {
|
||||
var _this;
|
||||
|
||||
// Access this object inside inner functions.
|
||||
_this = this;
|
||||
_this = this;
|
||||
|
||||
if (
|
||||
if (
|
||||
(this.jsonConfig.poll_answer.length > 0) &&
|
||||
(this.jsonConfig.answers.hasOwnProperty(this.jsonConfig.poll_answer) === false)
|
||||
) {
|
||||
this.questionEl.append(
|
||||
this.questionEl.append(
|
||||
'<h3>Error!</h3>' +
|
||||
'<p>XML data format changed. List of answers was modified, but poll data was not updated.</p>'
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the DOM id of the question.
|
||||
this.id = this.questionEl.attr('id');
|
||||
this.id = this.questionEl.attr('id');
|
||||
|
||||
// Get the URL to which we will post the users answer to the question.
|
||||
this.ajax_url = this.questionEl.data('ajax-url');
|
||||
this.ajax_url = this.questionEl.data('ajax-url');
|
||||
|
||||
this.questionHtmlMarkup = $('<div />').html(this.jsonConfig.question).text();
|
||||
this.questionEl.append(this.questionHtmlMarkup);
|
||||
this.questionHtmlMarkup = $('<div />').html(this.jsonConfig.question).text();
|
||||
this.questionEl.append(this.questionHtmlMarkup);
|
||||
|
||||
// When the user selects and answer, we will set this flag to true.
|
||||
this.questionAnswered = false;
|
||||
this.questionAnswered = false;
|
||||
|
||||
this.answersObj = {};
|
||||
this.shortVersion = true;
|
||||
this.answersObj = {};
|
||||
this.shortVersion = true;
|
||||
|
||||
$.each(this.jsonConfig.answers, function (index, value) {
|
||||
if (value.length >= 18) {
|
||||
_this.shortVersion = false;
|
||||
}
|
||||
});
|
||||
$.each(this.jsonConfig.answers, function(index, value) {
|
||||
if (value.length >= 18) {
|
||||
_this.shortVersion = false;
|
||||
}
|
||||
});
|
||||
|
||||
$.each(this.jsonConfig.answers, function (index, value) {
|
||||
var answer;
|
||||
$.each(this.jsonConfig.answers, function(index, value) {
|
||||
var answer;
|
||||
|
||||
answer = {};
|
||||
answer = {};
|
||||
|
||||
_this.answersObj[index] = answer;
|
||||
_this.answersObj[index] = answer;
|
||||
|
||||
answer.el = $('<div class="poll_answer"></div>');
|
||||
answer.el = $('<div class="poll_answer"></div>');
|
||||
|
||||
answer.questionEl = $('<div class="question"></div>');
|
||||
answer.buttonEl = $('<div class="button"></div>');
|
||||
answer.textEl = $('<div class="text"></div>');
|
||||
answer.questionEl.append(answer.buttonEl);
|
||||
answer.questionEl.append(answer.textEl);
|
||||
answer.questionEl = $('<div class="question"></div>');
|
||||
answer.buttonEl = $('<div class="button"></div>');
|
||||
answer.textEl = $('<div class="text"></div>');
|
||||
answer.questionEl.append(answer.buttonEl);
|
||||
answer.questionEl.append(answer.textEl);
|
||||
|
||||
answer.el.append(answer.questionEl);
|
||||
answer.el.append(answer.questionEl);
|
||||
|
||||
answer.statsEl = $('<div class="stats"></div>');
|
||||
answer.barEl = $('<div class="bar"></div>');
|
||||
answer.percentEl = $('<div class="percent"></div>');
|
||||
answer.barEl.append(answer.percentEl);
|
||||
answer.numberEl = $('<div class="number"></div>');
|
||||
answer.statsEl.append(answer.barEl);
|
||||
answer.statsEl.append(answer.numberEl);
|
||||
answer.statsEl = $('<div class="stats"></div>');
|
||||
answer.barEl = $('<div class="bar"></div>');
|
||||
answer.percentEl = $('<div class="percent"></div>');
|
||||
answer.barEl.append(answer.percentEl);
|
||||
answer.numberEl = $('<div class="number"></div>');
|
||||
answer.statsEl.append(answer.barEl);
|
||||
answer.statsEl.append(answer.numberEl);
|
||||
|
||||
answer.statsEl.hide();
|
||||
answer.statsEl.hide();
|
||||
|
||||
answer.el.append(answer.statsEl);
|
||||
answer.el.append(answer.statsEl);
|
||||
|
||||
answer.textEl.html(value);
|
||||
answer.textEl.html(value);
|
||||
|
||||
if (_this.shortVersion === true) {
|
||||
$.each(answer, function (index, value) {
|
||||
if (value instanceof jQuery) {
|
||||
value.addClass('short');
|
||||
if (_this.shortVersion === true) {
|
||||
$.each(answer, function(index, value) {
|
||||
if (value instanceof jQuery) {
|
||||
value.addClass('short');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
answer.el.appendTo(_this.questionEl);
|
||||
|
||||
answer.textEl.on('click', function() {
|
||||
_this.submitAnswer(index, answer);
|
||||
});
|
||||
|
||||
answer.buttonEl.on('click', function() {
|
||||
_this.submitAnswer(index, answer);
|
||||
});
|
||||
|
||||
if (index === _this.jsonConfig.poll_answer) {
|
||||
answer.buttonEl.addClass('answered');
|
||||
_this.questionAnswered = true;
|
||||
}
|
||||
});
|
||||
|
||||
console.log(this.jsonConfig.reset);
|
||||
|
||||
if ((typeof this.jsonConfig.reset === 'string') && (this.jsonConfig.reset.toLowerCase() === 'true')) {
|
||||
this.canReset = true;
|
||||
|
||||
this.resetButton = $('<div class="button reset-button">Change your vote</div>');
|
||||
|
||||
if (this.questionAnswered === false) {
|
||||
this.resetButton.hide();
|
||||
}
|
||||
|
||||
this.resetButton.appendTo(this.questionEl);
|
||||
|
||||
this.resetButton.on('click', function() {
|
||||
_this.submitReset();
|
||||
});
|
||||
} else {
|
||||
this.canReset = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
answer.el.appendTo(_this.questionEl);
|
||||
|
||||
answer.textEl.on('click', function () {
|
||||
_this.submitAnswer(index, answer);
|
||||
});
|
||||
|
||||
answer.buttonEl.on('click', function () {
|
||||
_this.submitAnswer(index, answer);
|
||||
});
|
||||
|
||||
if (index === _this.jsonConfig.poll_answer) {
|
||||
answer.buttonEl.addClass('answered');
|
||||
_this.questionAnswered = true;
|
||||
}
|
||||
});
|
||||
|
||||
console.log(this.jsonConfig.reset);
|
||||
|
||||
if ((typeof this.jsonConfig.reset === 'string') && (this.jsonConfig.reset.toLowerCase() === 'true')) {
|
||||
this.canReset = true;
|
||||
|
||||
this.resetButton = $('<div class="button reset-button">Change your vote</div>');
|
||||
|
||||
if (this.questionAnswered === false) {
|
||||
this.resetButton.hide();
|
||||
}
|
||||
|
||||
this.resetButton.appendTo(this.questionEl);
|
||||
|
||||
this.resetButton.on('click', function () {
|
||||
_this.submitReset();
|
||||
});
|
||||
} else {
|
||||
this.canReset = false;
|
||||
}
|
||||
|
||||
// If it turns out that the user already answered the question, show the answers graph.
|
||||
if (this.questionAnswered === true) {
|
||||
this.showAnswerGraph(this.jsonConfig.poll_answers, this.jsonConfig.total);
|
||||
}
|
||||
} // End-of: 'postInit': function () {
|
||||
}; // End-of: PollMain.prototype = {
|
||||
if (this.questionAnswered === true) {
|
||||
this.showAnswerGraph(this.jsonConfig.poll_answers, this.jsonConfig.total);
|
||||
}
|
||||
} // End-of: 'postInit': function () {
|
||||
}; // End-of: PollMain.prototype = {
|
||||
|
||||
return PollMain;
|
||||
return PollMain;
|
||||
|
||||
function PollMain(el) {
|
||||
var _this;
|
||||
function PollMain(el) {
|
||||
var _this;
|
||||
|
||||
this.questionEl = $(el).find('.poll_question');
|
||||
if (this.questionEl.length !== 1) {
|
||||
this.questionEl = $(el).find('.poll_question');
|
||||
if (this.questionEl.length !== 1) {
|
||||
// We require one question DOM element.
|
||||
console.log('ERROR: PollMain constructor requires one question DOM element.');
|
||||
console.log('ERROR: PollMain constructor requires one question DOM element.');
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Just a safety precussion. If we run this code more than once, multiple 'click' callback handlers will be
|
||||
// attached to the same DOM elements. We don't want this to happen.
|
||||
if (this.questionEl.attr('poll_main_processed') === 'true') {
|
||||
console.log(
|
||||
if (this.questionEl.attr('poll_main_processed') === 'true') {
|
||||
console.log(
|
||||
'ERROR: PolMain JS constructor was called on a DOM element that has already been processed once.'
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// This element was not processed earlier.
|
||||
// Make sure that next time we will not process this element a second time.
|
||||
this.questionEl.attr('poll_main_processed', 'true');
|
||||
this.questionEl.attr('poll_main_processed', 'true');
|
||||
|
||||
// Access this object inside inner functions.
|
||||
_this = this;
|
||||
_this = this;
|
||||
|
||||
// DOM element which contains the current poll along with any conditionals. By default we assume that such
|
||||
// element is not present. We will try to find it.
|
||||
this.wrapperSectionEl = null;
|
||||
this.wrapperSectionEl = null;
|
||||
|
||||
(function (tempEl, c1) {
|
||||
while (tempEl.tagName.toLowerCase() !== 'body') {
|
||||
tempEl = $(tempEl).parent()[0];
|
||||
c1 += 1;
|
||||
(function(tempEl, c1) {
|
||||
while (tempEl.tagName.toLowerCase() !== 'body') {
|
||||
tempEl = $(tempEl).parent()[0];
|
||||
c1 += 1;
|
||||
|
||||
if (
|
||||
if (
|
||||
(tempEl.tagName.toLowerCase() === 'div') &&
|
||||
($(tempEl).data('block-type') === 'wrapper')
|
||||
) {
|
||||
_this.wrapperSectionEl = tempEl;
|
||||
_this.wrapperSectionEl = tempEl;
|
||||
|
||||
break;
|
||||
} else if (c1 > 50) {
|
||||
break;
|
||||
} else if (c1 > 50) {
|
||||
// In case something breaks, and we enter an endless loop, a sane
|
||||
// limit for loop iterations.
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}($(el)[0], 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}($(el)[0], 0));
|
||||
|
||||
try {
|
||||
this.jsonConfig = JSON.parse(this.questionEl.children('.poll_question_div').html());
|
||||
try {
|
||||
this.jsonConfig = JSON.parse(this.questionEl.children('.poll_question_div').html());
|
||||
|
||||
$.postWithPrefix(
|
||||
'' + this.questionEl.data('ajax-url') + '/' + 'get_state', {},
|
||||
function (response) {
|
||||
$.postWithPrefix(
|
||||
'' + this.questionEl.data('ajax-url') + '/' + 'get_state', {},
|
||||
function(response) {
|
||||
_this.jsonConfig.poll_answer = response.poll_answer;
|
||||
_this.jsonConfig.total = response.total;
|
||||
|
||||
$.each(response.poll_answers, function (index, value) {
|
||||
$.each(response.poll_answers, function(index, value) {
|
||||
_this.jsonConfig.poll_answers[index] = value;
|
||||
});
|
||||
|
||||
@@ -306,18 +304,17 @@ function PollMain(el) {
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
} catch (err) {
|
||||
console.log(
|
||||
return;
|
||||
} catch (err) {
|
||||
console.log(
|
||||
'ERROR: Invalid JSON config for poll ID "' + this.id + '".',
|
||||
'Error messsage: "' + err.message + '".'
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
} // End-of: function PollMain(el) {
|
||||
|
||||
}); // End-of: define('PollMain', [], function () {
|
||||
return;
|
||||
}
|
||||
} // End-of: function PollMain(el) {
|
||||
}); // End-of: define('PollMain', [], function () {
|
||||
|
||||
// End-of: (function (requirejs, require, define) {
|
||||
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(function (undefined) {
|
||||
(function(undefined) {
|
||||
'use strict';
|
||||
|
||||
this.Time = {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(function (define) {
|
||||
define(
|
||||
(function(define) {
|
||||
define(
|
||||
'video/00_async_process.js',
|
||||
[],
|
||||
function() {
|
||||
"use strict";
|
||||
'use strict';
|
||||
/**
|
||||
* Provides convenient way to process big amount of data without UI blocking.
|
||||
*
|
||||
@@ -13,7 +13,7 @@ function() {
|
||||
* certain type bound to the collection, queued or not, have finished.
|
||||
*/
|
||||
var AsyncProcess = {
|
||||
array: function (list, process) {
|
||||
array: function(list, process) {
|
||||
if (!_.isArray(list)) {
|
||||
return $.Deferred().reject().promise();
|
||||
}
|
||||
@@ -28,11 +28,11 @@ function() {
|
||||
index = 0,
|
||||
len = list.length;
|
||||
|
||||
var getCurrentTime = function () {
|
||||
var getCurrentTime = function() {
|
||||
return (new Date()).getTime();
|
||||
};
|
||||
|
||||
var handler = function () {
|
||||
var handler = function() {
|
||||
var start = getCurrentTime();
|
||||
|
||||
do {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(function (define) {
|
||||
'use strict';
|
||||
define('video/00_component.js', [],
|
||||
function () {
|
||||
(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
|
||||
@@ -10,10 +10,10 @@ function () {
|
||||
* @throws {TypeError, Error}
|
||||
* @return {Object}
|
||||
*/
|
||||
var inherit = Object.create || (function () {
|
||||
var F = function () {};
|
||||
var inherit = Object.create || (function() {
|
||||
var F = function() {};
|
||||
|
||||
return function (o) {
|
||||
return function(o) {
|
||||
if (arguments.length > 1) {
|
||||
throw Error('Second argument not supported');
|
||||
}
|
||||
@@ -36,7 +36,7 @@ function () {
|
||||
* @constructor
|
||||
* @return {jquery Promise}
|
||||
*/
|
||||
var Component = function () {
|
||||
var Component = function() {
|
||||
if ($.isFunction(this.initialize)) {
|
||||
return this.initialize.apply(this, arguments);
|
||||
}
|
||||
@@ -49,9 +49,9 @@ function () {
|
||||
* the prototype.
|
||||
* @return {Object}
|
||||
*/
|
||||
Component.extend = function (protoProps, staticProps) {
|
||||
Component.extend = function(protoProps, staticProps) {
|
||||
var Parent = this,
|
||||
Child = function () {
|
||||
Child = function() {
|
||||
if ($.isFunction(this.initialize)) {
|
||||
return this.initialize.apply(this, arguments);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function (define) {
|
||||
'use strict';
|
||||
define(
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define(
|
||||
'video/00_i18n.js',
|
||||
[],
|
||||
function() {
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
(function (define) {
|
||||
define(
|
||||
(function(define) {
|
||||
define(
|
||||
'video/00_iterator.js',
|
||||
[],
|
||||
function() {
|
||||
"use strict";
|
||||
'use strict';
|
||||
/**
|
||||
* Provides convenient way to work with iterable data.
|
||||
* @exports video/00_iterator.js
|
||||
* @constructor
|
||||
* @param {array} list Array to be iterated.
|
||||
*/
|
||||
var Iterator = function (list) {
|
||||
this.list = list;
|
||||
this.index = 0;
|
||||
this.size = this.list.length;
|
||||
this.lastIndex = this.list.length - 1;
|
||||
};
|
||||
var Iterator = function(list) {
|
||||
this.list = list;
|
||||
this.index = 0;
|
||||
this.size = this.list.length;
|
||||
this.lastIndex = this.list.length - 1;
|
||||
};
|
||||
|
||||
Iterator.prototype = {
|
||||
|
||||
@@ -25,7 +25,7 @@ function() {
|
||||
* @param {numebr} index
|
||||
* @return {boolean}
|
||||
*/
|
||||
_isValid: function (index) {
|
||||
_isValid: function(index) {
|
||||
return _.isNumber(index) && index < this.size && index >= 0;
|
||||
},
|
||||
|
||||
@@ -34,12 +34,12 @@ function() {
|
||||
* @param {number} [index] Updates current position.
|
||||
* @return {any}
|
||||
*/
|
||||
next: function (index) {
|
||||
next: function(index) {
|
||||
if (!(this._isValid(index))) {
|
||||
index = this.index;
|
||||
}
|
||||
|
||||
this.index = (index >= this.lastIndex) ? 0: index + 1;
|
||||
this.index = (index >= this.lastIndex) ? 0 : index + 1;
|
||||
|
||||
return this.list[this.index];
|
||||
},
|
||||
@@ -49,12 +49,12 @@ function() {
|
||||
* @param {number} [index] Updates current position.
|
||||
* @return {any}
|
||||
*/
|
||||
prev: function (index) {
|
||||
prev: function(index) {
|
||||
if (!(this._isValid(index))) {
|
||||
index = this.index;
|
||||
}
|
||||
|
||||
this.index = (index < 1) ? this.lastIndex: index - 1;
|
||||
this.index = (index < 1) ? this.lastIndex : index - 1;
|
||||
|
||||
return this.list[this.index];
|
||||
},
|
||||
@@ -63,7 +63,7 @@ function() {
|
||||
* Returns last element in the list.
|
||||
* @return {any}
|
||||
*/
|
||||
last: function () {
|
||||
last: function() {
|
||||
return this.list[this.lastIndex];
|
||||
},
|
||||
|
||||
@@ -71,7 +71,7 @@ function() {
|
||||
* Returns first element in the list.
|
||||
* @return {any}
|
||||
*/
|
||||
first: function () {
|
||||
first: function() {
|
||||
return this.list[0];
|
||||
},
|
||||
|
||||
@@ -79,7 +79,7 @@ function() {
|
||||
* Returns `true` if current position is last for the iterator.
|
||||
* @return {boolean}
|
||||
*/
|
||||
isEnd: function () {
|
||||
isEnd: function() {
|
||||
return this.index === this.lastIndex;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
(function (requirejs, require, define) {
|
||||
|
||||
define(
|
||||
(function(requirejs, require, define) {
|
||||
define(
|
||||
'video/00_resizer.js',
|
||||
[],
|
||||
function () {
|
||||
|
||||
var Resizer = function (params) {
|
||||
function() {
|
||||
var Resizer = function(params) {
|
||||
var defaults = {
|
||||
container: window,
|
||||
element: null,
|
||||
@@ -21,7 +19,7 @@ function () {
|
||||
mode = null,
|
||||
config;
|
||||
|
||||
var initialize = function (params) {
|
||||
var initialize = function(params) {
|
||||
if (!config) {
|
||||
config = defaults;
|
||||
}
|
||||
@@ -37,7 +35,7 @@ function () {
|
||||
return module;
|
||||
};
|
||||
|
||||
var getData = function () {
|
||||
var getData = function() {
|
||||
var container = $(config.container),
|
||||
containerWidth = container.width() + delta.width,
|
||||
containerHeight = container.height() + delta.height,
|
||||
@@ -47,11 +45,11 @@ function () {
|
||||
elementRatio = config.elementRatio;
|
||||
|
||||
if (!containerRatio) {
|
||||
containerRatio = containerWidth/containerHeight;
|
||||
containerRatio = containerWidth / containerHeight;
|
||||
}
|
||||
|
||||
if (!elementRatio) {
|
||||
elementRatio = element.width()/element.height();
|
||||
elementRatio = element.width() / element.height();
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -63,25 +61,25 @@ function () {
|
||||
};
|
||||
};
|
||||
|
||||
var align = function () {
|
||||
var align = function() {
|
||||
var data = getData();
|
||||
|
||||
switch (mode) {
|
||||
case 'height':
|
||||
case 'height':
|
||||
alignByHeightOnly();
|
||||
break;
|
||||
|
||||
case 'width':
|
||||
alignByWidthOnly();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (data.containerRatio >= data.elementRatio) {
|
||||
alignByHeightOnly();
|
||||
break;
|
||||
|
||||
case 'width':
|
||||
} else {
|
||||
alignByWidthOnly();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (data.containerRatio >= data.elementRatio) {
|
||||
alignByHeightOnly();
|
||||
} else {
|
||||
alignByWidthOnly();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
fireCallbacks();
|
||||
@@ -89,35 +87,35 @@ function () {
|
||||
return module;
|
||||
};
|
||||
|
||||
var alignByWidthOnly = function () {
|
||||
var alignByWidthOnly = function() {
|
||||
var data = getData(),
|
||||
height = data.containerWidth/data.elementRatio;
|
||||
height = data.containerWidth / data.elementRatio;
|
||||
|
||||
data.element.css({
|
||||
'height': height,
|
||||
'width': data.containerWidth,
|
||||
'top': 0.5*(data.containerHeight - height),
|
||||
'top': 0.5 * (data.containerHeight - height),
|
||||
'left': 0
|
||||
});
|
||||
|
||||
return module;
|
||||
};
|
||||
|
||||
var alignByHeightOnly = function () {
|
||||
var alignByHeightOnly = function() {
|
||||
var data = getData(),
|
||||
width = data.containerHeight*data.elementRatio;
|
||||
width = data.containerHeight * data.elementRatio;
|
||||
|
||||
data.element.css({
|
||||
'height': data.containerHeight,
|
||||
'width': data.containerHeight*data.elementRatio,
|
||||
'width': data.containerHeight * data.elementRatio,
|
||||
'top': 0,
|
||||
'left': 0.5*(data.containerWidth - width)
|
||||
'left': 0.5 * (data.containerWidth - width)
|
||||
});
|
||||
|
||||
return module;
|
||||
};
|
||||
|
||||
var setMode = function (param) {
|
||||
var setMode = function(param) {
|
||||
if (_.isString(param)) {
|
||||
mode = param;
|
||||
align();
|
||||
@@ -126,13 +124,13 @@ function () {
|
||||
return module;
|
||||
};
|
||||
|
||||
var setElement = function (element) {
|
||||
var setElement = function(element) {
|
||||
config.element = element;
|
||||
|
||||
return module;
|
||||
};
|
||||
|
||||
var addCallback = function (func) {
|
||||
var addCallback = function(func) {
|
||||
if ($.isFunction(func)) {
|
||||
callbacksList.push(func);
|
||||
} else {
|
||||
@@ -142,9 +140,9 @@ function () {
|
||||
return module;
|
||||
};
|
||||
|
||||
var addOnceCallback = function (func) {
|
||||
var addOnceCallback = function(func) {
|
||||
if ($.isFunction(func)) {
|
||||
var decorator = function () {
|
||||
var decorator = function() {
|
||||
func();
|
||||
removeCallback(func);
|
||||
};
|
||||
@@ -157,19 +155,19 @@ function () {
|
||||
return module;
|
||||
};
|
||||
|
||||
var fireCallbacks = function () {
|
||||
var fireCallbacks = function() {
|
||||
$.each(callbacksList, function(index, callback) {
|
||||
callback();
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
var removeCallbacks = function () {
|
||||
var removeCallbacks = function() {
|
||||
callbacksList.length = 0;
|
||||
|
||||
return module;
|
||||
};
|
||||
|
||||
var removeCallback = function (func) {
|
||||
var removeCallback = function(func) {
|
||||
var index = $.inArray(func, callbacksList);
|
||||
|
||||
if (index !== -1) {
|
||||
@@ -177,13 +175,13 @@ function () {
|
||||
}
|
||||
};
|
||||
|
||||
var resetDelta = function () {
|
||||
var resetDelta = function() {
|
||||
delta['height'] = delta['width'] = 0;
|
||||
|
||||
return module;
|
||||
};
|
||||
|
||||
var addDelta = function (value, side) {
|
||||
var addDelta = function(value, side) {
|
||||
if (_.isNumber(value) && _.isNumber(delta[side])) {
|
||||
delta[side] += value;
|
||||
}
|
||||
@@ -191,7 +189,7 @@ function () {
|
||||
return module;
|
||||
};
|
||||
|
||||
var substractDelta = function (value, side) {
|
||||
var substractDelta = function(value, side) {
|
||||
if (_.isNumber(value) && _.isNumber(delta[side])) {
|
||||
delta[side] -= value;
|
||||
}
|
||||
@@ -199,7 +197,7 @@ function () {
|
||||
return module;
|
||||
};
|
||||
|
||||
var destroy = function () {
|
||||
var destroy = function() {
|
||||
var data = getData();
|
||||
data.element.css({
|
||||
'height': '', 'width': '', 'top': '', 'left': ''
|
||||
@@ -235,5 +233,4 @@ function () {
|
||||
|
||||
return Resizer;
|
||||
});
|
||||
|
||||
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
(function (define) {
|
||||
|
||||
define(
|
||||
(function(define) {
|
||||
define(
|
||||
'video/00_sjson.js',
|
||||
[],
|
||||
function() {
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
var Sjson = function (data) {
|
||||
var Sjson = function(data) {
|
||||
var sjson = {
|
||||
start: data.start.concat(),
|
||||
text: data.text.concat()
|
||||
},
|
||||
module = {};
|
||||
|
||||
var getter = function (propertyName) {
|
||||
return function () {
|
||||
var getter = function(propertyName) {
|
||||
return function() {
|
||||
return sjson[propertyName];
|
||||
};
|
||||
};
|
||||
@@ -23,7 +22,7 @@ function() {
|
||||
|
||||
var getCaptions = getter('text');
|
||||
|
||||
var size = function () {
|
||||
var size = function() {
|
||||
return sjson.text.length;
|
||||
};
|
||||
|
||||
@@ -40,11 +39,11 @@ function() {
|
||||
// Else, search the unfiltered list.
|
||||
if (typeof startTime !== 'undefined' &&
|
||||
typeof endTime !== 'undefined') {
|
||||
results = filter(startTime, endTime);
|
||||
start = results.start;
|
||||
max = results.captions.length - 1;
|
||||
results = filter(startTime, endTime);
|
||||
start = results.start;
|
||||
max = results.captions.length - 1;
|
||||
} else {
|
||||
start = getStartTimes();
|
||||
start = getStartTimes();
|
||||
}
|
||||
while (min < max) {
|
||||
index = Math.ceil((max + min) / 2);
|
||||
@@ -59,7 +58,7 @@ function() {
|
||||
}
|
||||
|
||||
return min;
|
||||
};
|
||||
}
|
||||
|
||||
function filter(start, end) {
|
||||
/* filters captions that occur between inputs
|
||||
@@ -79,7 +78,7 @@ function() {
|
||||
var captions = getCaptions();
|
||||
|
||||
if (startTimes.length !== captions.length) {
|
||||
console.warn("video caption and start time arrays do not match in length");
|
||||
console.warn('video caption and start time arrays do not match in length');
|
||||
}
|
||||
|
||||
// if end is null, then it's been set to
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
(function (requirejs, require, define) {
|
||||
|
||||
define(
|
||||
(function(requirejs, require, define) {
|
||||
define(
|
||||
'video/00_video_storage.js',
|
||||
[],
|
||||
function() {
|
||||
"use strict";
|
||||
'use strict';
|
||||
/**
|
||||
* Provides convenient way to store key value pairs.
|
||||
*
|
||||
* @param {string} namespace Namespace that is used to store data.
|
||||
* @return {object} VideoStorage API.
|
||||
*/
|
||||
var VideoStorage = function (namespace, id) {
|
||||
var VideoStorage = function(namespace, id) {
|
||||
/**
|
||||
* Adds new value to the storage or rewrites existent.
|
||||
*
|
||||
@@ -20,7 +19,7 @@ function() {
|
||||
* @param {boolean} instanceSpecific Data with this flag will be added
|
||||
* to instance specific storage.
|
||||
*/
|
||||
var setItem = function (name, value, instanceSpecific) {
|
||||
var setItem = function(name, value, instanceSpecific) {
|
||||
if (name) {
|
||||
if (instanceSpecific) {
|
||||
window[namespace][id][name] = value;
|
||||
@@ -40,7 +39,7 @@ function() {
|
||||
* If the given key does not exist in the list
|
||||
* associated with the object then this method must return null.
|
||||
*/
|
||||
var getItem = function (name, instanceSpecific) {
|
||||
var getItem = function(name, instanceSpecific) {
|
||||
if (instanceSpecific) {
|
||||
return window[namespace][id][name];
|
||||
} else {
|
||||
@@ -55,7 +54,7 @@ function() {
|
||||
* @param {boolean} instanceSpecific Data with this flag will be added
|
||||
* to instance specific storage.
|
||||
*/
|
||||
var removeItem = function (name, instanceSpecific) {
|
||||
var removeItem = function(name, instanceSpecific) {
|
||||
if (instanceSpecific) {
|
||||
delete window[namespace][id][name];
|
||||
} else {
|
||||
@@ -67,7 +66,7 @@ function() {
|
||||
* Empties the storage.
|
||||
*
|
||||
*/
|
||||
var clear = function () {
|
||||
var clear = function() {
|
||||
window[namespace] = {};
|
||||
window[namespace][id] = {};
|
||||
};
|
||||
|
||||
@@ -10,12 +10,11 @@
|
||||
* @module Initialize
|
||||
*/
|
||||
|
||||
(function (requirejs, require, define) {
|
||||
|
||||
define(
|
||||
(function(requirejs, require, define) {
|
||||
define(
|
||||
'video/01_initialize.js',
|
||||
['video/03_video_player.js', 'video/00_i18n.js', 'moment'],
|
||||
function (VideoPlayer, i18n, moment) {
|
||||
function(VideoPlayer, i18n, moment) {
|
||||
var moment = moment || window.moment;
|
||||
/**
|
||||
* @function
|
||||
@@ -27,11 +26,11 @@ function (VideoPlayer, i18n, moment) {
|
||||
* available via this object.
|
||||
* @param {DOM element} element Container of the entire Video DOM element.
|
||||
*/
|
||||
var Initialize = function (state, element) {
|
||||
_makeFunctionsPublic(state);
|
||||
var Initialize = function(state, element) {
|
||||
_makeFunctionsPublic(state);
|
||||
|
||||
state.initialize(element)
|
||||
.done(function () {
|
||||
state.initialize(element)
|
||||
.done(function() {
|
||||
if (state.isYoutubeType()) {
|
||||
state.parseSpeed();
|
||||
}
|
||||
@@ -44,7 +43,7 @@ function (VideoPlayer, i18n, moment) {
|
||||
}
|
||||
|
||||
_initializeModules(state, i18n)
|
||||
.done(function () {
|
||||
.done(function() {
|
||||
// On iPad ready state occurs just after start playing.
|
||||
// We hide controls before video starts playing.
|
||||
if (/iPad|Android/i.test(state.isTouch[0])) {
|
||||
@@ -60,30 +59,30 @@ function (VideoPlayer, i18n, moment) {
|
||||
state.el.trigger('initialize', arguments);
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
methodsDict = {
|
||||
bindTo: bindTo,
|
||||
fetchMetadata: fetchMetadata,
|
||||
getCurrentLanguage: getCurrentLanguage,
|
||||
getDuration: getDuration,
|
||||
getPlayerMode: getPlayerMode,
|
||||
getVideoMetadata: getVideoMetadata,
|
||||
initialize: initialize,
|
||||
isHtml5Mode: isHtml5Mode,
|
||||
isFlashMode: isFlashMode,
|
||||
isYoutubeType: isYoutubeType,
|
||||
parseSpeed: parseSpeed,
|
||||
parseYoutubeStreams: parseYoutubeStreams,
|
||||
setPlayerMode: setPlayerMode,
|
||||
setSpeed: setSpeed,
|
||||
speedToString: speedToString,
|
||||
trigger: trigger,
|
||||
youtubeId: youtubeId,
|
||||
loadHtmlPlayer: loadHtmlPlayer,
|
||||
loadYoutubePlayer: loadYoutubePlayer,
|
||||
loadYouTubeIFrameAPI: loadYouTubeIFrameAPI
|
||||
},
|
||||
methodsDict = {
|
||||
bindTo: bindTo,
|
||||
fetchMetadata: fetchMetadata,
|
||||
getCurrentLanguage: getCurrentLanguage,
|
||||
getDuration: getDuration,
|
||||
getPlayerMode: getPlayerMode,
|
||||
getVideoMetadata: getVideoMetadata,
|
||||
initialize: initialize,
|
||||
isHtml5Mode: isHtml5Mode,
|
||||
isFlashMode: isFlashMode,
|
||||
isYoutubeType: isYoutubeType,
|
||||
parseSpeed: parseSpeed,
|
||||
parseYoutubeStreams: parseYoutubeStreams,
|
||||
setPlayerMode: setPlayerMode,
|
||||
setSpeed: setSpeed,
|
||||
speedToString: speedToString,
|
||||
trigger: trigger,
|
||||
youtubeId: youtubeId,
|
||||
loadHtmlPlayer: loadHtmlPlayer,
|
||||
loadYoutubePlayer: loadYoutubePlayer,
|
||||
loadYouTubeIFrameAPI: loadYouTubeIFrameAPI
|
||||
},
|
||||
|
||||
_youtubeApiDeferred = null,
|
||||
_oldOnYouTubeIframeAPIReady;
|
||||
@@ -130,7 +129,7 @@ function (VideoPlayer, i18n, moment) {
|
||||
if (state.videoType === 'youtube') {
|
||||
state.youtubeApiAvailable = false;
|
||||
|
||||
onYTApiReady = function () {
|
||||
onYTApiReady = function() {
|
||||
console.log('[Video info]: YouTube API is available and is loaded.');
|
||||
if (state.htmlPlayerLoaded) { return; }
|
||||
|
||||
@@ -162,10 +161,10 @@ function (VideoPlayer, i18n, moment) {
|
||||
//
|
||||
// If this global function is already defined, we store it first, and make
|
||||
// sure that it gets executed when our Deferred object is resolved.
|
||||
setupOnYouTubeIframeAPIReady = function () {
|
||||
setupOnYouTubeIframeAPIReady = function() {
|
||||
_oldOnYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady || undefined;
|
||||
|
||||
window.onYouTubeIframeAPIReady = function () {
|
||||
window.onYouTubeIframeAPIReady = function() {
|
||||
window.onYouTubeIframeAPIReady.resolve();
|
||||
};
|
||||
|
||||
@@ -194,7 +193,7 @@ function (VideoPlayer, i18n, moment) {
|
||||
|
||||
// Attach a callback to our Deferred object to be called once the
|
||||
// YouTube API loads.
|
||||
window.onYouTubeIframeAPIReady.done(function () {
|
||||
window.onYouTubeIframeAPIReady.done(function() {
|
||||
window.YT.ready(onYTApiReady);
|
||||
});
|
||||
}
|
||||
@@ -209,7 +208,7 @@ function (VideoPlayer, i18n, moment) {
|
||||
|
||||
function _waitForYoutubeApi(state) {
|
||||
console.log('[Video info]: Starting to wait for YouTube API to load.');
|
||||
window.setTimeout(function () {
|
||||
window.setTimeout(function() {
|
||||
// If YouTube API will load OK, it will run `onYouTubeIframeAPIReady`
|
||||
// callback, which will set `state.youtubeApiAvailable` to `true`.
|
||||
// If something goes wrong at this stage, `state.youtubeApiAvailable` is
|
||||
@@ -222,7 +221,6 @@ function (VideoPlayer, i18n, moment) {
|
||||
}
|
||||
state.el.trigger('youtube_availability', [state.youtubeApiAvailable]);
|
||||
}, state.config.ytTestTimeout);
|
||||
|
||||
}
|
||||
|
||||
function loadYouTubeIFrameAPI(scriptTag) {
|
||||
@@ -337,7 +335,7 @@ function (VideoPlayer, i18n, moment) {
|
||||
} else if ($.isPlainObject(module)) {
|
||||
return module;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$.when.apply(null, modulesList)
|
||||
.done(dfd.resolve);
|
||||
@@ -346,101 +344,101 @@ function (VideoPlayer, i18n, moment) {
|
||||
}
|
||||
|
||||
function _getConfiguration(data, storage) {
|
||||
var isBoolean = function (value) {
|
||||
var regExp = /^true$/i;
|
||||
return regExp.test(value.toString());
|
||||
},
|
||||
var isBoolean = function(value) {
|
||||
var regExp = /^true$/i;
|
||||
return regExp.test(value.toString());
|
||||
},
|
||||
// List of keys that will be extracted form the configuration.
|
||||
extractKeys = [],
|
||||
extractKeys = [],
|
||||
// Compatibility keys used to change names of some parameters in
|
||||
// the final configuration.
|
||||
compatKeys = {
|
||||
'start': 'startTime',
|
||||
'end': 'endTime'
|
||||
},
|
||||
compatKeys = {
|
||||
'start': 'startTime',
|
||||
'end': 'endTime'
|
||||
},
|
||||
// Conversions used to pre-process some configuration data.
|
||||
conversions = {
|
||||
'showCaptions': isBoolean,
|
||||
'autoplay': isBoolean,
|
||||
'autohideHtml5': isBoolean,
|
||||
'savedVideoPosition': function (value) {
|
||||
return storage.getItem('savedVideoPosition', true) ||
|
||||
conversions = {
|
||||
'showCaptions': isBoolean,
|
||||
'autoplay': isBoolean,
|
||||
'autohideHtml5': isBoolean,
|
||||
'savedVideoPosition': function(value) {
|
||||
return storage.getItem('savedVideoPosition', true) ||
|
||||
Number(value) ||
|
||||
0;
|
||||
},
|
||||
'speed': function (value) {
|
||||
return storage.getItem('speed', true) || value;
|
||||
},
|
||||
'generalSpeed': function (value) {
|
||||
return storage.getItem('general_speed') ||
|
||||
},
|
||||
'speed': function(value) {
|
||||
return storage.getItem('speed', true) || value;
|
||||
},
|
||||
'generalSpeed': function(value) {
|
||||
return storage.getItem('general_speed') ||
|
||||
value ||
|
||||
'1.0';
|
||||
},
|
||||
'transcriptLanguage': function (value) {
|
||||
return storage.getItem('language') ||
|
||||
},
|
||||
'transcriptLanguage': function(value) {
|
||||
return storage.getItem('language') ||
|
||||
value ||
|
||||
'en';
|
||||
},
|
||||
'ytTestTimeout': function (value) {
|
||||
value = parseInt(value, 10);
|
||||
|
||||
if (!isFinite(value)) {
|
||||
value = 1500;
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
'startTime': function (value) {
|
||||
value = parseInt(value, 10);
|
||||
if (!isFinite(value) || value < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
'endTime': function (value) {
|
||||
value = parseInt(value, 10);
|
||||
|
||||
if (!isFinite(value) || value === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
},
|
||||
config = {};
|
||||
'ytTestTimeout': function(value) {
|
||||
value = parseInt(value, 10);
|
||||
|
||||
data = _.extend({
|
||||
startTime: 0,
|
||||
endTime: null,
|
||||
sub: '',
|
||||
streams: ''
|
||||
}, data);
|
||||
if (!isFinite(value)) {
|
||||
value = 1500;
|
||||
}
|
||||
|
||||
$.each(data, function(option, value) {
|
||||
// Extract option that is in `extractKeys`.
|
||||
if ($.inArray(option, extractKeys) !== -1) {
|
||||
return;
|
||||
return value;
|
||||
},
|
||||
'startTime': function(value) {
|
||||
value = parseInt(value, 10);
|
||||
if (!isFinite(value) || value < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
'endTime': function(value) {
|
||||
value = parseInt(value, 10);
|
||||
|
||||
if (!isFinite(value) || value === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
},
|
||||
config = {};
|
||||
|
||||
data = _.extend({
|
||||
startTime: 0,
|
||||
endTime: null,
|
||||
sub: '',
|
||||
streams: ''
|
||||
}, data);
|
||||
|
||||
$.each(data, function(option, value) {
|
||||
// Extract option that is in `extractKeys`.
|
||||
if ($.inArray(option, extractKeys) !== -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Change option name to key that is in `compatKeys`.
|
||||
if (compatKeys[option]) {
|
||||
option = compatKeys[option];
|
||||
}
|
||||
if (compatKeys[option]) {
|
||||
option = compatKeys[option];
|
||||
}
|
||||
|
||||
// Pre-process data.
|
||||
if (conversions[option]) {
|
||||
if (_.isFunction(conversions[option])) {
|
||||
value = conversions[option].call(this, value);
|
||||
} else {
|
||||
throw new TypeError(option + ' is not a function.');
|
||||
}
|
||||
if (conversions[option]) {
|
||||
if (_.isFunction(conversions[option])) {
|
||||
value = conversions[option].call(this, value);
|
||||
} else {
|
||||
throw new TypeError(option + ' is not a function.');
|
||||
}
|
||||
config[option] = value;
|
||||
});
|
||||
}
|
||||
config[option] = value;
|
||||
});
|
||||
|
||||
return config;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
// ***************************************************************
|
||||
// Public functions start here.
|
||||
@@ -456,7 +454,6 @@ function (VideoPlayer, i18n, moment) {
|
||||
function bindTo(methodsDict, obj, context, rewrite) {
|
||||
$.each(methodsDict, function(name, method) {
|
||||
if (_.isFunction(method)) {
|
||||
|
||||
if (_.isUndefined(rewrite)) {
|
||||
rewrite = true;
|
||||
}
|
||||
@@ -480,7 +477,6 @@ function (VideoPlayer, i18n, moment) {
|
||||
}
|
||||
|
||||
function loadHtmlPlayer() {
|
||||
|
||||
// When the youtube link doesn't work for any reason
|
||||
// (for example, firewall) any
|
||||
// alternate sources should automatically play.
|
||||
@@ -563,10 +559,8 @@ function (VideoPlayer, i18n, moment) {
|
||||
_setConfigurations(this);
|
||||
|
||||
if (!(_parseYouTubeIDs(this))) {
|
||||
|
||||
// If we do not have YouTube ID's, try parsing HTML5 video sources.
|
||||
if (!_prepareHTML5Video(this)) {
|
||||
|
||||
__dfd__.reject();
|
||||
// Non-YouTube sources were not found either.
|
||||
return __dfd__.promise();
|
||||
@@ -623,7 +617,7 @@ function (VideoPlayer, i18n, moment) {
|
||||
|
||||
this.videos = {};
|
||||
|
||||
_.each(youtubeStreams.split(/,/), function (video) {
|
||||
_.each(youtubeStreams.split(/,/), function(video) {
|
||||
var speed;
|
||||
video = video.split(/:/);
|
||||
speed = this.speedToString(video[0]);
|
||||
@@ -645,8 +639,8 @@ function (VideoPlayer, i18n, moment) {
|
||||
|
||||
this.metadata = {};
|
||||
|
||||
metadataXHRs = _.map(this.videos, function (url, speed) {
|
||||
return self.getVideoMetadata(url, function (data) {
|
||||
metadataXHRs = _.map(this.videos, function(url, speed) {
|
||||
return self.getVideoMetadata(url, function(data) {
|
||||
if (data.items.length > 0) {
|
||||
var metaDataItem = data.items[0];
|
||||
self.metadata[metaDataItem.id] = metaDataItem.contentDetails;
|
||||
@@ -654,7 +648,7 @@ function (VideoPlayer, i18n, moment) {
|
||||
});
|
||||
});
|
||||
|
||||
$.when.apply(this, metadataXHRs).done(function () {
|
||||
$.when.apply(this, metadataXHRs).done(function() {
|
||||
self.el.trigger('metadata_received');
|
||||
|
||||
// Not only do we trigger the "metadata_received" event, we also
|
||||
@@ -664,7 +658,6 @@ function (VideoPlayer, i18n, moment) {
|
||||
// cases when some code will subscribe to the "metadata_received"
|
||||
// event after it has been triggered.
|
||||
self.youtubeMetadataReceived = true;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -715,7 +708,7 @@ function (VideoPlayer, i18n, moment) {
|
||||
function youtubeId(speed) {
|
||||
var currentSpeed = this.isFlashMode() ? this.speed : '1.0';
|
||||
|
||||
return this.videos[speed] ||
|
||||
return this.videos[speed] ||
|
||||
this.videos[currentSpeed] ||
|
||||
this.videos['1.0'];
|
||||
}
|
||||
@@ -836,5 +829,4 @@ function (VideoPlayer, i18n, moment) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
|
||||
|
||||
@@ -25,14 +25,13 @@
|
||||
* ~ Zen saying
|
||||
*/
|
||||
|
||||
(function (requirejs, require, define) {
|
||||
|
||||
(function(requirejs, require, define) {
|
||||
// FocusGrabber module.
|
||||
define(
|
||||
define(
|
||||
'video/025_focus_grabber.js',
|
||||
[],
|
||||
function () {
|
||||
return function (state) {
|
||||
function() {
|
||||
return function(state) {
|
||||
var dfd = $.Deferred();
|
||||
|
||||
state.focusGrabber = {};
|
||||
@@ -75,7 +74,7 @@ function () {
|
||||
// When the video container element receives programmatic focus, then
|
||||
// on un-focus ('blur' event) we should trigger a 'mousemove' event so
|
||||
// as to reveal autohidden controls.
|
||||
state.el.on('blur', function () {
|
||||
state.el.on('blur', function() {
|
||||
state.el.trigger('mousemove');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,16 +13,15 @@
|
||||
* @module HTML5Video
|
||||
*/
|
||||
|
||||
(function (requirejs, require, define) {
|
||||
|
||||
define(
|
||||
(function(requirejs, require, define) {
|
||||
define(
|
||||
'video/02_html5_video.js',
|
||||
[],
|
||||
function () {
|
||||
function() {
|
||||
var HTML5Video = {};
|
||||
|
||||
HTML5Video.Player = (function () {
|
||||
Player.prototype.callStateChangeCallback = function () {
|
||||
HTML5Video.Player = (function() {
|
||||
Player.prototype.callStateChangeCallback = function() {
|
||||
if ($.isFunction(this.config.events.onStateChange)) {
|
||||
this.config.events.onStateChange({
|
||||
data: this.playerState
|
||||
@@ -30,11 +29,11 @@ function () {
|
||||
}
|
||||
};
|
||||
|
||||
Player.prototype.pauseVideo = function () {
|
||||
Player.prototype.pauseVideo = function() {
|
||||
this.video.pause();
|
||||
};
|
||||
|
||||
Player.prototype.seekTo = function (value) {
|
||||
Player.prototype.seekTo = function(value) {
|
||||
if (
|
||||
typeof value === 'number' &&
|
||||
value <= this.video.duration &&
|
||||
@@ -44,29 +43,29 @@ function () {
|
||||
}
|
||||
};
|
||||
|
||||
Player.prototype.setVolume = function (value) {
|
||||
Player.prototype.setVolume = function(value) {
|
||||
if (typeof value === 'number' && value <= 100 && value >= 0) {
|
||||
this.video.volume = value * 0.01;
|
||||
}
|
||||
};
|
||||
|
||||
Player.prototype.getCurrentTime = function () {
|
||||
Player.prototype.getCurrentTime = function() {
|
||||
return this.video.currentTime;
|
||||
};
|
||||
|
||||
Player.prototype.playVideo = function () {
|
||||
Player.prototype.playVideo = function() {
|
||||
this.video.play();
|
||||
};
|
||||
|
||||
Player.prototype.getPlayerState = function () {
|
||||
Player.prototype.getPlayerState = function() {
|
||||
return this.playerState;
|
||||
};
|
||||
|
||||
Player.prototype.getVolume = function () {
|
||||
Player.prototype.getVolume = function() {
|
||||
return this.video.volume;
|
||||
};
|
||||
|
||||
Player.prototype.getDuration = function () {
|
||||
Player.prototype.getDuration = function() {
|
||||
if (isNaN(this.video.duration)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -74,7 +73,7 @@ function () {
|
||||
return this.video.duration;
|
||||
};
|
||||
|
||||
Player.prototype.setPlaybackRate = function (value) {
|
||||
Player.prototype.setPlaybackRate = function(value) {
|
||||
var newSpeed;
|
||||
|
||||
newSpeed = parseFloat(value);
|
||||
@@ -86,15 +85,15 @@ function () {
|
||||
}
|
||||
};
|
||||
|
||||
Player.prototype.getAvailablePlaybackRates = function () {
|
||||
Player.prototype.getAvailablePlaybackRates = function() {
|
||||
return [0.75, 1.0, 1.25, 1.5];
|
||||
};
|
||||
|
||||
Player.prototype._getLogs = function () {
|
||||
Player.prototype._getLogs = function() {
|
||||
return this.logs;
|
||||
};
|
||||
|
||||
Player.prototype.showErrorMessage = function () {
|
||||
Player.prototype.showErrorMessage = function() {
|
||||
this.el
|
||||
.find('.video-player div')
|
||||
.addClass('hidden')
|
||||
@@ -110,13 +109,13 @@ function () {
|
||||
});
|
||||
};
|
||||
|
||||
Player.prototype.onError = function (event) {
|
||||
Player.prototype.onError = function(event) {
|
||||
if ($.isFunction(this.config.events.onError)) {
|
||||
this.config.events.onError();
|
||||
}
|
||||
};
|
||||
|
||||
Player.prototype.destroy = function () {
|
||||
Player.prototype.destroy = function() {
|
||||
this.video.removeEventListener('loadedmetadata', this.onLoadedMetadata, false);
|
||||
this.video.removeEventListener('play', this.onPlay, false);
|
||||
this.video.removeEventListener('playing', this.onPlaying, false);
|
||||
@@ -131,29 +130,29 @@ function () {
|
||||
this.videoEl.remove();
|
||||
};
|
||||
|
||||
Player.prototype.onLoadedMetadata = function () {
|
||||
Player.prototype.onLoadedMetadata = function() {
|
||||
this.playerState = HTML5Video.PlayerState.PAUSED;
|
||||
if ($.isFunction(this.config.events.onReady)) {
|
||||
this.config.events.onReady(null);
|
||||
}
|
||||
};
|
||||
|
||||
Player.prototype.onPlay = function () {
|
||||
Player.prototype.onPlay = function() {
|
||||
this.playerState = HTML5Video.PlayerState.BUFFERING;
|
||||
this.callStateChangeCallback();
|
||||
};
|
||||
|
||||
Player.prototype.onPlaying = function () {
|
||||
Player.prototype.onPlaying = function() {
|
||||
this.playerState = HTML5Video.PlayerState.PLAYING;
|
||||
this.callStateChangeCallback();
|
||||
};
|
||||
|
||||
Player.prototype.onPause = function () {
|
||||
Player.prototype.onPause = function() {
|
||||
this.playerState = HTML5Video.PlayerState.PAUSED;
|
||||
this.callStateChangeCallback();
|
||||
};
|
||||
|
||||
Player.prototype.onEnded = function () {
|
||||
Player.prototype.onEnded = function() {
|
||||
this.playerState = HTML5Video.PlayerState.ENDED;
|
||||
this.callStateChangeCallback();
|
||||
};
|
||||
@@ -242,16 +241,16 @@ function () {
|
||||
|
||||
// Create HTML markup for individual sources of the HTML5 <video>
|
||||
// element.
|
||||
sourceList = $.map(config.videoSources, function (source) {
|
||||
return [
|
||||
sourceList = $.map(config.videoSources, function(source) {
|
||||
return [
|
||||
'<source ',
|
||||
'src="', source,
|
||||
'src="', source,
|
||||
// Following hack allows to open the same video twice
|
||||
// https://code.google.com/p/chromium/issues/detail?id=31014
|
||||
// Check whether the url already has a '?' inside, and if so,
|
||||
// use '&' instead of '?' to prevent breaking the url's integrity.
|
||||
(source.indexOf('?') === -1 ? '?' : '&'),
|
||||
(new Date()).getTime(), '" />'
|
||||
(new Date()).getTime(), '" />'
|
||||
].join('');
|
||||
});
|
||||
|
||||
@@ -286,7 +285,7 @@ function () {
|
||||
|
||||
// Attach a 'click' event on the <video> element. It will cause the
|
||||
// video to pause/play.
|
||||
this.videoEl.on('click', function (event) {
|
||||
this.videoEl.on('click', function(event) {
|
||||
var PlayerState = HTML5Video.PlayerState;
|
||||
|
||||
if (_this.playerState === PlayerState.PLAYING) {
|
||||
@@ -307,7 +306,7 @@ function () {
|
||||
|
||||
this.debug = false;
|
||||
$.each(events, function(index, eventName) {
|
||||
_this.video.addEventListener(eventName, function () {
|
||||
_this.video.addEventListener(eventName, function() {
|
||||
_this.logs.push({
|
||||
'event name': eventName,
|
||||
'state': _this.playerState
|
||||
@@ -356,5 +355,4 @@ function () {
|
||||
// HTML5Video object - what this module exports.
|
||||
return HTML5Video;
|
||||
});
|
||||
|
||||
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(function(define) {
|
||||
'use strict';
|
||||
'use strict';
|
||||
// VideoAccessibleMenu module.
|
||||
define(
|
||||
define(
|
||||
'video/035_video_accessible_menu.js', [],
|
||||
function() {
|
||||
/**
|
||||
@@ -51,7 +51,7 @@ function() {
|
||||
this.menuList = this.el.children('.a11y-menu-list');
|
||||
this.menuItems = this.menuList.children('.a11y-menu-item');
|
||||
this.menuItemsLinks = this.menuItems.children('.a11y-menu-item-link');
|
||||
value = (function (val, activeElement) {
|
||||
value = (function(val, activeElement) {
|
||||
return val || activeElement.find('a').data('value') || 'srt';
|
||||
}(this.value, this.menuItems.filter('.active')));
|
||||
msg = '.' + value;
|
||||
@@ -159,57 +159,57 @@ function() {
|
||||
index = target.parent().index();
|
||||
switch (keyCode) {
|
||||
// Scroll up menu, wrapping at the top. Keep menu open.
|
||||
case KEY.UP:
|
||||
this.previousMenuItemLink(this.menuItemsLinks, index).focus();
|
||||
break;
|
||||
case KEY.UP:
|
||||
this.previousMenuItemLink(this.menuItemsLinks, index).focus();
|
||||
break;
|
||||
// Scroll down menu, wrapping at the bottom. Keep menu
|
||||
// open.
|
||||
case KEY.DOWN:
|
||||
this.nextMenuItemLink(this.menuItemsLinks, index).focus();
|
||||
break;
|
||||
case KEY.DOWN:
|
||||
this.nextMenuItemLink(this.menuItemsLinks, index).focus();
|
||||
break;
|
||||
// Close menu.
|
||||
case KEY.TAB:
|
||||
this.closeMenu();
|
||||
case KEY.TAB:
|
||||
this.closeMenu();
|
||||
// TODO
|
||||
// What has to happen here? In speed menu, tabbing backward
|
||||
// will give focus to Play/Pause button and tabbing
|
||||
// forward to Volume button.
|
||||
break;
|
||||
break;
|
||||
// Close menu, give focus to button and change
|
||||
// file type.
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
this.button.focus();
|
||||
this.changeFileType.call(this, event);
|
||||
this.closeMenu();
|
||||
break;
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
this.button.focus();
|
||||
this.changeFileType.call(this, event);
|
||||
this.closeMenu();
|
||||
break;
|
||||
// Close menu and give focus to speed control.
|
||||
case KEY.ESCAPE:
|
||||
this.closeMenu();
|
||||
this.button.focus();
|
||||
break;
|
||||
case KEY.ESCAPE:
|
||||
this.closeMenu();
|
||||
this.button.focus();
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
switch(keyCode) {
|
||||
switch (keyCode) {
|
||||
// Open menu and focus on last element of list above it.
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
case KEY.UP:
|
||||
this.openMenu();
|
||||
this.menuItemsLinks.last().focus();
|
||||
break;
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
case KEY.UP:
|
||||
this.openMenu();
|
||||
this.menuItemsLinks.last().focus();
|
||||
break;
|
||||
// Close menu.
|
||||
case KEY.ESCAPE:
|
||||
this.closeMenu();
|
||||
break;
|
||||
case KEY.ESCAPE:
|
||||
this.closeMenu();
|
||||
break;
|
||||
}
|
||||
// We do not stop propagation and default behavior on a TAB
|
||||
// keypress.
|
||||
return event.keyCode === KEY.TAB;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
setValue: function(value) {
|
||||
this.value = value;
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
(function (requirejs, require, define) {
|
||||
|
||||
(function(requirejs, require, define) {
|
||||
// VideoPlayer module.
|
||||
define(
|
||||
define(
|
||||
'video/03_video_player.js',
|
||||
['video/02_html5_video.js', 'video/00_resizer.js'],
|
||||
function (HTML5Video, Resizer) {
|
||||
function(HTML5Video, Resizer) {
|
||||
var dfd = $.Deferred(),
|
||||
VideoPlayer = function (state) {
|
||||
VideoPlayer = function(state) {
|
||||
state.videoPlayer = {};
|
||||
_makeFunctionsPublic(state);
|
||||
_initialize(state);
|
||||
@@ -69,7 +68,7 @@ function (HTML5Video, Resizer) {
|
||||
// these functions will get the 'state' object as a context.
|
||||
function _makeFunctionsPublic(state) {
|
||||
var debouncedF = _.debounce(
|
||||
function (params) {
|
||||
function(params) {
|
||||
// Can't cancel a queued debounced function on destroy
|
||||
if (state.videoPlayer) {
|
||||
return onSeek.call(this, params);
|
||||
@@ -108,9 +107,8 @@ function (HTML5Video, Resizer) {
|
||||
// by student before video starts playing. Waits until the video's
|
||||
// metadata is loaded, which normally happens just after the video
|
||||
// starts playing. Just after that configurations can be applied.
|
||||
state.videoPlayer.ready = _.once(function () {
|
||||
state.videoPlayer.ready = _.once(function() {
|
||||
if (!state.isFlashMode() && state.speed != '1.0') {
|
||||
|
||||
// Work around a bug in the Youtube API that causes videos to
|
||||
// play at normal speed rather than at the configured speed in
|
||||
// Safari. Setting the playback rate to 1.0 *after* playing
|
||||
@@ -160,10 +158,10 @@ function (HTML5Video, Resizer) {
|
||||
|
||||
if (state.videoType === 'html5') {
|
||||
state.videoPlayer.player = new HTML5Video.Player(state.el, {
|
||||
playerVars: state.videoPlayer.playerVars,
|
||||
playerVars: state.videoPlayer.playerVars,
|
||||
videoSources: state.config.sources,
|
||||
events: {
|
||||
onReady: state.videoPlayer.onReady,
|
||||
onReady: state.videoPlayer.onReady,
|
||||
onStateChange: state.videoPlayer.onStateChange,
|
||||
onError: state.videoPlayer.onError
|
||||
}
|
||||
@@ -171,7 +169,6 @@ function (HTML5Video, Resizer) {
|
||||
|
||||
player = state.videoEl = state.videoPlayer.player.videoEl;
|
||||
player[0].addEventListener('loadedmetadata', state.videoPlayer.onLoadMetadataHtml5, false);
|
||||
|
||||
} else {
|
||||
youTubeId = state.youtubeId();
|
||||
|
||||
@@ -186,7 +183,7 @@ function (HTML5Video, Resizer) {
|
||||
}
|
||||
});
|
||||
|
||||
state.el.on('initialize', function () {
|
||||
state.el.on('initialize', function() {
|
||||
var player = state.videoEl = state.el.find('iframe'),
|
||||
videoWidth = player.attr('width') || player.width(),
|
||||
videoHeight = player.attr('height') || player.height();
|
||||
@@ -202,7 +199,7 @@ function (HTML5Video, Resizer) {
|
||||
}
|
||||
|
||||
function _updateVcrAndRegion(state, isYoutube) {
|
||||
var update = function (state) {
|
||||
var update = function(state) {
|
||||
var duration = state.videoPlayer.duration(),
|
||||
time;
|
||||
|
||||
@@ -244,7 +241,7 @@ function (HTML5Video, Resizer) {
|
||||
// We wait for metadata to arrive, before we request the update
|
||||
// of the VCR video time, and of the start-end time region.
|
||||
// Metadata contains duration of the video.
|
||||
state.el.on('metadata_received', function () {
|
||||
state.el.on('metadata_received', function() {
|
||||
update(state);
|
||||
});
|
||||
}
|
||||
@@ -252,10 +249,10 @@ function (HTML5Video, Resizer) {
|
||||
|
||||
function _resize(state, videoWidth, videoHeight) {
|
||||
state.resizer = new Resizer({
|
||||
element: state.videoEl,
|
||||
elementRatio: videoWidth/videoHeight,
|
||||
container: state.container
|
||||
})
|
||||
element: state.videoEl,
|
||||
elementRatio: videoWidth / videoHeight,
|
||||
container: state.container
|
||||
})
|
||||
.callbacks.once(function() {
|
||||
state.el.trigger('caption:resize');
|
||||
})
|
||||
@@ -263,12 +260,12 @@ function (HTML5Video, Resizer) {
|
||||
|
||||
// Update captions size when controls becomes visible on iPad or Android
|
||||
if (/iPad|Android/i.test(state.isTouch[0])) {
|
||||
state.el.on('controls:show', function () {
|
||||
state.el.on('controls:show', function() {
|
||||
state.el.trigger('caption:resize');
|
||||
});
|
||||
}
|
||||
|
||||
$(window).on('resize.video', _.debounce(function () {
|
||||
$(window).on('resize.video', _.debounce(function() {
|
||||
state.trigger('videoFullScreen.updateControlsHeight', null);
|
||||
state.el.trigger('caption:resize');
|
||||
state.resizer.align();
|
||||
@@ -372,7 +369,6 @@ function (HTML5Video, Resizer) {
|
||||
this.videoPlayer.endTime !== null &&
|
||||
this.videoPlayer.endTime <= this.videoPlayer.currentTime
|
||||
) {
|
||||
|
||||
this.videoPlayer.pause();
|
||||
|
||||
this.trigger('videoProgressSlider.notifyThroughHandleEnd', {
|
||||
@@ -508,7 +504,7 @@ function (HTML5Video, Resizer) {
|
||||
// Youtube video cannot be rewinded during bufferization, so wait to
|
||||
// finish bufferization and then rewind the video.
|
||||
if (this.isYoutubeType() && this.videoPlayer.isBuffering()) {
|
||||
this.el.on('play.seek', function () {
|
||||
this.el.on('play.seek', function() {
|
||||
this.videoPlayer.player.seekTo(time, true);
|
||||
}.bind(this));
|
||||
} else {
|
||||
@@ -601,11 +597,11 @@ function (HTML5Video, Resizer) {
|
||||
|
||||
dfd.resolve();
|
||||
|
||||
this.el.on('speedchange', function (event, speed) {
|
||||
this.el.on('speedchange', function(event, speed) {
|
||||
_this.videoPlayer.onSpeedChange(speed);
|
||||
});
|
||||
|
||||
this.el.on('volumechange volumechange:silent', function (event, volume) {
|
||||
this.el.on('volumechange volumechange:silent', function(event, volume) {
|
||||
_this.videoPlayer.onVolumeChange(volume);
|
||||
});
|
||||
|
||||
@@ -621,7 +617,7 @@ function (HTML5Video, Resizer) {
|
||||
|
||||
availablePlaybackRates = _.filter(
|
||||
availablePlaybackRates,
|
||||
function (item) {
|
||||
function(item) {
|
||||
var speed = Number(item);
|
||||
return speed > 0.25 && speed <= 5;
|
||||
}
|
||||
@@ -664,12 +660,12 @@ function (HTML5Video, Resizer) {
|
||||
// and their associated subs.
|
||||
|
||||
// First clear the dictionary.
|
||||
$.each(this.videos, function (index, value) {
|
||||
$.each(this.videos, function(index, value) {
|
||||
delete _this.videos[index];
|
||||
});
|
||||
this.speeds = [];
|
||||
// Recreate it with the supplied frame rates.
|
||||
$.each(availablePlaybackRates, function (index, value) {
|
||||
$.each(availablePlaybackRates, function(index, value) {
|
||||
var key = value.toFixed(2).replace(/\.00$/, '.0');
|
||||
|
||||
_this.videos[key] = baseSpeedSubs;
|
||||
@@ -712,36 +708,36 @@ function (HTML5Video, Resizer) {
|
||||
].join(' '));
|
||||
|
||||
switch (event.data) {
|
||||
case this.videoPlayer.PlayerState.UNSTARTED:
|
||||
this.el.addClass('is-unstarted');
|
||||
this.videoPlayer.onUnstarted();
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.PLAYING:
|
||||
this.el.addClass('is-playing');
|
||||
this.videoPlayer.onPlay();
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.PAUSED:
|
||||
this.el.addClass('is-paused');
|
||||
this.videoPlayer.onPause();
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.BUFFERING:
|
||||
this.el.addClass('is-buffered');
|
||||
this.el.trigger('buffering');
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.ENDED:
|
||||
this.el.addClass('is-ended');
|
||||
this.videoPlayer.onEnded();
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.CUED:
|
||||
this.el.addClass('is-cued');
|
||||
if (this.isFlashMode()) {
|
||||
this.videoPlayer.play();
|
||||
}
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.UNSTARTED:
|
||||
this.el.addClass('is-unstarted');
|
||||
this.videoPlayer.onUnstarted();
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.PLAYING:
|
||||
this.el.addClass('is-playing');
|
||||
this.videoPlayer.onPlay();
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.PAUSED:
|
||||
this.el.addClass('is-paused');
|
||||
this.videoPlayer.onPause();
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.BUFFERING:
|
||||
this.el.addClass('is-buffered');
|
||||
this.el.trigger('buffering');
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.ENDED:
|
||||
this.el.addClass('is-ended');
|
||||
this.videoPlayer.onEnded();
|
||||
break;
|
||||
case this.videoPlayer.PlayerState.CUED:
|
||||
this.el.addClass('is-cued');
|
||||
if (this.isFlashMode()) {
|
||||
this.videoPlayer.play();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function onError (code) {
|
||||
function onError(code) {
|
||||
this.el.trigger('error', [code]);
|
||||
}
|
||||
|
||||
@@ -779,7 +775,7 @@ function (HTML5Video, Resizer) {
|
||||
this.videoPlayer.figureOutStartEndTime(duration);
|
||||
|
||||
startTime = this.videoPlayer.startTime;
|
||||
endTime = this.videoPlayer.endTime;
|
||||
endTime = this.videoPlayer.endTime;
|
||||
|
||||
if (startTime > 0) {
|
||||
if (
|
||||
@@ -931,5 +927,4 @@ function (HTML5Video, Resizer) {
|
||||
this.videoPlayer.player.setVolume(volume);
|
||||
}
|
||||
});
|
||||
|
||||
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
(function (requirejs, require, define) {
|
||||
(function(requirejs, require, define) {
|
||||
// VideoControl module.
|
||||
define(
|
||||
define(
|
||||
'video/04_video_control.js',
|
||||
[],
|
||||
function () {
|
||||
|
||||
function() {
|
||||
// VideoControl() function - what this module "exports".
|
||||
return function (state) {
|
||||
return function(state) {
|
||||
var dfd = $.Deferred();
|
||||
|
||||
state.videoControl = {};
|
||||
@@ -137,7 +136,7 @@ function () {
|
||||
}
|
||||
|
||||
this.controlState = 'hiding';
|
||||
this.videoControl.el.fadeOut(this.videoControl.fadeOutTimeout, function () {
|
||||
this.videoControl.el.fadeOut(this.videoControl.fadeOutTimeout, function() {
|
||||
_this.controlState = 'invisible';
|
||||
// If the focus was on the video control or the volume control,
|
||||
// then we must make sure to close these dialogs. Otherwise, after
|
||||
@@ -156,7 +155,5 @@ function () {
|
||||
endTime = Math.min(endTime, params.duration);
|
||||
this.videoControl.vidTimeEl.html(Time.format(params.time) + ' / ' + Time.format(endTime));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
(function (define) {
|
||||
'use strict';
|
||||
define('video/04_video_full_screen.js', ['edx-ui-toolkit/js/utils/html-utils'], function (HtmlUtils) {
|
||||
var template = [
|
||||
'<button class="control add-fullscreen" aria-disabled="false" title="',
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define('video/04_video_full_screen.js', ['edx-ui-toolkit/js/utils/html-utils'], function(HtmlUtils) {
|
||||
var template = [
|
||||
'<button class="control add-fullscreen" aria-disabled="false" title="',
|
||||
gettext('Fill browser'),
|
||||
'">',
|
||||
'">',
|
||||
'<span class="icon fa fa-arrows-alt" aria-hidden="true"></span>',
|
||||
'</button>'
|
||||
].join('');
|
||||
'</button>'
|
||||
].join('');
|
||||
|
||||
// VideoControl() function - what this module "exports".
|
||||
return function (state) {
|
||||
var dfd = $.Deferred();
|
||||
return function(state) {
|
||||
var dfd = $.Deferred();
|
||||
|
||||
state.videoFullScreen = {};
|
||||
state.videoFullScreen = {};
|
||||
|
||||
_makeFunctionsPublic(state);
|
||||
_renderElements(state);
|
||||
_bindHandlers(state);
|
||||
_makeFunctionsPublic(state);
|
||||
_renderElements(state);
|
||||
_bindHandlers(state);
|
||||
|
||||
dfd.resolve();
|
||||
return dfd.promise();
|
||||
};
|
||||
dfd.resolve();
|
||||
return dfd.promise();
|
||||
};
|
||||
|
||||
// ***************************************************************
|
||||
// Private functions start here.
|
||||
@@ -31,62 +31,62 @@ define('video/04_video_full_screen.js', ['edx-ui-toolkit/js/utils/html-utils'],
|
||||
//
|
||||
// Functions which will be accessible via 'state' object. When called, these functions will
|
||||
// get the 'state' object as a context.
|
||||
function _makeFunctionsPublic(state) {
|
||||
var methodsDict = {
|
||||
destroy: destroy,
|
||||
enter: enter,
|
||||
exitHandler: exitHandler,
|
||||
exit: exit,
|
||||
onFullscreenChange: onFullscreenChange,
|
||||
toggle: toggle,
|
||||
toggleHandler: toggleHandler,
|
||||
updateControlsHeight: updateControlsHeight
|
||||
};
|
||||
function _makeFunctionsPublic(state) {
|
||||
var methodsDict = {
|
||||
destroy: destroy,
|
||||
enter: enter,
|
||||
exitHandler: exitHandler,
|
||||
exit: exit,
|
||||
onFullscreenChange: onFullscreenChange,
|
||||
toggle: toggle,
|
||||
toggleHandler: toggleHandler,
|
||||
updateControlsHeight: updateControlsHeight
|
||||
};
|
||||
|
||||
state.bindTo(methodsDict, state.videoFullScreen, state);
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
$(document).off('keyup', this.videoFullScreen.exitHandler);
|
||||
this.videoFullScreen.fullScreenEl.remove();
|
||||
this.el.off({
|
||||
'fullscreen': this.videoFullScreen.onFullscreenChange,
|
||||
'destroy': this.videoFullScreen.destroy
|
||||
});
|
||||
if (this.isFullScreen) {
|
||||
this.videoFullScreen.exit();
|
||||
state.bindTo(methodsDict, state.videoFullScreen, state);
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
$(document).off('keyup', this.videoFullScreen.exitHandler);
|
||||
this.videoFullScreen.fullScreenEl.remove();
|
||||
this.el.off({
|
||||
'fullscreen': this.videoFullScreen.onFullscreenChange,
|
||||
'destroy': this.videoFullScreen.destroy
|
||||
});
|
||||
if (this.isFullScreen) {
|
||||
this.videoFullScreen.exit();
|
||||
}
|
||||
delete this.videoFullScreen;
|
||||
}
|
||||
delete this.videoFullScreen;
|
||||
}
|
||||
|
||||
// function _renderElements(state)
|
||||
//
|
||||
// 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) {
|
||||
state.videoFullScreen.fullScreenEl = $(template);
|
||||
state.videoFullScreen.sliderEl = state.el.find('.slider');
|
||||
state.videoFullScreen.fullScreenState = false;
|
||||
HtmlUtils.append(state.el.find('.secondary-controls'), HtmlUtils.HTML(state.videoFullScreen.fullScreenEl));
|
||||
state.videoFullScreen.updateControlsHeight();
|
||||
}
|
||||
function _renderElements(state) {
|
||||
state.videoFullScreen.fullScreenEl = $(template);
|
||||
state.videoFullScreen.sliderEl = state.el.find('.slider');
|
||||
state.videoFullScreen.fullScreenState = false;
|
||||
HtmlUtils.append(state.el.find('.secondary-controls'), HtmlUtils.HTML(state.videoFullScreen.fullScreenEl));
|
||||
state.videoFullScreen.updateControlsHeight();
|
||||
}
|
||||
|
||||
// function _bindHandlers(state)
|
||||
//
|
||||
// Bind any necessary function callbacks to DOM events (click, mousemove, etc.).
|
||||
function _bindHandlers(state) {
|
||||
state.videoFullScreen.fullScreenEl.on('click', state.videoFullScreen.toggleHandler);
|
||||
state.el.on({
|
||||
'fullscreen': state.videoFullScreen.onFullscreenChange,
|
||||
'destroy': state.videoFullScreen.destroy
|
||||
});
|
||||
$(document).on('keyup', state.videoFullScreen.exitHandler);
|
||||
}
|
||||
function _bindHandlers(state) {
|
||||
state.videoFullScreen.fullScreenEl.on('click', state.videoFullScreen.toggleHandler);
|
||||
state.el.on({
|
||||
'fullscreen': state.videoFullScreen.onFullscreenChange,
|
||||
'destroy': state.videoFullScreen.destroy
|
||||
});
|
||||
$(document).on('keyup', state.videoFullScreen.exitHandler);
|
||||
}
|
||||
|
||||
function _getControlsHeight(controls, slider) {
|
||||
return controls.height() + 0.5 * slider.height();
|
||||
}
|
||||
function _getControlsHeight(controls, slider) {
|
||||
return controls.height() + 0.5 * slider.height();
|
||||
}
|
||||
|
||||
// ***************************************************************
|
||||
// Public functions start here.
|
||||
@@ -94,101 +94,99 @@ define('video/04_video_full_screen.js', ['edx-ui-toolkit/js/utils/html-utils'],
|
||||
// The magic private function that makes them available and sets up their context is makeFunctionsPublic().
|
||||
// ***************************************************************
|
||||
|
||||
function onFullscreenChange (event, isFullScreen) {
|
||||
var height = this.videoFullScreen.updateControlsHeight();
|
||||
function onFullscreenChange(event, isFullScreen) {
|
||||
var height = this.videoFullScreen.updateControlsHeight();
|
||||
|
||||
if (isFullScreen) {
|
||||
this.resizer
|
||||
if (isFullScreen) {
|
||||
this.resizer
|
||||
.delta
|
||||
.substract(height, 'height')
|
||||
.setMode('both');
|
||||
|
||||
} else {
|
||||
this.resizer
|
||||
} else {
|
||||
this.resizer
|
||||
.delta
|
||||
.reset()
|
||||
.setMode('width');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateControlsHeight() {
|
||||
var controls = this.el.find('.video-controls'),
|
||||
slider = this.videoFullScreen.sliderEl;
|
||||
this.videoFullScreen.height = _getControlsHeight(controls, slider);
|
||||
return this.videoFullScreen.height;
|
||||
}
|
||||
function updateControlsHeight() {
|
||||
var controls = this.el.find('.video-controls'),
|
||||
slider = this.videoFullScreen.sliderEl;
|
||||
this.videoFullScreen.height = _getControlsHeight(controls, slider);
|
||||
return this.videoFullScreen.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler to toggle fullscreen mode.
|
||||
* @param {jquery Event} event
|
||||
*/
|
||||
function toggleHandler(event) {
|
||||
event.preventDefault();
|
||||
this.videoCommands.execute('toggleFullScreen');
|
||||
}
|
||||
function toggleHandler(event) {
|
||||
event.preventDefault();
|
||||
this.videoCommands.execute('toggleFullScreen');
|
||||
}
|
||||
|
||||
function exit() {
|
||||
var fullScreenClassNameEl = this.el.add(document.documentElement),
|
||||
closedCaptionsEl = this.el.find('.closed-captions');
|
||||
function exit() {
|
||||
var fullScreenClassNameEl = this.el.add(document.documentElement),
|
||||
closedCaptionsEl = this.el.find('.closed-captions');
|
||||
|
||||
this.videoFullScreen.fullScreenState = this.isFullScreen = false;
|
||||
fullScreenClassNameEl.removeClass('video-fullscreen');
|
||||
$(window).scrollTop(this.scrollPos);
|
||||
this.videoFullScreen.fullScreenEl
|
||||
this.videoFullScreen.fullScreenState = this.isFullScreen = false;
|
||||
fullScreenClassNameEl.removeClass('video-fullscreen');
|
||||
$(window).scrollTop(this.scrollPos);
|
||||
this.videoFullScreen.fullScreenEl
|
||||
.attr('title', gettext('Fill browser'))
|
||||
.find('.icon')
|
||||
.removeClass('fa-compress')
|
||||
.addClass('fa-arrows-alt');
|
||||
|
||||
this.el.trigger('fullscreen', [this.isFullScreen]);
|
||||
this.el.trigger('fullscreen', [this.isFullScreen]);
|
||||
|
||||
$(closedCaptionsEl).css({
|
||||
'top': '70%',
|
||||
'left': '5%'
|
||||
});
|
||||
}
|
||||
$(closedCaptionsEl).css({
|
||||
'top': '70%',
|
||||
'left': '5%'
|
||||
});
|
||||
}
|
||||
|
||||
function enter() {
|
||||
var fullScreenClassNameEl = this.el.add(document.documentElement),
|
||||
closedCaptionsEl = this.el.find('.closed-captions');
|
||||
function enter() {
|
||||
var fullScreenClassNameEl = this.el.add(document.documentElement),
|
||||
closedCaptionsEl = this.el.find('.closed-captions');
|
||||
|
||||
this.scrollPos = $(window).scrollTop();
|
||||
$(window).scrollTop(0);
|
||||
this.videoFullScreen.fullScreenState = this.isFullScreen = true;
|
||||
fullScreenClassNameEl.addClass('video-fullscreen');
|
||||
this.videoFullScreen.fullScreenEl
|
||||
this.scrollPos = $(window).scrollTop();
|
||||
$(window).scrollTop(0);
|
||||
this.videoFullScreen.fullScreenState = this.isFullScreen = true;
|
||||
fullScreenClassNameEl.addClass('video-fullscreen');
|
||||
this.videoFullScreen.fullScreenEl
|
||||
.attr('title', gettext('Exit full browser'))
|
||||
.find('.icon')
|
||||
.removeClass('fa-arrows-alt')
|
||||
.addClass('fa-compress');
|
||||
|
||||
this.el.trigger('fullscreen', [this.isFullScreen]);
|
||||
this.el.trigger('fullscreen', [this.isFullScreen]);
|
||||
|
||||
$(closedCaptionsEl).css({
|
||||
'top': '70%',
|
||||
'left': '5%'
|
||||
});
|
||||
}
|
||||
$(closedCaptionsEl).css({
|
||||
'top': '70%',
|
||||
'left': '5%'
|
||||
});
|
||||
}
|
||||
|
||||
/** Toggle fullscreen mode. */
|
||||
function toggle() {
|
||||
if (this.videoFullScreen.fullScreenState) {
|
||||
this.videoFullScreen.exit();
|
||||
} else {
|
||||
this.videoFullScreen.enter();
|
||||
function toggle() {
|
||||
if (this.videoFullScreen.fullScreenState) {
|
||||
this.videoFullScreen.exit();
|
||||
} else {
|
||||
this.videoFullScreen.enter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler to exit from fullscreen mode.
|
||||
* @param {jquery Event} event
|
||||
*/
|
||||
function exitHandler(event) {
|
||||
if ((this.isFullScreen) && (event.keyCode === 27)) {
|
||||
event.preventDefault();
|
||||
this.videoCommands.execute('toggleFullScreen');
|
||||
function exitHandler(event) {
|
||||
if ((this.isFullScreen) && (event.keyCode === 27)) {
|
||||
event.preventDefault();
|
||||
this.videoCommands.execute('toggleFullScreen');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}(RequireJS.define));
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
(function (requirejs, require, define) {
|
||||
|
||||
(function(requirejs, require, define) {
|
||||
// VideoQualityControl module.
|
||||
'use strict';
|
||||
define(
|
||||
'use strict';
|
||||
define(
|
||||
'video/05_video_quality_control.js',
|
||||
['edx-ui-toolkit/js/utils/html-utils'],
|
||||
function (HtmlUtils) {
|
||||
function(HtmlUtils) {
|
||||
var template = HtmlUtils.interpolateHtml(
|
||||
HtmlUtils.HTML([
|
||||
'<button class="control quality-control is-hidden" aria-disabled="false" title="',
|
||||
'{highDefinition}',
|
||||
'{highDefinition}',
|
||||
'">',
|
||||
'<span class="icon icon-hd" aria-hidden="true">HD</span>',
|
||||
'<span class="sr text-translation">',
|
||||
'{highDefinition}',
|
||||
'</span> ',
|
||||
'<span class="sr control-text">',
|
||||
'{off}',
|
||||
'</span>',
|
||||
'<span class="icon icon-hd" aria-hidden="true">HD</span>',
|
||||
'<span class="sr text-translation">',
|
||||
'{highDefinition}',
|
||||
'</span> ',
|
||||
'<span class="sr control-text">',
|
||||
'{off}',
|
||||
'</span>',
|
||||
'</button>'
|
||||
].join('')),
|
||||
{
|
||||
@@ -27,7 +26,7 @@ function (HtmlUtils) {
|
||||
);
|
||||
|
||||
// VideoQualityControl() function - what this module "exports".
|
||||
return function (state) {
|
||||
return function(state) {
|
||||
var dfd = $.Deferred();
|
||||
|
||||
// Changing quality for now only works for YouTube videos.
|
||||
@@ -159,7 +158,6 @@ function (HtmlUtils) {
|
||||
.removeClass('active')
|
||||
.find('.control-text')
|
||||
.text(controlStateStr);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +173,5 @@ function (HtmlUtils) {
|
||||
|
||||
this.trigger('videoPlayer.handlePlaybackQualityChange', newQuality);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
(function (requirejs, require, define) {
|
||||
|
||||
(function(requirejs, require, define) {
|
||||
/*
|
||||
"This is as true in everyday life as it is in battle: we are given one life
|
||||
and the decision is ours whether to wait for circumstances to make up our
|
||||
@@ -8,16 +7,16 @@ mind, or whether to act, and in acting, to live."
|
||||
*/
|
||||
|
||||
// VideoProgressSlider module.
|
||||
define(
|
||||
define(
|
||||
'video/06_video_progress_slider.js',
|
||||
[],
|
||||
function () {
|
||||
function() {
|
||||
var template = [
|
||||
'<div class="slider" title="', gettext('Video position'), '"></div>'
|
||||
].join('');
|
||||
|
||||
// VideoProgressSlider() function - what this module "exports".
|
||||
return function (state) {
|
||||
return function(state) {
|
||||
var dfd = $.Deferred();
|
||||
|
||||
state.videoProgressSlider = {};
|
||||
@@ -298,19 +297,19 @@ function () {
|
||||
var seconds = Math.floor(time),
|
||||
minutes = Math.floor(seconds / 60),
|
||||
hours = Math.floor(minutes / 60),
|
||||
i18n = function (value, word) {
|
||||
i18n = function(value, word) {
|
||||
var msg;
|
||||
|
||||
switch(word) {
|
||||
case 'hour':
|
||||
msg = ngettext('%(value)s hour', '%(value)s hours', value);
|
||||
break;
|
||||
case 'minute':
|
||||
msg = ngettext('%(value)s minute', '%(value)s minutes', value);
|
||||
break;
|
||||
case 'second':
|
||||
msg = ngettext('%(value)s second', '%(value)s seconds', value);
|
||||
break;
|
||||
switch (word) {
|
||||
case 'hour':
|
||||
msg = ngettext('%(value)s hour', '%(value)s hours', value);
|
||||
break;
|
||||
case 'minute':
|
||||
msg = ngettext('%(value)s minute', '%(value)s minutes', value);
|
||||
break;
|
||||
case 'second':
|
||||
msg = ngettext('%(value)s second', '%(value)s seconds', value);
|
||||
break;
|
||||
}
|
||||
return interpolate(msg, {'value': value}, true);
|
||||
};
|
||||
@@ -319,17 +318,15 @@ function () {
|
||||
minutes = minutes % 60;
|
||||
|
||||
if (hours) {
|
||||
return i18n(hours, 'hour') + ' ' +
|
||||
return i18n(hours, 'hour') + ' ' +
|
||||
i18n(minutes, 'minute') + ' ' +
|
||||
i18n(seconds, 'second');
|
||||
} else if (minutes) {
|
||||
return i18n(minutes, 'minute') + ' ' +
|
||||
return i18n(minutes, 'minute') + ' ' +
|
||||
i18n(seconds, 'second');
|
||||
}
|
||||
|
||||
return i18n(seconds, 'second');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(function (define) {
|
||||
'use strict';
|
||||
(function(define) {
|
||||
'use strict';
|
||||
// VideoVolumeControl module.
|
||||
define(
|
||||
define(
|
||||
'video/07_video_volume_control.js', ['edx-ui-toolkit/js/utils/html-utils'],
|
||||
function (HtmlUtils) {
|
||||
function(HtmlUtils) {
|
||||
/**
|
||||
* Video volume control module.
|
||||
* @exports video/07_video_volume_control.js
|
||||
@@ -39,30 +39,30 @@ function (HtmlUtils) {
|
||||
|
||||
videoVolumeControlHtml: HtmlUtils.interpolateHtml(
|
||||
HtmlUtils.HTML([
|
||||
'<div class="volume" role="application">',
|
||||
'<div class="volume" role="application">',
|
||||
'<p class="sr instructions" id="volume-instructions">',
|
||||
'{volumeInstructions}',
|
||||
'{volumeInstructions}',
|
||||
'</p>',
|
||||
'<button class="control" aria-disabled="false" aria-describedby="volume-instructions"',
|
||||
'" aria-expanded="false" title="',
|
||||
'{adjustVideoVolume}',
|
||||
'">',
|
||||
'<span class="icon fa fa-volume-up" aria-hidden="true"></span>',
|
||||
'" aria-expanded="false" title="',
|
||||
'{adjustVideoVolume}',
|
||||
'">',
|
||||
'<span class="icon fa fa-volume-up" aria-hidden="true"></span>',
|
||||
'</button>',
|
||||
'<div class="volume-slider-container" aria-hidden="true" title="',
|
||||
'{adjustVideoVolume}',
|
||||
'">',
|
||||
'<div class="volume-slider" ',
|
||||
'role="slider"',
|
||||
'aria-orientation="vertical" ',
|
||||
'aria-valuemin="0" ',
|
||||
'aria-valuemax="100" ',
|
||||
'aria-valuenow="" ',
|
||||
'aria-label="',
|
||||
'{volumeText}',
|
||||
'"></div>',
|
||||
'{adjustVideoVolume}',
|
||||
'">',
|
||||
'<div class="volume-slider" ',
|
||||
'role="slider"',
|
||||
'aria-orientation="vertical" ',
|
||||
'aria-valuemin="0" ',
|
||||
'aria-valuemax="100" ',
|
||||
'aria-valuenow="" ',
|
||||
'aria-label="',
|
||||
'{volumeText}',
|
||||
'"></div>',
|
||||
'</div>',
|
||||
'</div>'].join('')),
|
||||
'</div>'].join('')),
|
||||
{
|
||||
volumeInstructions: gettext('Click on this button to mute or unmute this video or press UP or DOWN buttons to increase or decrease volume level.'), // eslint-disable-line max-len
|
||||
adjustVideoVolume: gettext('Adjust video volume'),
|
||||
@@ -70,7 +70,7 @@ function (HtmlUtils) {
|
||||
}
|
||||
),
|
||||
|
||||
destroy: function () {
|
||||
destroy: function() {
|
||||
this.volumeSlider.slider('destroy');
|
||||
this.state.el.find('iframe').removeAttr('tabindex');
|
||||
this.a11y.destroy();
|
||||
@@ -230,7 +230,7 @@ function (HtmlUtils) {
|
||||
},
|
||||
|
||||
/** Updates volume slider view. */
|
||||
updateSliderView: function (volume) {
|
||||
updateSliderView: function(volume) {
|
||||
this.volumeSlider.slider('value', volume);
|
||||
this.el.find('.volume-slider')
|
||||
.attr('aria-valuenow', volume);
|
||||
@@ -259,7 +259,7 @@ function (HtmlUtils) {
|
||||
* Returns current volume state (is it muted or not?).
|
||||
* @return {Boolean}
|
||||
*/
|
||||
getMuteStatus: function () {
|
||||
getMuteStatus: function() {
|
||||
return this.getVolume() === 0;
|
||||
},
|
||||
|
||||
@@ -295,12 +295,12 @@ function (HtmlUtils) {
|
||||
* volume level.
|
||||
* @param {Number} volume Volume level.
|
||||
*/
|
||||
checkMuteButtonStatus: function (volume) {
|
||||
checkMuteButtonStatus: function(volume) {
|
||||
if (volume <= this.min) {
|
||||
this.updateMuteButtonView(true);
|
||||
this.state.el.off('volumechange.is-muted');
|
||||
this.state.el.on('volumechange.is-muted', _.once(function () {
|
||||
this.updateMuteButtonView(false);
|
||||
this.state.el.on('volumechange.is-muted', _.once(function() {
|
||||
this.updateMuteButtonView(false);
|
||||
}.bind(this)));
|
||||
}
|
||||
},
|
||||
@@ -336,35 +336,35 @@ function (HtmlUtils) {
|
||||
keyCode = event.keyCode;
|
||||
|
||||
switch (keyCode) {
|
||||
case KEY.UP:
|
||||
case KEY.UP:
|
||||
// Shift + Arrows keyboard shortcut might be used by
|
||||
// screen readers. In this case, do nothing.
|
||||
if (event.shiftKey) {
|
||||
return true;
|
||||
}
|
||||
if (event.shiftKey) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.increaseVolume();
|
||||
return false;
|
||||
case KEY.DOWN:
|
||||
this.increaseVolume();
|
||||
return false;
|
||||
case KEY.DOWN:
|
||||
// Shift + Arrows keyboard shortcut might be used by
|
||||
// screen readers. In this case, do nothing.
|
||||
if (event.shiftKey) {
|
||||
return true;
|
||||
}
|
||||
if (event.shiftKey) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.decreaseVolume();
|
||||
return false;
|
||||
this.decreaseVolume();
|
||||
return false;
|
||||
|
||||
case KEY.SPACE:
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
case KEY.ENTER:
|
||||
// Shift + Enter keyboard shortcut might be used by
|
||||
// screen readers. In this case, do nothing.
|
||||
if (event.shiftKey) {
|
||||
return true;
|
||||
}
|
||||
if (event.shiftKey) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.toggleMute();
|
||||
return false;
|
||||
this.toggleMute();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -374,7 +374,7 @@ function (HtmlUtils) {
|
||||
* Keydown event handler for the volume button.
|
||||
* @param {jquery Event} event
|
||||
*/
|
||||
keyDownButtonHandler: function(event) {
|
||||
keyDownButtonHandler: function(event) {
|
||||
// ALT key is used to change (alternate) the function of
|
||||
// other pressed keys. In this case, do nothing.
|
||||
if (event.altKey) {
|
||||
@@ -385,10 +385,10 @@ function (HtmlUtils) {
|
||||
keyCode = event.keyCode;
|
||||
|
||||
switch (keyCode) {
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
this.toggleMute();
|
||||
return false;
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
this.toggleMute();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -433,7 +433,7 @@ function (HtmlUtils) {
|
||||
* @param {Number} max Maximum value for the volume slider.
|
||||
* @param {Object} i18n The object containing strings with translations.
|
||||
*/
|
||||
var Accessibility = function (button, min, max, i18n) {
|
||||
var Accessibility = function(button, min, max, i18n) {
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.button = button;
|
||||
@@ -443,14 +443,14 @@ function (HtmlUtils) {
|
||||
};
|
||||
|
||||
Accessibility.prototype = {
|
||||
destroy: function () {
|
||||
destroy: function() {
|
||||
this.liveRegion.remove();
|
||||
},
|
||||
|
||||
/** Initializes the module. */
|
||||
initialize: function() {
|
||||
this.liveRegion = $('<div />', {
|
||||
'class': 'sr video-live-region',
|
||||
'class': 'sr video-live-region',
|
||||
'aria-hidden': 'false',
|
||||
'aria-live': 'polite'
|
||||
});
|
||||
@@ -502,7 +502,7 @@ function (HtmlUtils) {
|
||||
* @param {Number} min Minimum value for the volume slider.
|
||||
* @param {Number} max Maximum value for the volume slider.
|
||||
*/
|
||||
var CookieManager = function (min, max) {
|
||||
var CookieManager = function(min, max) {
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.cookieName = 'video_player_volume_level';
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
(function (requirejs, require, define) {
|
||||
"use strict";
|
||||
define(
|
||||
(function(requirejs, require, define) {
|
||||
'use strict';
|
||||
define(
|
||||
'video/08_video_speed_control.js', [
|
||||
'video/00_iterator.js',
|
||||
'edx-ui-toolkit/js/utils/html-utils'
|
||||
], function (Iterator, HtmlUtils) {
|
||||
], function(Iterator, HtmlUtils) {
|
||||
/**
|
||||
* Video speed control module.
|
||||
* @exports video/08_video_speed_control.js
|
||||
@@ -12,7 +12,7 @@ define(
|
||||
* @param {object} state The object containing the state of the video player.
|
||||
* @return {jquery Promise}
|
||||
*/
|
||||
var SpeedControl = function (state) {
|
||||
var SpeedControl = function(state) {
|
||||
if (!(this instanceof SpeedControl)) {
|
||||
return new SpeedControl(state);
|
||||
}
|
||||
@@ -31,26 +31,26 @@ define(
|
||||
SpeedControl.prototype = {
|
||||
template: [
|
||||
'<div class="speeds menu-container" role="application">',
|
||||
'<p class="sr instructions" id="speed-instructions">',
|
||||
'<p class="sr instructions" id="speed-instructions">',
|
||||
gettext('Press UP to enter the speed menu then use the UP and DOWN arrow keys to navigate the different speeds, then press ENTER to change to the selected speed.'), // eslint-disable-line max-len, indent
|
||||
'</p>',
|
||||
'<button class="control speed-button" aria-disabled="false" aria-expanded="false"',
|
||||
'title="',
|
||||
gettext('Adjust video speed'),
|
||||
'" aria-describedby="speed-instructions">',
|
||||
'<span>',
|
||||
'<span class="icon fa fa-caret-right" aria-hidden="true"></span>',
|
||||
'</span>',
|
||||
'<span class="label" aria-hidden="true">',
|
||||
gettext('Speed'),
|
||||
'</span>',
|
||||
'<span class="value"></span>',
|
||||
'</button>',
|
||||
'<ol class="video-speeds menu"></ol>',
|
||||
'</p>',
|
||||
'<button class="control speed-button" aria-disabled="false" aria-expanded="false"',
|
||||
'title="',
|
||||
gettext('Adjust video speed'),
|
||||
'" aria-describedby="speed-instructions">',
|
||||
'<span>',
|
||||
'<span class="icon fa fa-caret-right" aria-hidden="true"></span>',
|
||||
'</span>',
|
||||
'<span class="label" aria-hidden="true">',
|
||||
gettext('Speed'),
|
||||
'</span>',
|
||||
'<span class="value"></span>',
|
||||
'</button>',
|
||||
'<ol class="video-speeds menu"></ol>',
|
||||
'</div>'
|
||||
].join(''),
|
||||
|
||||
destroy: function () {
|
||||
destroy: function() {
|
||||
this.el.off({
|
||||
'mouseenter': this.mouseEnterHandler,
|
||||
'mouseleave': this.mouseLeaveHandler,
|
||||
@@ -69,7 +69,7 @@ define(
|
||||
},
|
||||
|
||||
/** Initializes the module. */
|
||||
initialize: function () {
|
||||
initialize: function() {
|
||||
var state = this.state;
|
||||
|
||||
if (!this.isPlaybackRatesSupported(state)) {
|
||||
@@ -95,19 +95,19 @@ define(
|
||||
* @param {array} speeds List of speeds available for the player.
|
||||
* @param {string} currentSpeed The current speed set to the player.
|
||||
*/
|
||||
render: function (speeds, currentSpeed) {
|
||||
render: function(speeds, currentSpeed) {
|
||||
var speedsContainer = this.speedsContainer,
|
||||
reversedSpeeds = speeds.concat().reverse(),
|
||||
speedsList = $.map(reversedSpeeds, function (speed) {
|
||||
speedsList = $.map(reversedSpeeds, function(speed) {
|
||||
return HtmlUtils.interpolateHtml(
|
||||
HtmlUtils.HTML(
|
||||
[
|
||||
'<li data-speed="{speed}">',
|
||||
'<button class="control speed-option" tabindex="-1" aria-pressed="false">',
|
||||
'{speed}x',
|
||||
'</button>',
|
||||
'</li>'
|
||||
].join('')
|
||||
[
|
||||
'<li data-speed="{speed}">',
|
||||
'<button class="control speed-option" tabindex="-1" aria-pressed="false">',
|
||||
'{speed}x',
|
||||
'</button>',
|
||||
'</li>'
|
||||
].join('')
|
||||
),
|
||||
{
|
||||
speed: speed
|
||||
@@ -131,7 +131,7 @@ define(
|
||||
* Bind any necessary function callbacks to DOM events (click,
|
||||
* mousemove, etc.).
|
||||
*/
|
||||
bindHandlers: function () {
|
||||
bindHandlers: function() {
|
||||
// Attach various events handlers to the speed menu button.
|
||||
this.el.on({
|
||||
'mouseenter': this.mouseEnterHandler,
|
||||
@@ -154,11 +154,11 @@ define(
|
||||
this.state.el.on('destroy', this.destroy);
|
||||
},
|
||||
|
||||
onSetSpeed: function (event, speed) {
|
||||
onSetSpeed: function(event, speed) {
|
||||
this.setSpeed(speed, true);
|
||||
},
|
||||
|
||||
onRenderSpeed: function (event, speeds, currentSpeed) {
|
||||
onRenderSpeed: function(event, speeds, currentSpeed) {
|
||||
this.render(speeds, currentSpeed);
|
||||
},
|
||||
|
||||
@@ -173,7 +173,7 @@ define(
|
||||
* true: Browser support playbackRate functionality.
|
||||
* false: Browser doesn't support playbackRate functionality.
|
||||
*/
|
||||
isPlaybackRatesSupported: function (state) {
|
||||
isPlaybackRatesSupported: function(state) {
|
||||
var isHtml5 = state.videoType === 'html5',
|
||||
isTouch = state.isTouch,
|
||||
video = document.createElement('video');
|
||||
@@ -185,7 +185,7 @@ define(
|
||||
* Opens speed menu.
|
||||
* @param {boolean} [bindEvent] Click event will be attached on window.
|
||||
*/
|
||||
openMenu: function (bindEvent) {
|
||||
openMenu: function(bindEvent) {
|
||||
// When speed entries have focus, the menu stays open on
|
||||
// mouseleave. A clickHandler is added to the window
|
||||
// element to have clicks close the menu when they happen
|
||||
@@ -204,7 +204,7 @@ define(
|
||||
* Closes speed menu.
|
||||
* @param {boolean} [unBindEvent] Click event will be detached from window.
|
||||
*/
|
||||
closeMenu: function (unBindEvent) {
|
||||
closeMenu: function(unBindEvent) {
|
||||
// Remove the previously added clickHandler from window element.
|
||||
if (unBindEvent) {
|
||||
$(window).off('click.speedMenu');
|
||||
@@ -225,7 +225,7 @@ define(
|
||||
* @param {boolean} [forceUpdate] Updates the speed even if it's
|
||||
* not differs from current speed.
|
||||
*/
|
||||
setSpeed: function (speed, silent, forceUpdate) {
|
||||
setSpeed: function(speed, silent, forceUpdate) {
|
||||
if (speed !== this.currentSpeed || forceUpdate) {
|
||||
this.speedsContainer
|
||||
.find('li')
|
||||
@@ -267,7 +267,7 @@ define(
|
||||
* Click event handler for the menu.
|
||||
* @param {jquery Event} event
|
||||
*/
|
||||
clickMenuHandler: function () {
|
||||
clickMenuHandler: function() {
|
||||
this.closeMenu();
|
||||
|
||||
return false;
|
||||
@@ -277,7 +277,7 @@ define(
|
||||
* Click event handler for speed links.
|
||||
* @param {jquery Event} event
|
||||
*/
|
||||
clickLinkHandler: function (event) {
|
||||
clickLinkHandler: function(event) {
|
||||
var el = $(event.currentTarget).parent(),
|
||||
speed = $(el).data('speed');
|
||||
|
||||
@@ -293,7 +293,7 @@ define(
|
||||
* Mouseenter event handler for the menu.
|
||||
* @param {jquery Event} event
|
||||
*/
|
||||
mouseEnterHandler: function () {
|
||||
mouseEnterHandler: function() {
|
||||
this.openMenu();
|
||||
|
||||
return false;
|
||||
@@ -303,12 +303,12 @@ define(
|
||||
* Mouseleave event handler for the menu.
|
||||
* @param {jquery Event} event
|
||||
*/
|
||||
mouseLeaveHandler: function () {
|
||||
mouseLeaveHandler: function() {
|
||||
// Only close the menu is no speed entry has focus.
|
||||
if (!this.speedLinks.list.is(':focus')) {
|
||||
this.closeMenu();
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
@@ -316,33 +316,33 @@ define(
|
||||
* Keydown event handler for the menu.
|
||||
* @param {jquery Event} event
|
||||
*/
|
||||
keyDownMenuHandler: function (event) {
|
||||
keyDownMenuHandler: function(event) {
|
||||
var KEY = $.ui.keyCode,
|
||||
keyCode = event.keyCode;
|
||||
|
||||
switch(keyCode) {
|
||||
switch (keyCode) {
|
||||
// Open menu and focus on last element of list above it.
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
case KEY.UP:
|
||||
this.openMenu(true);
|
||||
this.speedLinks.last().focus();
|
||||
break;
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
case KEY.UP:
|
||||
this.openMenu(true);
|
||||
this.speedLinks.last().focus();
|
||||
break;
|
||||
// Close menu.
|
||||
case KEY.ESCAPE:
|
||||
this.closeMenu(true);
|
||||
break;
|
||||
case KEY.ESCAPE:
|
||||
this.closeMenu(true);
|
||||
break;
|
||||
}
|
||||
// We do not stop propagation and default behavior on a TAB
|
||||
// keypress.
|
||||
return event.keyCode === KEY.TAB;
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Keydown event handler for speed links.
|
||||
* @param {jquery Event} event
|
||||
*/
|
||||
keyDownLinkHandler: function (event) {
|
||||
keyDownLinkHandler: function(event) {
|
||||
// ALT key is used to change (alternate) the function of
|
||||
// other pressed keys. In this, do nothing.
|
||||
if (event.altKey) {
|
||||
@@ -357,57 +357,56 @@ define(
|
||||
|
||||
switch (event.keyCode) {
|
||||
// Close menu.
|
||||
case KEY.TAB:
|
||||
case KEY.TAB:
|
||||
// Closes menu after 25ms delay to change `tabindex` after
|
||||
// finishing default behavior.
|
||||
setTimeout(function () {
|
||||
self.closeMenu(true);
|
||||
}, 25);
|
||||
setTimeout(function() {
|
||||
self.closeMenu(true);
|
||||
}, 25);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
// Close menu and give focus to speed control.
|
||||
case KEY.ESCAPE:
|
||||
this.closeMenu(true);
|
||||
this.speedButton.focus();
|
||||
case KEY.ESCAPE:
|
||||
this.closeMenu(true);
|
||||
this.speedButton.focus();
|
||||
|
||||
return false;
|
||||
return false;
|
||||
// Scroll up menu, wrapping at the top. Keep menu open.
|
||||
case KEY.UP:
|
||||
case KEY.UP:
|
||||
// Shift + Arrows keyboard shortcut might be used by
|
||||
// screen readers. In this, do nothing.
|
||||
if (event.shiftKey) {
|
||||
return true;
|
||||
}
|
||||
if (event.shiftKey) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.speedLinks.prev(index).focus();
|
||||
return false;
|
||||
this.speedLinks.prev(index).focus();
|
||||
return false;
|
||||
// Scroll down menu, wrapping at the bottom. Keep menu
|
||||
// open.
|
||||
case KEY.DOWN:
|
||||
case KEY.DOWN:
|
||||
// Shift + Arrows keyboard shortcut might be used by
|
||||
// screen readers. In this, do nothing.
|
||||
if (event.shiftKey) {
|
||||
return true;
|
||||
}
|
||||
if (event.shiftKey) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.speedLinks.next(index).focus();
|
||||
return false;
|
||||
this.speedLinks.next(index).focus();
|
||||
return false;
|
||||
// Close menu, give focus to speed control and change
|
||||
// speed.
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
this.closeMenu(true);
|
||||
this.speedButton.focus();
|
||||
this.setSpeed(this.state.speedToString(speed));
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
this.closeMenu(true);
|
||||
this.speedButton.focus();
|
||||
this.setSpeed(this.state.speedToString(speed));
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return SpeedControl;
|
||||
});
|
||||
|
||||
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
(function (define) {
|
||||
'use strict';
|
||||
(function(define) {
|
||||
'use strict';
|
||||
// VideoContextMenu module.
|
||||
define(
|
||||
define(
|
||||
'video/095_video_context_menu.js',
|
||||
['video/00_component.js'],
|
||||
function (Component) {
|
||||
function(Component) {
|
||||
var AbstractItem, AbstractMenu, Menu, Overlay, Submenu, MenuItem;
|
||||
|
||||
AbstractItem = Component.extend({
|
||||
initialize: function (options) {
|
||||
initialize: function(options) {
|
||||
this.options = $.extend(true, {
|
||||
label: '',
|
||||
prefix: 'edx-',
|
||||
@@ -26,24 +26,24 @@ function (Component) {
|
||||
this.delegateEvents();
|
||||
this.options.initialize.call(this, this);
|
||||
},
|
||||
destroy: function () {
|
||||
destroy: function() {
|
||||
_.invoke(this.getChildren(), 'destroy');
|
||||
this.undelegateEvents();
|
||||
this.getElement().remove();
|
||||
},
|
||||
open: function () {
|
||||
open: function() {
|
||||
this.getElement().addClass('is-opened');
|
||||
return this;
|
||||
},
|
||||
close: function () { },
|
||||
closeSiblings: function () {
|
||||
close: function() { },
|
||||
closeSiblings: function() {
|
||||
_.invoke(this.getSiblings(), 'close');
|
||||
return this;
|
||||
},
|
||||
getElement: function () {
|
||||
getElement: function() {
|
||||
return this.element;
|
||||
},
|
||||
addChild: function (child) {
|
||||
addChild: function(child) {
|
||||
var firstChild = null, lastChild = null;
|
||||
if (this.hasChildren()) {
|
||||
lastChild = this.getLastChild();
|
||||
@@ -57,51 +57,51 @@ function (Component) {
|
||||
this.children.push(child);
|
||||
return this;
|
||||
},
|
||||
getChildren: function () {
|
||||
getChildren: function() {
|
||||
// Returns the copy.
|
||||
return this.children.concat();
|
||||
},
|
||||
hasChildren: function () {
|
||||
hasChildren: function() {
|
||||
return this.getChildren().length > 0;
|
||||
},
|
||||
getFirstChild: function () {
|
||||
getFirstChild: function() {
|
||||
return _.first(this.children);
|
||||
},
|
||||
getLastChild: function () {
|
||||
getLastChild: function() {
|
||||
return _.last(this.children);
|
||||
},
|
||||
bindEvent: function (element, events, handler) {
|
||||
bindEvent: function(element, events, handler) {
|
||||
$(element).on(this.addNamespace(events), handler);
|
||||
return this;
|
||||
},
|
||||
getNext: function () {
|
||||
getNext: function() {
|
||||
var item = this.next;
|
||||
while (item.isHidden() && this.id !== item.id) { item = item.next; }
|
||||
return item;
|
||||
},
|
||||
getPrev: function () {
|
||||
getPrev: function() {
|
||||
var item = this.prev;
|
||||
while (item.isHidden() && this.id !== item.id) { item = item.prev; }
|
||||
return item;
|
||||
},
|
||||
createElement: function () {
|
||||
createElement: function() {
|
||||
return null;
|
||||
},
|
||||
getRoot: function () {
|
||||
getRoot: function() {
|
||||
var item = this;
|
||||
while (item.parent) { item = item.parent; }
|
||||
return item;
|
||||
},
|
||||
populateElement: function () { },
|
||||
focus: function () {
|
||||
populateElement: function() { },
|
||||
focus: function() {
|
||||
this.getElement().focus();
|
||||
this.closeSiblings();
|
||||
return this;
|
||||
},
|
||||
isHidden: function () {
|
||||
isHidden: function() {
|
||||
return this.getElement().is(':hidden');
|
||||
},
|
||||
getSiblings: function () {
|
||||
getSiblings: function() {
|
||||
var items = [],
|
||||
item = this;
|
||||
while (item.next && item.next.id !== this.id) {
|
||||
@@ -110,33 +110,33 @@ function (Component) {
|
||||
}
|
||||
return items;
|
||||
},
|
||||
select: function () { },
|
||||
unselect: function () { },
|
||||
setLabel: function () { },
|
||||
itemHandler: function () { },
|
||||
keyDownHandler: function () { },
|
||||
delegateEvents: function () { },
|
||||
undelegateEvents: function () {
|
||||
select: function() { },
|
||||
unselect: function() { },
|
||||
setLabel: function() { },
|
||||
itemHandler: function() { },
|
||||
keyDownHandler: function() { },
|
||||
delegateEvents: function() { },
|
||||
undelegateEvents: function() {
|
||||
this.getElement().off('.' + this.id);
|
||||
},
|
||||
addNamespace: function (events) {
|
||||
return _.map(events.split(/\s+/), function (event) {
|
||||
addNamespace: function(events) {
|
||||
return _.map(events.split(/\s+/), function(event) {
|
||||
return event + '.' + this.id;
|
||||
}, this).join(' ');
|
||||
}
|
||||
});
|
||||
|
||||
AbstractMenu = AbstractItem.extend({
|
||||
delegateEvents: function () {
|
||||
delegateEvents: function() {
|
||||
this.bindEvent(this.getElement(), 'keydown mouseleave mouseover', this.itemHandler.bind(this))
|
||||
.bindEvent(this.getElement(), 'contextmenu', function (event) { event.preventDefault(); });
|
||||
.bindEvent(this.getElement(), 'contextmenu', function(event) { event.preventDefault(); });
|
||||
return this;
|
||||
},
|
||||
|
||||
populateElement: function () {
|
||||
populateElement: function() {
|
||||
var fragment = document.createDocumentFragment();
|
||||
|
||||
_.each(this.getChildren(), function (child) {
|
||||
_.each(this.getChildren(), function(child) {
|
||||
fragment.appendChild(child.populateElement()[0]);
|
||||
}, this);
|
||||
|
||||
@@ -145,40 +145,40 @@ function (Component) {
|
||||
return this.getElement();
|
||||
},
|
||||
|
||||
close: function () {
|
||||
close: function() {
|
||||
this.closeChildren();
|
||||
this.getElement().removeClass('is-opened');
|
||||
return this;
|
||||
},
|
||||
|
||||
closeChildren: function () {
|
||||
closeChildren: function() {
|
||||
_.invoke(this.getChildren(), 'close');
|
||||
return this;
|
||||
},
|
||||
|
||||
itemHandler: function (event) {
|
||||
itemHandler: function(event) {
|
||||
event.preventDefault();
|
||||
var item = $(event.target).data('menu');
|
||||
switch(event.type) {
|
||||
case 'keydown':
|
||||
this.keyDownHandler.call(this, event, item);
|
||||
break;
|
||||
case 'mouseover':
|
||||
this.mouseOverHandler.call(this, event, item);
|
||||
break;
|
||||
case 'mouseleave':
|
||||
this.mouseLeaveHandler.call(this, event, item);
|
||||
break;
|
||||
switch (event.type) {
|
||||
case 'keydown':
|
||||
this.keyDownHandler.call(this, event, item);
|
||||
break;
|
||||
case 'mouseover':
|
||||
this.mouseOverHandler.call(this, event, item);
|
||||
break;
|
||||
case 'mouseleave':
|
||||
this.mouseLeaveHandler.call(this, event, item);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
keyDownHandler: function () { },
|
||||
mouseOverHandler: function () { },
|
||||
mouseLeaveHandler: function () { }
|
||||
keyDownHandler: function() { },
|
||||
mouseOverHandler: function() { },
|
||||
mouseLeaveHandler: function() { }
|
||||
});
|
||||
|
||||
Menu = AbstractMenu.extend({
|
||||
initialize: function (options, contextmenuElement, container) {
|
||||
initialize: function(options, contextmenuElement, container) {
|
||||
this.contextmenuElement = $(contextmenuElement);
|
||||
this.container = $(container);
|
||||
this.overlay = this.getOverlay();
|
||||
@@ -186,7 +186,7 @@ function (Component) {
|
||||
this.build(this, this.options.items);
|
||||
},
|
||||
|
||||
createElement: function () {
|
||||
createElement: function() {
|
||||
return $('<ol />', {
|
||||
'class': ['contextmenu', this.options.prefix + 'contextmenu'].join(' '),
|
||||
'role': 'menu',
|
||||
@@ -194,40 +194,40 @@ function (Component) {
|
||||
});
|
||||
},
|
||||
|
||||
delegateEvents: function () {
|
||||
delegateEvents: function() {
|
||||
AbstractMenu.prototype.delegateEvents.call(this);
|
||||
this.bindEvent(this.contextmenuElement, 'contextmenu', this.contextmenuHandler.bind(this))
|
||||
.bindEvent(window, 'resize', _.debounce(this.close.bind(this), 100));
|
||||
return this;
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
destroy: function() {
|
||||
AbstractMenu.prototype.destroy.call(this);
|
||||
this.overlay.destroy();
|
||||
this.contextmenuElement.removeData('contextmenu');
|
||||
return this;
|
||||
},
|
||||
|
||||
undelegateEvents: function () {
|
||||
undelegateEvents: function() {
|
||||
AbstractMenu.prototype.undelegateEvents.call(this);
|
||||
this.contextmenuElement.off(this.addNamespace('contextmenu'));
|
||||
this.overlay.undelegateEvents();
|
||||
return this;
|
||||
},
|
||||
|
||||
appendContent: function (content) {
|
||||
appendContent: function(content) {
|
||||
this.getElement().append(content);
|
||||
return this;
|
||||
},
|
||||
|
||||
addChild: function () {
|
||||
addChild: function() {
|
||||
AbstractMenu.prototype.addChild.apply(this, arguments);
|
||||
this.next = this.getFirstChild();
|
||||
this.prev = this.getLastChild();
|
||||
return this;
|
||||
},
|
||||
|
||||
build: function (container, items) {
|
||||
build: function(container, items) {
|
||||
_.each(items, function(item) {
|
||||
var child;
|
||||
if (_.has(item, 'items')) {
|
||||
@@ -240,12 +240,12 @@ function (Component) {
|
||||
return container;
|
||||
},
|
||||
|
||||
focus: function () {
|
||||
focus: function() {
|
||||
this.getElement().focus();
|
||||
return this;
|
||||
},
|
||||
|
||||
open: function () {
|
||||
open: function() {
|
||||
var menu = (this.isRendered) ? this.getElement() : this.populateElement();
|
||||
this.container.append(menu);
|
||||
AbstractItem.prototype.open.call(this);
|
||||
@@ -253,7 +253,7 @@ function (Component) {
|
||||
return this;
|
||||
},
|
||||
|
||||
close: function () {
|
||||
close: function() {
|
||||
AbstractMenu.prototype.close.call(this);
|
||||
this.getElement().detach();
|
||||
this.overlay.hide();
|
||||
@@ -271,7 +271,7 @@ function (Component) {
|
||||
return this;
|
||||
},
|
||||
|
||||
pointInContainerBox: function (x, y) {
|
||||
pointInContainerBox: function(x, y) {
|
||||
var containerOffset = this.contextmenuElement.offset(),
|
||||
containerBox = {
|
||||
x0: containerOffset.left,
|
||||
@@ -282,10 +282,10 @@ function (Component) {
|
||||
return containerBox.x0 <= x && x <= containerBox.x1 && containerBox.y0 <= y && y <= containerBox.y1;
|
||||
},
|
||||
|
||||
getOverlay: function () {
|
||||
getOverlay: function() {
|
||||
return new Overlay(
|
||||
this.close.bind(this),
|
||||
function (event) {
|
||||
function(event) {
|
||||
event.preventDefault();
|
||||
if (this.pointInContainerBox(event.pageX, event.pageY)) {
|
||||
this.position(event).focus();
|
||||
@@ -293,45 +293,44 @@ function (Component) {
|
||||
} else {
|
||||
this.close();
|
||||
}
|
||||
|
||||
}.bind(this)
|
||||
);
|
||||
},
|
||||
|
||||
contextmenuHandler: function (event) {
|
||||
contextmenuHandler: function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.open().position(event).focus();
|
||||
},
|
||||
|
||||
keyDownHandler: function (event, item) {
|
||||
keyDownHandler: function(event, item) {
|
||||
var KEY = $.ui.keyCode,
|
||||
keyCode = event.keyCode;
|
||||
|
||||
switch (keyCode) {
|
||||
case KEY.UP:
|
||||
item.getPrev().focus();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case KEY.DOWN:
|
||||
item.getNext().focus();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case KEY.TAB:
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case KEY.ESCAPE:
|
||||
this.close();
|
||||
break;
|
||||
case KEY.UP:
|
||||
item.getPrev().focus();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case KEY.DOWN:
|
||||
item.getNext().focus();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case KEY.TAB:
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case KEY.ESCAPE:
|
||||
this.close();
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Overlay = Component.extend({
|
||||
ns: '.overlay',
|
||||
initialize: function (clickHandler, contextmenuHandler) {
|
||||
initialize: function(clickHandler, contextmenuHandler) {
|
||||
this.element = $('<div />', {
|
||||
'class': 'overlay'
|
||||
});
|
||||
@@ -339,37 +338,37 @@ function (Component) {
|
||||
this.contextmenuHandler = contextmenuHandler;
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
destroy: function() {
|
||||
this.getElement().remove();
|
||||
this.undelegateEvents();
|
||||
},
|
||||
|
||||
getElement: function () {
|
||||
getElement: function() {
|
||||
return this.element;
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
hide: function() {
|
||||
this.getElement().detach();
|
||||
this.undelegateEvents();
|
||||
return this;
|
||||
},
|
||||
|
||||
show: function (container) {
|
||||
show: function(container) {
|
||||
$(container).append(this.getElement());
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
},
|
||||
|
||||
delegateEvents: function () {
|
||||
delegateEvents: function() {
|
||||
var self = this;
|
||||
$(document)
|
||||
.on('click' + this.ns, function () {
|
||||
.on('click' + this.ns, function() {
|
||||
if (_.isFunction(self.clickHandler)) {
|
||||
self.clickHandler.apply(this, arguments);
|
||||
}
|
||||
self.hide();
|
||||
})
|
||||
.on('contextmenu' + this.ns, function () {
|
||||
.on('contextmenu' + this.ns, function() {
|
||||
if (_.isFunction(self.contextmenuHandler)) {
|
||||
self.contextmenuHandler.apply(this, arguments);
|
||||
}
|
||||
@@ -377,21 +376,21 @@ function (Component) {
|
||||
return this;
|
||||
},
|
||||
|
||||
undelegateEvents: function () {
|
||||
undelegateEvents: function() {
|
||||
$(document).off(this.ns);
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
Submenu = AbstractMenu.extend({
|
||||
initialize: function (options, contextmenuElement) {
|
||||
initialize: function(options, contextmenuElement) {
|
||||
this.contextmenuElement = contextmenuElement;
|
||||
AbstractMenu.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
createElement: function () {
|
||||
createElement: function() {
|
||||
var element = $('<li />', {
|
||||
'class': ['submenu-item','menu-item', this.options.prefix + 'submenu-item'].join(' '),
|
||||
'class': ['submenu-item', 'menu-item', this.options.prefix + 'submenu-item'].join(' '),
|
||||
'aria-expanded': 'false',
|
||||
'aria-haspopup': 'true',
|
||||
'aria-labelledby': 'submenu-item-label-' + this.id,
|
||||
@@ -412,17 +411,17 @@ function (Component) {
|
||||
return element;
|
||||
},
|
||||
|
||||
appendContent: function (content) {
|
||||
appendContent: function(content) {
|
||||
this.list.append(content);
|
||||
return this;
|
||||
},
|
||||
|
||||
setLabel: function (label) {
|
||||
setLabel: function(label) {
|
||||
this.label.text(label);
|
||||
return this;
|
||||
},
|
||||
|
||||
openKeyboard: function () {
|
||||
openKeyboard: function() {
|
||||
if (this.hasChildren()) {
|
||||
this.open();
|
||||
this.getFirstChild().focus();
|
||||
@@ -430,40 +429,40 @@ function (Component) {
|
||||
return this;
|
||||
},
|
||||
|
||||
keyDownHandler: function (event) {
|
||||
keyDownHandler: function(event) {
|
||||
var KEY = $.ui.keyCode,
|
||||
keyCode = event.keyCode;
|
||||
|
||||
switch (keyCode) {
|
||||
case KEY.LEFT:
|
||||
this.close().focus();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case KEY.RIGHT:
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
this.openKeyboard();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case KEY.LEFT:
|
||||
this.close().focus();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case KEY.RIGHT:
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
this.openKeyboard();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
},
|
||||
|
||||
open: function () {
|
||||
open: function() {
|
||||
AbstractMenu.prototype.open.call(this);
|
||||
this.getElement().attr({'aria-expanded': 'true'});
|
||||
this.position();
|
||||
return this;
|
||||
},
|
||||
|
||||
close: function () {
|
||||
close: function() {
|
||||
AbstractMenu.prototype.close.call(this);
|
||||
this.getElement().attr({'aria-expanded': 'false'});
|
||||
return this;
|
||||
},
|
||||
|
||||
position: function () {
|
||||
position: function() {
|
||||
this.list.position({
|
||||
my: 'left top',
|
||||
at: 'right top',
|
||||
@@ -474,13 +473,13 @@ function (Component) {
|
||||
return this;
|
||||
},
|
||||
|
||||
mouseOverHandler: function () {
|
||||
mouseOverHandler: function() {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = setTimeout(this.open.bind(this), 200);
|
||||
this.focus();
|
||||
},
|
||||
|
||||
mouseLeaveHandler: function () {
|
||||
mouseLeaveHandler: function() {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = setTimeout(this.close.bind(this), 200);
|
||||
this.focus();
|
||||
@@ -488,7 +487,7 @@ function (Component) {
|
||||
});
|
||||
|
||||
MenuItem = AbstractItem.extend({
|
||||
createElement: function () {
|
||||
createElement: function() {
|
||||
var classNames = [
|
||||
'menu-item', this.options.prefix + 'menu-item',
|
||||
this.options.isSelected ? 'is-selected' : ''
|
||||
@@ -503,21 +502,21 @@ function (Component) {
|
||||
});
|
||||
},
|
||||
|
||||
populateElement: function () {
|
||||
populateElement: function() {
|
||||
return this.getElement();
|
||||
},
|
||||
|
||||
delegateEvents: function () {
|
||||
delegateEvents: function() {
|
||||
this.bindEvent(this.getElement(), 'click keydown contextmenu mouseover', this.itemHandler.bind(this));
|
||||
return this;
|
||||
},
|
||||
|
||||
setLabel: function (label) {
|
||||
setLabel: function(label) {
|
||||
this.getElement().text(label);
|
||||
return this;
|
||||
},
|
||||
|
||||
select: function (event) {
|
||||
select: function(event) {
|
||||
this.options.callback.call(this, event, this, this.options);
|
||||
this.getElement()
|
||||
.addClass('is-selected')
|
||||
@@ -528,80 +527,79 @@ function (Component) {
|
||||
return this;
|
||||
},
|
||||
|
||||
unselect: function () {
|
||||
unselect: function() {
|
||||
this.getElement()
|
||||
.removeClass('is-selected')
|
||||
.attr({'aria-selected': 'false'});
|
||||
return this;
|
||||
},
|
||||
|
||||
itemHandler: function (event) {
|
||||
itemHandler: function(event) {
|
||||
event.preventDefault();
|
||||
switch(event.type) {
|
||||
case 'contextmenu':
|
||||
case 'click':
|
||||
this.select();
|
||||
break;
|
||||
case 'mouseover':
|
||||
this.focus();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case 'keydown':
|
||||
this.keyDownHandler.call(this, event, this);
|
||||
break;
|
||||
switch (event.type) {
|
||||
case 'contextmenu':
|
||||
case 'click':
|
||||
this.select();
|
||||
break;
|
||||
case 'mouseover':
|
||||
this.focus();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case 'keydown':
|
||||
this.keyDownHandler.call(this, event, this);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
keyDownHandler: function (event) {
|
||||
keyDownHandler: function(event) {
|
||||
var KEY = $.ui.keyCode,
|
||||
keyCode = event.keyCode;
|
||||
|
||||
switch (keyCode) {
|
||||
case KEY.RIGHT:
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
this.select();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case KEY.RIGHT:
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
this.select();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// VideoContextMenu() function - what this module 'exports'.
|
||||
return function (state, i18n) {
|
||||
|
||||
var speedCallback = function (event, menuitem, options) {
|
||||
return function(state, i18n) {
|
||||
var speedCallback = function(event, menuitem, options) {
|
||||
var speed = parseFloat(options.label);
|
||||
state.videoCommands.execute('speed', speed);
|
||||
},
|
||||
options = {
|
||||
items: [{
|
||||
label: i18n.Play,
|
||||
callback: function () {
|
||||
callback: function() {
|
||||
state.videoCommands.execute('togglePlayback');
|
||||
},
|
||||
initialize: function (menuitem) {
|
||||
initialize: function(menuitem) {
|
||||
state.el.on({
|
||||
'play': function () {
|
||||
'play': function() {
|
||||
menuitem.setLabel(i18n.Pause);
|
||||
},
|
||||
'pause': function () {
|
||||
'pause': function() {
|
||||
menuitem.setLabel(i18n.Play);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
label: state.videoVolumeControl.getMuteStatus() ? i18n.Unmute : i18n.Mute,
|
||||
callback: function () {
|
||||
callback: function() {
|
||||
state.videoCommands.execute('toggleMute');
|
||||
},
|
||||
initialize: function (menuitem) {
|
||||
initialize: function(menuitem) {
|
||||
state.el.on({
|
||||
'volumechange': function () {
|
||||
'volumechange': function() {
|
||||
if (state.videoVolumeControl.getMuteStatus()) {
|
||||
menuitem.setLabel(i18n.Unmute);
|
||||
} else {
|
||||
@@ -612,12 +610,12 @@ function (Component) {
|
||||
}
|
||||
}, {
|
||||
label: i18n['Fill browser'],
|
||||
callback: function () {
|
||||
callback: function() {
|
||||
state.videoCommands.execute('toggleFullScreen');
|
||||
},
|
||||
initialize: function (menuitem) {
|
||||
initialize: function(menuitem) {
|
||||
state.el.on({
|
||||
'fullscreen': function (event, isFullscreen) {
|
||||
'fullscreen': function(event, isFullscreen) {
|
||||
if (isFullscreen) {
|
||||
menuitem.setLabel(i18n['Exit full browser']);
|
||||
} else {
|
||||
@@ -628,14 +626,14 @@ function (Component) {
|
||||
}
|
||||
}, {
|
||||
label: i18n.Speed,
|
||||
items: _.map(state.speeds, function (speed) {
|
||||
items: _.map(state.speeds, function(speed) {
|
||||
var isSelected = speed === state.speed;
|
||||
return {label: speed + 'x', callback: speedCallback, speed: speed, isSelected: isSelected};
|
||||
}),
|
||||
initialize: function (menuitem) {
|
||||
initialize: function(menuitem) {
|
||||
state.el.on({
|
||||
'speedchange': function (event, speed) {
|
||||
var item = menuitem.getChildren().filter(function (item) {
|
||||
'speedchange': function(event, speed) {
|
||||
var item = menuitem.getChildren().filter(function(item) {
|
||||
return item.options.speed === speed;
|
||||
})[0];
|
||||
if (item) {
|
||||
@@ -646,9 +644,9 @@ function (Component) {
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
$.fn.contextmenu = function (container, options) {
|
||||
$.fn.contextmenu = function(container, options) {
|
||||
return this.each(function() {
|
||||
$(this).data('contextmenu', new Menu(options, this, container));
|
||||
});
|
||||
@@ -656,7 +654,7 @@ function (Component) {
|
||||
|
||||
if (!state.isYoutubeType()) {
|
||||
state.el.find('video').contextmenu(state.el, options);
|
||||
state.el.on('destroy', function () {
|
||||
state.el.on('destroy', function() {
|
||||
var contextmenu = $(this).find('video').data('contextmenu');
|
||||
if (contextmenu) {
|
||||
contextmenu.destroy();
|
||||
@@ -667,5 +665,4 @@ function (Component) {
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
});
|
||||
|
||||
}(RequireJS.define));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function (define) {
|
||||
'use strict';
|
||||
define('video/09_bumper.js',[], function () {
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define('video/09_bumper.js', [], function() {
|
||||
/**
|
||||
* VideoBumper module.
|
||||
* @exports video/09_bumper.js
|
||||
@@ -9,103 +9,103 @@ define('video/09_bumper.js',[], function () {
|
||||
* @param {Object} state The object containing the state of the video
|
||||
* @return {jquery Promise}
|
||||
*/
|
||||
var VideoBumper = function (player, state) {
|
||||
if (!(this instanceof VideoBumper)) {
|
||||
return new VideoBumper(player, state);
|
||||
}
|
||||
var VideoBumper = function(player, state) {
|
||||
if (!(this instanceof VideoBumper)) {
|
||||
return new VideoBumper(player, state);
|
||||
}
|
||||
|
||||
_.bindAll(
|
||||
_.bindAll(
|
||||
this, 'showMainVideoHandler', 'destroy', 'skipByDuration', 'destroyAndResolve'
|
||||
);
|
||||
this.dfd = $.Deferred();
|
||||
this.element = state.el;
|
||||
this.element.addClass('is-bumper');
|
||||
this.player = player;
|
||||
this.state = state;
|
||||
this.doNotShowAgain = false;
|
||||
this.state.videoBumper = this;
|
||||
this.bindHandlers();
|
||||
this.initialize();
|
||||
this.maxBumperDuration = 35; // seconds
|
||||
};
|
||||
this.dfd = $.Deferred();
|
||||
this.element = state.el;
|
||||
this.element.addClass('is-bumper');
|
||||
this.player = player;
|
||||
this.state = state;
|
||||
this.doNotShowAgain = false;
|
||||
this.state.videoBumper = this;
|
||||
this.bindHandlers();
|
||||
this.initialize();
|
||||
this.maxBumperDuration = 35; // seconds
|
||||
};
|
||||
|
||||
VideoBumper.prototype = {
|
||||
initialize: function () {
|
||||
this.player();
|
||||
},
|
||||
VideoBumper.prototype = {
|
||||
initialize: function() {
|
||||
this.player();
|
||||
},
|
||||
|
||||
getPromise: function () {
|
||||
return this.dfd.promise();
|
||||
},
|
||||
getPromise: function() {
|
||||
return this.dfd.promise();
|
||||
},
|
||||
|
||||
showMainVideoHandler: function () {
|
||||
this.state.storage.setItem('isBumperShown', true);
|
||||
setTimeout(function () {
|
||||
this.saveState();
|
||||
this.showMainVideo();
|
||||
}.bind(this), 20);
|
||||
},
|
||||
showMainVideoHandler: function() {
|
||||
this.state.storage.setItem('isBumperShown', true);
|
||||
setTimeout(function() {
|
||||
this.saveState();
|
||||
this.showMainVideo();
|
||||
}.bind(this), 20);
|
||||
},
|
||||
|
||||
destroyAndResolve: function () {
|
||||
this.destroy();
|
||||
this.dfd.resolve();
|
||||
},
|
||||
destroyAndResolve: function() {
|
||||
this.destroy();
|
||||
this.dfd.resolve();
|
||||
},
|
||||
|
||||
showMainVideo: function () {
|
||||
if (this.state.videoPlayer) {
|
||||
this.destroyAndResolve();
|
||||
} else {
|
||||
this.state.el.on('initialize', this.destroyAndResolve);
|
||||
showMainVideo: function() {
|
||||
if (this.state.videoPlayer) {
|
||||
this.destroyAndResolve();
|
||||
} else {
|
||||
this.state.el.on('initialize', this.destroyAndResolve);
|
||||
}
|
||||
},
|
||||
|
||||
skip: function() {
|
||||
this.element.trigger('skip', [this.doNotShowAgain]);
|
||||
this.showMainVideoHandler();
|
||||
},
|
||||
|
||||
skipAndDoNotShowAgain: function() {
|
||||
this.doNotShowAgain = true;
|
||||
this.skip();
|
||||
},
|
||||
|
||||
skipByDuration: function(event, time) {
|
||||
if (time > this.maxBumperDuration) {
|
||||
this.element.trigger('ended');
|
||||
}
|
||||
},
|
||||
|
||||
bindHandlers: function() {
|
||||
var events = ['ended', 'error'].join(' ');
|
||||
this.element.on(events, this.showMainVideoHandler);
|
||||
this.element.on('timeupdate', this.skipByDuration);
|
||||
},
|
||||
|
||||
saveState: function() {
|
||||
var info = {bumper_last_view_date: true};
|
||||
if (this.doNotShowAgain) {
|
||||
_.extend(info, {bumper_do_not_show_again: true});
|
||||
}
|
||||
if (this.state.videoSaveStatePlugin) {
|
||||
this.state.videoSaveStatePlugin.saveState(true, info);
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
var events = ['ended', 'error'].join(' ');
|
||||
this.element.off(events, this.showMainVideoHandler);
|
||||
this.element.off({
|
||||
'timeupdate': this.skipByDuration,
|
||||
'initialize': this.destroyAndResolve
|
||||
});
|
||||
this.element.removeClass('is-bumper');
|
||||
if (_.isFunction(this.state.videoPlayer.destroy)) {
|
||||
this.state.videoPlayer.destroy();
|
||||
}
|
||||
delete this.state.videoBumper;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
skip: function () {
|
||||
this.element.trigger('skip', [this.doNotShowAgain]);
|
||||
this.showMainVideoHandler();
|
||||
},
|
||||
|
||||
skipAndDoNotShowAgain: function () {
|
||||
this.doNotShowAgain = true;
|
||||
this.skip();
|
||||
},
|
||||
|
||||
skipByDuration: function (event, time) {
|
||||
if (time > this.maxBumperDuration) {
|
||||
this.element.trigger('ended');
|
||||
}
|
||||
},
|
||||
|
||||
bindHandlers: function () {
|
||||
var events = ['ended', 'error'].join(' ');
|
||||
this.element.on(events, this.showMainVideoHandler);
|
||||
this.element.on('timeupdate', this.skipByDuration);
|
||||
},
|
||||
|
||||
saveState: function () {
|
||||
var info = {bumper_last_view_date: true};
|
||||
if (this.doNotShowAgain) {
|
||||
_.extend(info, {bumper_do_not_show_again: true});
|
||||
}
|
||||
if (this.state.videoSaveStatePlugin) {
|
||||
this.state.videoSaveStatePlugin.saveState(true, info);
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
var events = ['ended', 'error'].join(' ');
|
||||
this.element.off(events, this.showMainVideoHandler);
|
||||
this.element.off({
|
||||
'timeupdate': this.skipByDuration,
|
||||
'initialize': this.destroyAndResolve
|
||||
});
|
||||
this.element.removeClass('is-bumper');
|
||||
if (_.isFunction(this.state.videoPlayer.destroy)) {
|
||||
this.state.videoPlayer.destroy();
|
||||
}
|
||||
delete this.state.videoBumper;
|
||||
}
|
||||
};
|
||||
|
||||
return VideoBumper;
|
||||
});
|
||||
return VideoBumper;
|
||||
});
|
||||
}(RequireJS.define));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define('video/09_events_bumper_plugin.js', [], function() {
|
||||
'use strict';
|
||||
define('video/09_events_bumper_plugin.js', [], function() {
|
||||
/**
|
||||
* Events module.
|
||||
* @exports video/09_events_bumper_plugin.js
|
||||
@@ -10,103 +10,103 @@ define('video/09_events_bumper_plugin.js', [], function() {
|
||||
* @param {Object} options
|
||||
* @return {jquery Promise}
|
||||
*/
|
||||
var EventsBumperPlugin = function(state, i18n, options) {
|
||||
if (!(this instanceof EventsBumperPlugin)) {
|
||||
return new EventsBumperPlugin(state, i18n, options);
|
||||
}
|
||||
var EventsBumperPlugin = function(state, i18n, options) {
|
||||
if (!(this instanceof EventsBumperPlugin)) {
|
||||
return new EventsBumperPlugin(state, i18n, options);
|
||||
}
|
||||
|
||||
_.bindAll(this, 'onReady', 'onPlay', 'onEnded', 'onShowLanguageMenu', 'onHideLanguageMenu', 'onSkip',
|
||||
_.bindAll(this, 'onReady', 'onPlay', 'onEnded', 'onShowLanguageMenu', 'onHideLanguageMenu', 'onSkip',
|
||||
'onShowCaptions', 'onHideCaptions', 'destroy');
|
||||
this.state = state;
|
||||
this.options = _.extend({}, options);
|
||||
this.state.videoEventsBumperPlugin = this;
|
||||
this.i18n = i18n;
|
||||
this.initialize();
|
||||
this.state = state;
|
||||
this.options = _.extend({}, options);
|
||||
this.state.videoEventsBumperPlugin = this;
|
||||
this.i18n = i18n;
|
||||
this.initialize();
|
||||
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
|
||||
EventsBumperPlugin.moduleName = 'EventsBumperPlugin';
|
||||
EventsBumperPlugin.prototype = {
|
||||
destroy: function () {
|
||||
this.state.el.off(this.events);
|
||||
delete this.state.videoEventsBumperPlugin;
|
||||
},
|
||||
EventsBumperPlugin.moduleName = 'EventsBumperPlugin';
|
||||
EventsBumperPlugin.prototype = {
|
||||
destroy: function() {
|
||||
this.state.el.off(this.events);
|
||||
delete this.state.videoEventsBumperPlugin;
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
this.events = {
|
||||
'ready': this.onReady,
|
||||
'play': this.onPlay,
|
||||
'ended stop': this.onEnded,
|
||||
'skip': this.onSkip,
|
||||
'language_menu:show': this.onShowLanguageMenu,
|
||||
'language_menu:hide': this.onHideLanguageMenu,
|
||||
'captions:show': this.onShowCaptions,
|
||||
'captions:hide': this.onHideCaptions,
|
||||
'destroy': this.destroy
|
||||
};
|
||||
this.bindHandlers();
|
||||
},
|
||||
initialize: function() {
|
||||
this.events = {
|
||||
'ready': this.onReady,
|
||||
'play': this.onPlay,
|
||||
'ended stop': this.onEnded,
|
||||
'skip': this.onSkip,
|
||||
'language_menu:show': this.onShowLanguageMenu,
|
||||
'language_menu:hide': this.onHideLanguageMenu,
|
||||
'captions:show': this.onShowCaptions,
|
||||
'captions:hide': this.onHideCaptions,
|
||||
'destroy': this.destroy
|
||||
};
|
||||
this.bindHandlers();
|
||||
},
|
||||
|
||||
bindHandlers: function() {
|
||||
this.state.el.on(this.events);
|
||||
},
|
||||
bindHandlers: function() {
|
||||
this.state.el.on(this.events);
|
||||
},
|
||||
|
||||
onReady: function () {
|
||||
this.log('edx.video.bumper.loaded');
|
||||
},
|
||||
onReady: function() {
|
||||
this.log('edx.video.bumper.loaded');
|
||||
},
|
||||
|
||||
onPlay: function () {
|
||||
this.log('edx.video.bumper.played', {currentTime: this.getCurrentTime()});
|
||||
},
|
||||
onPlay: function() {
|
||||
this.log('edx.video.bumper.played', {currentTime: this.getCurrentTime()});
|
||||
},
|
||||
|
||||
onEnded: function () {
|
||||
this.log('edx.video.bumper.stopped', {currentTime: this.getCurrentTime()});
|
||||
},
|
||||
onEnded: function() {
|
||||
this.log('edx.video.bumper.stopped', {currentTime: this.getCurrentTime()});
|
||||
},
|
||||
|
||||
onSkip: function (event, doNotShowAgain) {
|
||||
var info = {currentTime: this.getCurrentTime()},
|
||||
eventName = 'edx.video.bumper.' + (doNotShowAgain ? 'dismissed': 'skipped');
|
||||
this.log(eventName, info);
|
||||
},
|
||||
onSkip: function(event, doNotShowAgain) {
|
||||
var info = {currentTime: this.getCurrentTime()},
|
||||
eventName = 'edx.video.bumper.' + (doNotShowAgain ? 'dismissed' : 'skipped');
|
||||
this.log(eventName, info);
|
||||
},
|
||||
|
||||
onShowLanguageMenu: function () {
|
||||
this.log('edx.video.bumper.transcript.menu.shown');
|
||||
},
|
||||
onShowLanguageMenu: function() {
|
||||
this.log('edx.video.bumper.transcript.menu.shown');
|
||||
},
|
||||
|
||||
onHideLanguageMenu: function () {
|
||||
this.log('edx.video.bumper.transcript.menu.hidden');
|
||||
},
|
||||
onHideLanguageMenu: function() {
|
||||
this.log('edx.video.bumper.transcript.menu.hidden');
|
||||
},
|
||||
|
||||
onShowCaptions: function () {
|
||||
this.log('edx.video.bumper.transcript.shown', {currentTime: this.getCurrentTime()});
|
||||
},
|
||||
onShowCaptions: function() {
|
||||
this.log('edx.video.bumper.transcript.shown', {currentTime: this.getCurrentTime()});
|
||||
},
|
||||
|
||||
onHideCaptions: function () {
|
||||
this.log('edx.video.bumper.transcript.hidden', {currentTime: this.getCurrentTime()});
|
||||
},
|
||||
onHideCaptions: function() {
|
||||
this.log('edx.video.bumper.transcript.hidden', {currentTime: this.getCurrentTime()});
|
||||
},
|
||||
|
||||
getCurrentTime: function () {
|
||||
var player = this.state.videoPlayer;
|
||||
return player ? player.currentTime : 0;
|
||||
},
|
||||
getCurrentTime: function() {
|
||||
var player = this.state.videoPlayer;
|
||||
return player ? player.currentTime : 0;
|
||||
},
|
||||
|
||||
getDuration: function () {
|
||||
var player = this.state.videoPlayer;
|
||||
return player ? player.duration() : 0;
|
||||
},
|
||||
getDuration: function() {
|
||||
var player = this.state.videoPlayer;
|
||||
return player ? player.duration() : 0;
|
||||
},
|
||||
|
||||
log: function (eventName, data) {
|
||||
var logInfo = _.extend({
|
||||
host_component_id: this.state.id,
|
||||
bumper_id: this.state.config.sources[0] || '',
|
||||
duration: this.getDuration(),
|
||||
code: 'html5'
|
||||
}, data, this.options.data);
|
||||
Logger.log(eventName, logInfo);
|
||||
}
|
||||
};
|
||||
log: function(eventName, data) {
|
||||
var logInfo = _.extend({
|
||||
host_component_id: this.state.id,
|
||||
bumper_id: this.state.config.sources[0] || '',
|
||||
duration: this.getDuration(),
|
||||
code: 'html5'
|
||||
}, data, this.options.data);
|
||||
Logger.log(eventName, logInfo);
|
||||
}
|
||||
};
|
||||
|
||||
return EventsBumperPlugin;
|
||||
});
|
||||
return EventsBumperPlugin;
|
||||
});
|
||||
}(RequireJS.define));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define('video/09_events_plugin.js', [], function() {
|
||||
'use strict';
|
||||
define('video/09_events_plugin.js', [], function() {
|
||||
/**
|
||||
* Events module.
|
||||
* @exports video/09_events_plugin.js
|
||||
@@ -10,143 +10,143 @@ define('video/09_events_plugin.js', [], function() {
|
||||
* @param {Object} options
|
||||
* @return {jquery Promise}
|
||||
*/
|
||||
var EventsPlugin = function(state, i18n, options) {
|
||||
if (!(this instanceof EventsPlugin)) {
|
||||
return new EventsPlugin(state, i18n, options);
|
||||
}
|
||||
var EventsPlugin = function(state, i18n, options) {
|
||||
if (!(this instanceof EventsPlugin)) {
|
||||
return new EventsPlugin(state, i18n, options);
|
||||
}
|
||||
|
||||
_.bindAll(this, 'onReady', 'onPlay', 'onPause', 'onEnded', 'onSeek',
|
||||
_.bindAll(this, 'onReady', 'onPlay', 'onPause', 'onEnded', 'onSeek',
|
||||
'onSpeedChange', 'onShowLanguageMenu', 'onHideLanguageMenu', 'onSkip',
|
||||
'onShowTranscript', 'onHideTranscript', 'onShowCaptions', 'onHideCaptions',
|
||||
'destroy');
|
||||
|
||||
this.state = state;
|
||||
this.options = _.extend({}, options);
|
||||
this.state.videoEventsPlugin = this;
|
||||
this.i18n = i18n;
|
||||
this.initialize();
|
||||
this.state = state;
|
||||
this.options = _.extend({}, options);
|
||||
this.state.videoEventsPlugin = this;
|
||||
this.i18n = i18n;
|
||||
this.initialize();
|
||||
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
|
||||
EventsPlugin.moduleName = 'EventsPlugin';
|
||||
EventsPlugin.prototype = {
|
||||
destroy: function () {
|
||||
this.state.el.off(this.events);
|
||||
delete this.state.videoEventsPlugin;
|
||||
},
|
||||
EventsPlugin.moduleName = 'EventsPlugin';
|
||||
EventsPlugin.prototype = {
|
||||
destroy: function() {
|
||||
this.state.el.off(this.events);
|
||||
delete this.state.videoEventsPlugin;
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
this.events = {
|
||||
'ready': this.onReady,
|
||||
'play': this.onPlay,
|
||||
'pause': this.onPause,
|
||||
'ended stop': this.onEnded,
|
||||
'seek': this.onSeek,
|
||||
'skip': this.onSkip,
|
||||
'speedchange': this.onSpeedChange,
|
||||
'language_menu:show': this.onShowLanguageMenu,
|
||||
'language_menu:hide': this.onHideLanguageMenu,
|
||||
'transcript:show': this.onShowTranscript,
|
||||
'transcript:hide': this.onHideTranscript,
|
||||
'captions:show': this.onShowCaptions,
|
||||
'captions:hide': this.onHideCaptions,
|
||||
'destroy': this.destroy
|
||||
};
|
||||
this.bindHandlers();
|
||||
this.emitPlayVideoEvent = true;
|
||||
},
|
||||
initialize: function() {
|
||||
this.events = {
|
||||
'ready': this.onReady,
|
||||
'play': this.onPlay,
|
||||
'pause': this.onPause,
|
||||
'ended stop': this.onEnded,
|
||||
'seek': this.onSeek,
|
||||
'skip': this.onSkip,
|
||||
'speedchange': this.onSpeedChange,
|
||||
'language_menu:show': this.onShowLanguageMenu,
|
||||
'language_menu:hide': this.onHideLanguageMenu,
|
||||
'transcript:show': this.onShowTranscript,
|
||||
'transcript:hide': this.onHideTranscript,
|
||||
'captions:show': this.onShowCaptions,
|
||||
'captions:hide': this.onHideCaptions,
|
||||
'destroy': this.destroy
|
||||
};
|
||||
this.bindHandlers();
|
||||
this.emitPlayVideoEvent = true;
|
||||
},
|
||||
|
||||
bindHandlers: function() {
|
||||
this.state.el.on(this.events);
|
||||
},
|
||||
bindHandlers: function() {
|
||||
this.state.el.on(this.events);
|
||||
},
|
||||
|
||||
onReady: function () {
|
||||
this.log('load_video');
|
||||
},
|
||||
onReady: function() {
|
||||
this.log('load_video');
|
||||
},
|
||||
|
||||
onPlay: function () {
|
||||
if (this.emitPlayVideoEvent) {
|
||||
this.log('play_video', {currentTime: this.getCurrentTime()});
|
||||
this.emitPlayVideoEvent = false;
|
||||
onPlay: function() {
|
||||
if (this.emitPlayVideoEvent) {
|
||||
this.log('play_video', {currentTime: this.getCurrentTime()});
|
||||
this.emitPlayVideoEvent = false;
|
||||
}
|
||||
},
|
||||
|
||||
onPause: function() {
|
||||
this.log('pause_video', {currentTime: this.getCurrentTime()});
|
||||
this.emitPlayVideoEvent = true;
|
||||
},
|
||||
|
||||
onEnded: function() {
|
||||
this.log('stop_video', {currentTime: this.getCurrentTime()});
|
||||
this.emitPlayVideoEvent = true;
|
||||
},
|
||||
|
||||
onSkip: function(event, doNotShowAgain) {
|
||||
var info = {currentTime: this.getCurrentTime()},
|
||||
eventName = doNotShowAgain ? 'do_not_show_again_video' : 'skip_video';
|
||||
this.log(eventName, info);
|
||||
},
|
||||
|
||||
onSeek: function(event, time, oldTime, type) {
|
||||
this.log('seek_video', {
|
||||
old_time: oldTime,
|
||||
new_time: time,
|
||||
type: type
|
||||
});
|
||||
},
|
||||
|
||||
onSpeedChange: function(event, newSpeed, oldSpeed) {
|
||||
this.log('speed_change_video', {
|
||||
current_time: this.getCurrentTime(),
|
||||
old_speed: oldSpeed,
|
||||
new_speed: newSpeed
|
||||
});
|
||||
},
|
||||
|
||||
onShowLanguageMenu: function() {
|
||||
this.log('edx.video.language_menu.shown');
|
||||
},
|
||||
|
||||
onHideLanguageMenu: function() {
|
||||
this.log('edx.video.language_menu.hidden', {language: this.getCurrentLanguage()});
|
||||
},
|
||||
|
||||
onShowTranscript: function() {
|
||||
this.log('show_transcript', {current_time: this.getCurrentTime()});
|
||||
},
|
||||
|
||||
onHideTranscript: function() {
|
||||
this.log('hide_transcript', {current_time: this.getCurrentTime()});
|
||||
},
|
||||
|
||||
onShowCaptions: function() {
|
||||
this.log('edx.video.closed_captions.shown', {current_time: this.getCurrentTime()});
|
||||
},
|
||||
|
||||
onHideCaptions: function() {
|
||||
this.log('edx.video.closed_captions.hidden', {current_time: this.getCurrentTime()});
|
||||
},
|
||||
|
||||
getCurrentTime: function() {
|
||||
var player = this.state.videoPlayer;
|
||||
return player ? player.currentTime : 0;
|
||||
},
|
||||
|
||||
getCurrentLanguage: function() {
|
||||
var language = this.state.lang;
|
||||
return language;
|
||||
},
|
||||
|
||||
log: function(eventName, data) {
|
||||
var logInfo = _.extend({
|
||||
id: this.state.id,
|
||||
code: this.state.isYoutubeType() ? this.state.youtubeId() : 'html5'
|
||||
}, data, this.options.data);
|
||||
Logger.log(eventName, logInfo);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
onPause: function () {
|
||||
this.log('pause_video', {currentTime: this.getCurrentTime()});
|
||||
this.emitPlayVideoEvent = true;
|
||||
},
|
||||
|
||||
onEnded: function () {
|
||||
this.log('stop_video', {currentTime: this.getCurrentTime()});
|
||||
this.emitPlayVideoEvent = true;
|
||||
},
|
||||
|
||||
onSkip: function (event, doNotShowAgain) {
|
||||
var info = {currentTime: this.getCurrentTime()},
|
||||
eventName = doNotShowAgain ? 'do_not_show_again_video': 'skip_video';
|
||||
this.log(eventName, info);
|
||||
},
|
||||
|
||||
onSeek: function (event, time, oldTime, type) {
|
||||
this.log('seek_video', {
|
||||
old_time: oldTime,
|
||||
new_time: time,
|
||||
type: type
|
||||
});
|
||||
},
|
||||
|
||||
onSpeedChange: function (event, newSpeed, oldSpeed) {
|
||||
this.log('speed_change_video', {
|
||||
current_time: this.getCurrentTime(),
|
||||
old_speed: oldSpeed,
|
||||
new_speed: newSpeed
|
||||
});
|
||||
},
|
||||
|
||||
onShowLanguageMenu: function () {
|
||||
this.log('edx.video.language_menu.shown');
|
||||
},
|
||||
|
||||
onHideLanguageMenu: function () {
|
||||
this.log('edx.video.language_menu.hidden', { language: this.getCurrentLanguage() });
|
||||
},
|
||||
|
||||
onShowTranscript: function () {
|
||||
this.log('show_transcript', {current_time: this.getCurrentTime()});
|
||||
},
|
||||
|
||||
onHideTranscript: function () {
|
||||
this.log('hide_transcript', {current_time: this.getCurrentTime()});
|
||||
},
|
||||
|
||||
onShowCaptions: function () {
|
||||
this.log('edx.video.closed_captions.shown', {current_time: this.getCurrentTime()});
|
||||
},
|
||||
|
||||
onHideCaptions: function () {
|
||||
this.log('edx.video.closed_captions.hidden', {current_time: this.getCurrentTime()});
|
||||
},
|
||||
|
||||
getCurrentTime: function () {
|
||||
var player = this.state.videoPlayer;
|
||||
return player ? player.currentTime : 0;
|
||||
},
|
||||
|
||||
getCurrentLanguage: function() {
|
||||
var language = this.state.lang;
|
||||
return language;
|
||||
},
|
||||
|
||||
log: function (eventName, data) {
|
||||
var logInfo = _.extend({
|
||||
id: this.state.id,
|
||||
code: this.state.isYoutubeType() ? this.state.youtubeId() : 'html5'
|
||||
}, data, this.options.data);
|
||||
Logger.log(eventName, logInfo);
|
||||
}
|
||||
};
|
||||
|
||||
return EventsPlugin;
|
||||
});
|
||||
return EventsPlugin;
|
||||
});
|
||||
}(RequireJS.define));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define('video/09_play_pause_control.js', [], function() {
|
||||
'use strict';
|
||||
define('video/09_play_pause_control.js', [], function() {
|
||||
/**
|
||||
* Play/pause control module.
|
||||
* @exports video/09_play_pause_control.js
|
||||
@@ -9,88 +9,88 @@ define('video/09_play_pause_control.js', [], function() {
|
||||
* @param {Object} i18n The object containing strings with translations.
|
||||
* @return {jquery Promise}
|
||||
*/
|
||||
var PlayPauseControl = function(state, i18n) {
|
||||
if (!(this instanceof PlayPauseControl)) {
|
||||
return new PlayPauseControl(state, i18n);
|
||||
}
|
||||
var PlayPauseControl = function(state, i18n) {
|
||||
if (!(this instanceof PlayPauseControl)) {
|
||||
return new PlayPauseControl(state, i18n);
|
||||
}
|
||||
|
||||
_.bindAll(this, 'play', 'pause', 'onClick', 'destroy');
|
||||
this.state = state;
|
||||
this.state.videoPlayPauseControl = this;
|
||||
this.i18n = i18n;
|
||||
this.initialize();
|
||||
_.bindAll(this, 'play', 'pause', 'onClick', 'destroy');
|
||||
this.state = state;
|
||||
this.state.videoPlayPauseControl = this;
|
||||
this.i18n = i18n;
|
||||
this.initialize();
|
||||
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
|
||||
PlayPauseControl.prototype = {
|
||||
template: [
|
||||
'<button class="control video_control play" aria-disabled="false" title="',
|
||||
PlayPauseControl.prototype = {
|
||||
template: [
|
||||
'<button class="control video_control play" aria-disabled="false" title="',
|
||||
gettext('Play'),
|
||||
'">',
|
||||
'">',
|
||||
'<span class="icon fa fa-play" aria-hidden="true"></span>',
|
||||
'</button>'
|
||||
].join(''),
|
||||
'</button>'
|
||||
].join(''),
|
||||
|
||||
destroy: function () {
|
||||
this.el.remove();
|
||||
this.state.el.off('destroy', this.destroy);
|
||||
delete this.state.videoPlayPauseControl;
|
||||
},
|
||||
destroy: function() {
|
||||
this.el.remove();
|
||||
this.state.el.off('destroy', this.destroy);
|
||||
delete this.state.videoPlayPauseControl;
|
||||
},
|
||||
|
||||
/** Initializes the module. */
|
||||
initialize: function() {
|
||||
this.el = $(this.template);
|
||||
this.render();
|
||||
this.bindHandlers();
|
||||
},
|
||||
initialize: function() {
|
||||
this.el = $(this.template);
|
||||
this.render();
|
||||
this.bindHandlers();
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates any necessary DOM elements, attach them, and set their,
|
||||
* initial configuration.
|
||||
*/
|
||||
render: function() {
|
||||
this.state.el.find('.vcr').prepend(this.el);
|
||||
},
|
||||
render: function() {
|
||||
this.state.el.find('.vcr').prepend(this.el);
|
||||
},
|
||||
|
||||
/** Bind any necessary function callbacks to DOM events. */
|
||||
bindHandlers: function() {
|
||||
this.el.on({
|
||||
'click': this.onClick
|
||||
});
|
||||
this.state.el.on({
|
||||
'play': this.play,
|
||||
'pause ended': this.pause,
|
||||
'destroy': this.destroy
|
||||
});
|
||||
},
|
||||
bindHandlers: function() {
|
||||
this.el.on({
|
||||
'click': this.onClick
|
||||
});
|
||||
this.state.el.on({
|
||||
'play': this.play,
|
||||
'pause ended': this.pause,
|
||||
'destroy': this.destroy
|
||||
});
|
||||
},
|
||||
|
||||
onClick: function (event) {
|
||||
event.preventDefault();
|
||||
this.state.videoCommands.execute('togglePlayback');
|
||||
},
|
||||
onClick: function(event) {
|
||||
event.preventDefault();
|
||||
this.state.videoCommands.execute('togglePlayback');
|
||||
},
|
||||
|
||||
play: function () {
|
||||
this.el
|
||||
play: function() {
|
||||
this.el
|
||||
.addClass('pause')
|
||||
.removeClass('play')
|
||||
.attr('title', gettext('Pause'))
|
||||
.find('.icon')
|
||||
.removeClass('fa-play')
|
||||
.addClass('fa-pause');
|
||||
},
|
||||
},
|
||||
|
||||
pause: function () {
|
||||
this.el
|
||||
pause: function() {
|
||||
this.el
|
||||
.removeClass('pause')
|
||||
.addClass('play')
|
||||
.attr('title', gettext('Play'))
|
||||
.find('.icon')
|
||||
.removeClass('fa-pause')
|
||||
.addClass('fa-play');
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return PlayPauseControl;
|
||||
});
|
||||
return PlayPauseControl;
|
||||
});
|
||||
}(RequireJS.define));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define('video/09_play_placeholder.js', [], function() {
|
||||
'use strict';
|
||||
define('video/09_play_placeholder.js', [], function() {
|
||||
/**
|
||||
* Play placeholder control module.
|
||||
* @exports video/09_play_placeholder.js
|
||||
@@ -9,79 +9,79 @@ define('video/09_play_placeholder.js', [], function() {
|
||||
* @param {Object} i18n The object containing strings with translations.
|
||||
* @return {jquery Promise}
|
||||
*/
|
||||
var PlayPlaceholder = function(state, i18n) {
|
||||
if (!(this instanceof PlayPlaceholder)) {
|
||||
return new PlayPlaceholder(state, i18n);
|
||||
}
|
||||
var PlayPlaceholder = function(state, i18n) {
|
||||
if (!(this instanceof PlayPlaceholder)) {
|
||||
return new PlayPlaceholder(state, i18n);
|
||||
}
|
||||
|
||||
_.bindAll(this, 'onClick', 'hide', 'show', 'destroy');
|
||||
this.state = state;
|
||||
this.state.videoPlayPlaceholder = this;
|
||||
this.i18n = i18n;
|
||||
this.initialize();
|
||||
_.bindAll(this, 'onClick', 'hide', 'show', 'destroy');
|
||||
this.state = state;
|
||||
this.state.videoPlayPlaceholder = this;
|
||||
this.i18n = i18n;
|
||||
this.initialize();
|
||||
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
|
||||
PlayPlaceholder.prototype = {
|
||||
destroy: function () {
|
||||
this.el.off('click', this.onClick);
|
||||
this.state.el.on({
|
||||
'destroy': this.destroy,
|
||||
'play': this.hide,
|
||||
'ended pause': this.show
|
||||
});
|
||||
this.hide();
|
||||
delete this.state.videoPlayPlaceholder;
|
||||
},
|
||||
PlayPlaceholder.prototype = {
|
||||
destroy: function() {
|
||||
this.el.off('click', this.onClick);
|
||||
this.state.el.on({
|
||||
'destroy': this.destroy,
|
||||
'play': this.hide,
|
||||
'ended pause': this.show
|
||||
});
|
||||
this.hide();
|
||||
delete this.state.videoPlayPlaceholder;
|
||||
},
|
||||
|
||||
/**
|
||||
* Indicates whether the placeholder should be shown. We display it
|
||||
* for html5 videos on iPad and Android devices.
|
||||
* @return {Boolean}
|
||||
*/
|
||||
shouldBeShown: function () {
|
||||
return /iPad|Android/i.test(this.state.isTouch[0]) && !this.state.isYoutubeType();
|
||||
},
|
||||
shouldBeShown: function() {
|
||||
return /iPad|Android/i.test(this.state.isTouch[0]) && !this.state.isYoutubeType();
|
||||
},
|
||||
|
||||
/** Initializes the module. */
|
||||
initialize: function() {
|
||||
if (!this.shouldBeShown()) {
|
||||
return false;
|
||||
}
|
||||
initialize: function() {
|
||||
if (!this.shouldBeShown()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.el = this.state.el.find('.btn-play');
|
||||
this.bindHandlers();
|
||||
this.show();
|
||||
},
|
||||
this.el = this.state.el.find('.btn-play');
|
||||
this.bindHandlers();
|
||||
this.show();
|
||||
},
|
||||
|
||||
/** Bind any necessary function callbacks to DOM events. */
|
||||
bindHandlers: function() {
|
||||
this.el.on('click', this.onClick);
|
||||
this.state.el.on({
|
||||
'destroy': this.destroy,
|
||||
'play': this.hide,
|
||||
'ended pause': this.show
|
||||
});
|
||||
},
|
||||
bindHandlers: function() {
|
||||
this.el.on('click', this.onClick);
|
||||
this.state.el.on({
|
||||
'destroy': this.destroy,
|
||||
'play': this.hide,
|
||||
'ended pause': this.show
|
||||
});
|
||||
},
|
||||
|
||||
onClick: function () {
|
||||
this.state.videoCommands.execute('play');
|
||||
},
|
||||
onClick: function() {
|
||||
this.state.videoCommands.execute('play');
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
this.el
|
||||
hide: function() {
|
||||
this.el
|
||||
.addClass('is-hidden')
|
||||
.attr({'aria-hidden': 'true', 'tabindex': -1});
|
||||
},
|
||||
},
|
||||
|
||||
show: function () {
|
||||
this.el
|
||||
show: function() {
|
||||
this.el
|
||||
.removeClass('is-hidden')
|
||||
.attr({'aria-hidden': 'false', 'tabindex': 0});
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return PlayPlaceholder;
|
||||
});
|
||||
return PlayPlaceholder;
|
||||
});
|
||||
}(RequireJS.define));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define('video/09_play_skip_control.js', [], function() {
|
||||
'use strict';
|
||||
define('video/09_play_skip_control.js', [], function() {
|
||||
/**
|
||||
* Play/skip control module.
|
||||
* @exports video/09_play_skip_control.js
|
||||
@@ -9,70 +9,70 @@ define('video/09_play_skip_control.js', [], function() {
|
||||
* @param {Object} i18n The object containing strings with translations.
|
||||
* @return {jquery Promise}
|
||||
*/
|
||||
var PlaySkipControl = function(state, i18n) {
|
||||
if (!(this instanceof PlaySkipControl)) {
|
||||
return new PlaySkipControl(state, i18n);
|
||||
}
|
||||
var PlaySkipControl = function(state, i18n) {
|
||||
if (!(this instanceof PlaySkipControl)) {
|
||||
return new PlaySkipControl(state, i18n);
|
||||
}
|
||||
|
||||
_.bindAll(this, 'play', 'onClick', 'destroy');
|
||||
this.state = state;
|
||||
this.state.videoPlaySkipControl = this;
|
||||
this.i18n = i18n;
|
||||
this.initialize();
|
||||
_.bindAll(this, 'play', 'onClick', 'destroy');
|
||||
this.state = state;
|
||||
this.state.videoPlaySkipControl = this;
|
||||
this.i18n = i18n;
|
||||
this.initialize();
|
||||
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
|
||||
PlaySkipControl.prototype = {
|
||||
template: [
|
||||
'<button class="control video_control play play-skip-control" title="',
|
||||
PlaySkipControl.prototype = {
|
||||
template: [
|
||||
'<button class="control video_control play play-skip-control" title="',
|
||||
gettext('Play'),
|
||||
'">',
|
||||
'">',
|
||||
'<span class="icon fa fa-play" aria-hidden="true"></span>',
|
||||
'</button>'
|
||||
].join(''),
|
||||
'</button>'
|
||||
].join(''),
|
||||
|
||||
destroy: function () {
|
||||
this.el.remove();
|
||||
this.state.el.off('destroy', this.destroy);
|
||||
delete this.state.videoPlaySkipControl;
|
||||
},
|
||||
destroy: function() {
|
||||
this.el.remove();
|
||||
this.state.el.off('destroy', this.destroy);
|
||||
delete this.state.videoPlaySkipControl;
|
||||
},
|
||||
|
||||
/** Initializes the module. */
|
||||
initialize: function() {
|
||||
this.el = $(this.template);
|
||||
this.render();
|
||||
this.bindHandlers();
|
||||
},
|
||||
initialize: function() {
|
||||
this.el = $(this.template);
|
||||
this.render();
|
||||
this.bindHandlers();
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates any necessary DOM elements, attach them, and set their,
|
||||
* initial configuration.
|
||||
*/
|
||||
render: function() {
|
||||
this.state.el.find('.vcr').prepend(this.el);
|
||||
},
|
||||
render: function() {
|
||||
this.state.el.find('.vcr').prepend(this.el);
|
||||
},
|
||||
|
||||
/** Bind any necessary function callbacks to DOM events. */
|
||||
bindHandlers: function() {
|
||||
this.el.on('click', this.onClick);
|
||||
this.state.el.on({
|
||||
'play': this.play,
|
||||
'destroy': this.destroy
|
||||
});
|
||||
},
|
||||
bindHandlers: function() {
|
||||
this.el.on('click', this.onClick);
|
||||
this.state.el.on({
|
||||
'play': this.play,
|
||||
'destroy': this.destroy
|
||||
});
|
||||
},
|
||||
|
||||
onClick: function (event) {
|
||||
event.preventDefault();
|
||||
if (this.state.videoPlayer.isPlaying()) {
|
||||
this.state.videoCommands.execute('skip');
|
||||
} else {
|
||||
this.state.videoCommands.execute('play');
|
||||
}
|
||||
},
|
||||
onClick: function(event) {
|
||||
event.preventDefault();
|
||||
if (this.state.videoPlayer.isPlaying()) {
|
||||
this.state.videoCommands.execute('skip');
|
||||
} else {
|
||||
this.state.videoCommands.execute('play');
|
||||
}
|
||||
},
|
||||
|
||||
play: function () {
|
||||
this.el
|
||||
play: function() {
|
||||
this.el
|
||||
.removeClass('play')
|
||||
.addClass('skip')
|
||||
.attr('title', gettext('Skip'))
|
||||
@@ -80,10 +80,10 @@ define('video/09_play_skip_control.js', [], function() {
|
||||
.removeClass('fa-play')
|
||||
.addClass('fa-step-forward');
|
||||
// Disable possibility to pause the video.
|
||||
this.state.el.find('video').off('click');
|
||||
}
|
||||
};
|
||||
this.state.el.find('video').off('click');
|
||||
}
|
||||
};
|
||||
|
||||
return PlaySkipControl;
|
||||
});
|
||||
return PlaySkipControl;
|
||||
});
|
||||
}(RequireJS.define));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function (define) {
|
||||
'use strict';
|
||||
define('video/09_poster.js', [], function () {
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define('video/09_poster.js', [], function() {
|
||||
/**
|
||||
* Poster module.
|
||||
* @exports video/09_poster.js
|
||||
@@ -8,62 +8,62 @@ define('video/09_poster.js', [], function () {
|
||||
* @param {jquery Element} element
|
||||
* @param {Object} options
|
||||
*/
|
||||
var VideoPoster = function (element, options) {
|
||||
if (!(this instanceof VideoPoster)) {
|
||||
return new VideoPoster(element, options);
|
||||
}
|
||||
var VideoPoster = function(element, options) {
|
||||
if (!(this instanceof VideoPoster)) {
|
||||
return new VideoPoster(element, options);
|
||||
}
|
||||
|
||||
_.bindAll(this, 'onClick', 'destroy');
|
||||
this.element = element;
|
||||
this.container = element.find('.video-player');
|
||||
this.options = options || {};
|
||||
this.initialize();
|
||||
};
|
||||
_.bindAll(this, 'onClick', 'destroy');
|
||||
this.element = element;
|
||||
this.container = element.find('.video-player');
|
||||
this.options = options || {};
|
||||
this.initialize();
|
||||
};
|
||||
|
||||
VideoPoster.moduleName = 'Poster';
|
||||
VideoPoster.prototype = {
|
||||
template: _.template([
|
||||
'<div class="video-pre-roll is-<%= type %> poster" ',
|
||||
VideoPoster.moduleName = 'Poster';
|
||||
VideoPoster.prototype = {
|
||||
template: _.template([
|
||||
'<div class="video-pre-roll is-<%= type %> poster" ',
|
||||
'style="background-image: url(<%= url %>)">',
|
||||
'<button class="btn-play btn-pre-roll">',
|
||||
'<img src="/static/images/play.png" alt="">',
|
||||
'<span class="sr">', gettext('Play video'), '</span>',
|
||||
'<img src="/static/images/play.png" alt="">',
|
||||
'<span class="sr">', gettext('Play video'), '</span>',
|
||||
'</button>',
|
||||
'</div>'
|
||||
].join('')),
|
||||
'</div>'
|
||||
].join('')),
|
||||
|
||||
initialize: function () {
|
||||
this.el = $(this.template({
|
||||
url: this.options.poster.url,
|
||||
type: this.options.poster.type
|
||||
}));
|
||||
this.element.addClass('is-pre-roll');
|
||||
this.render();
|
||||
this.bindHandlers();
|
||||
},
|
||||
initialize: function() {
|
||||
this.el = $(this.template({
|
||||
url: this.options.poster.url,
|
||||
type: this.options.poster.type
|
||||
}));
|
||||
this.element.addClass('is-pre-roll');
|
||||
this.render();
|
||||
this.bindHandlers();
|
||||
},
|
||||
|
||||
bindHandlers: function () {
|
||||
this.el.on('click', this.onClick);
|
||||
this.element.on('destroy', this.destroy);
|
||||
},
|
||||
bindHandlers: function() {
|
||||
this.el.on('click', this.onClick);
|
||||
this.element.on('destroy', this.destroy);
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.container.append(this.el);
|
||||
},
|
||||
render: function() {
|
||||
this.container.append(this.el);
|
||||
},
|
||||
|
||||
onClick: function () {
|
||||
if (_.isFunction(this.options.onClick)) {
|
||||
this.options.onClick();
|
||||
onClick: function() {
|
||||
if (_.isFunction(this.options.onClick)) {
|
||||
this.options.onClick();
|
||||
}
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.element.off('destroy', this.destroy).removeClass('is-pre-roll');
|
||||
this.el.remove();
|
||||
}
|
||||
this.destroy();
|
||||
},
|
||||
};
|
||||
|
||||
destroy: function () {
|
||||
this.element.off('destroy', this.destroy).removeClass('is-pre-roll');
|
||||
this.el.remove();
|
||||
}
|
||||
};
|
||||
|
||||
return VideoPoster;
|
||||
});
|
||||
return VideoPoster;
|
||||
});
|
||||
}(RequireJS.define));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define('video/09_save_state_plugin.js', [], function() {
|
||||
'use strict';
|
||||
define('video/09_save_state_plugin.js', [], function() {
|
||||
/**
|
||||
* Save state module.
|
||||
* @exports video/09_save_state_plugin.js
|
||||
@@ -10,114 +10,114 @@ define('video/09_save_state_plugin.js', [], function() {
|
||||
* @param {Object} options
|
||||
* @return {jquery Promise}
|
||||
*/
|
||||
var SaveStatePlugin = function(state, i18n, options) {
|
||||
if (!(this instanceof SaveStatePlugin)) {
|
||||
return new SaveStatePlugin(state, i18n, options);
|
||||
}
|
||||
|
||||
_.bindAll(this, 'onSpeedChange', 'saveStateHandler', 'bindUnloadHandler', 'onUnload', 'onYoutubeAvailability',
|
||||
'onLanguageChange', 'destroy');
|
||||
this.state = state;
|
||||
this.options = _.extend({events: []}, options);
|
||||
this.state.videoSaveStatePlugin = this;
|
||||
this.i18n = i18n;
|
||||
this.initialize();
|
||||
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
|
||||
|
||||
SaveStatePlugin.moduleName = 'SaveStatePlugin';
|
||||
SaveStatePlugin.prototype = {
|
||||
destroy: function () {
|
||||
this.state.el.off(this.events).off('destroy', this.destroy);
|
||||
$(window).off('unload', this.onUnload);
|
||||
delete this.state.videoSaveStatePlugin;
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
this.events = {
|
||||
'speedchange': this.onSpeedChange,
|
||||
'play': this.bindUnloadHandler,
|
||||
'pause destroy': this.saveStateHandler,
|
||||
'language_menu:change': this.onLanguageChange,
|
||||
'youtube_availability': this.onYoutubeAvailability
|
||||
};
|
||||
this.bindHandlers();
|
||||
},
|
||||
|
||||
bindHandlers: function() {
|
||||
if (this.options.events.length) {
|
||||
_.each(this.options.events, function (eventName) {
|
||||
var callback;
|
||||
if (_.has(this.events, eventName)) {
|
||||
callback = this.events[eventName];
|
||||
this.state.el.on(eventName, callback);
|
||||
}
|
||||
}, this);
|
||||
} else {
|
||||
this.state.el.on(this.events);
|
||||
var SaveStatePlugin = function(state, i18n, options) {
|
||||
if (!(this instanceof SaveStatePlugin)) {
|
||||
return new SaveStatePlugin(state, i18n, options);
|
||||
}
|
||||
this.state.el.on('destroy', this.destroy);
|
||||
},
|
||||
|
||||
bindUnloadHandler: _.once(function () {
|
||||
$(window).on('unload.video', this.onUnload);
|
||||
}),
|
||||
_.bindAll(this, 'onSpeedChange', 'saveStateHandler', 'bindUnloadHandler', 'onUnload', 'onYoutubeAvailability',
|
||||
'onLanguageChange', 'destroy');
|
||||
this.state = state;
|
||||
this.options = _.extend({events: []}, options);
|
||||
this.state.videoSaveStatePlugin = this;
|
||||
this.i18n = i18n;
|
||||
this.initialize();
|
||||
|
||||
onSpeedChange: function (event, newSpeed) {
|
||||
this.saveState(true, {speed: newSpeed});
|
||||
this.state.storage.setItem('speed', newSpeed, true);
|
||||
this.state.storage.setItem('general_speed', newSpeed);
|
||||
},
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
|
||||
saveStateHandler: function () {
|
||||
this.saveState(true);
|
||||
},
|
||||
|
||||
onUnload: function () {
|
||||
this.saveState();
|
||||
},
|
||||
SaveStatePlugin.moduleName = 'SaveStatePlugin';
|
||||
SaveStatePlugin.prototype = {
|
||||
destroy: function() {
|
||||
this.state.el.off(this.events).off('destroy', this.destroy);
|
||||
$(window).off('unload', this.onUnload);
|
||||
delete this.state.videoSaveStatePlugin;
|
||||
},
|
||||
|
||||
onLanguageChange: function (event, langCode) {
|
||||
this.state.storage.setItem('language', langCode);
|
||||
},
|
||||
initialize: function() {
|
||||
this.events = {
|
||||
'speedchange': this.onSpeedChange,
|
||||
'play': this.bindUnloadHandler,
|
||||
'pause destroy': this.saveStateHandler,
|
||||
'language_menu:change': this.onLanguageChange,
|
||||
'youtube_availability': this.onYoutubeAvailability
|
||||
};
|
||||
this.bindHandlers();
|
||||
},
|
||||
|
||||
onYoutubeAvailability: function (event, youtubeIsAvailable) {
|
||||
bindHandlers: function() {
|
||||
if (this.options.events.length) {
|
||||
_.each(this.options.events, function(eventName) {
|
||||
var callback;
|
||||
if (_.has(this.events, eventName)) {
|
||||
callback = this.events[eventName];
|
||||
this.state.el.on(eventName, callback);
|
||||
}
|
||||
}, this);
|
||||
} else {
|
||||
this.state.el.on(this.events);
|
||||
}
|
||||
this.state.el.on('destroy', this.destroy);
|
||||
},
|
||||
|
||||
bindUnloadHandler: _.once(function() {
|
||||
$(window).on('unload.video', this.onUnload);
|
||||
}),
|
||||
|
||||
onSpeedChange: function(event, newSpeed) {
|
||||
this.saveState(true, {speed: newSpeed});
|
||||
this.state.storage.setItem('speed', newSpeed, true);
|
||||
this.state.storage.setItem('general_speed', newSpeed);
|
||||
},
|
||||
|
||||
saveStateHandler: function() {
|
||||
this.saveState(true);
|
||||
},
|
||||
|
||||
onUnload: function() {
|
||||
this.saveState();
|
||||
},
|
||||
|
||||
onLanguageChange: function(event, langCode) {
|
||||
this.state.storage.setItem('language', langCode);
|
||||
},
|
||||
|
||||
onYoutubeAvailability: function(event, youtubeIsAvailable) {
|
||||
// Compare what the client-side code has determined Youtube
|
||||
// availability to be (true/false) vs. what the LMS recorded for
|
||||
// this user. The LMS will assume YouTube is available by default.
|
||||
if (youtubeIsAvailable !== this.state.config.recordedYoutubeIsAvailable) {
|
||||
this.saveState(true, {youtube_is_available: youtubeIsAvailable});
|
||||
if (youtubeIsAvailable !== this.state.config.recordedYoutubeIsAvailable) {
|
||||
this.saveState(true, {youtube_is_available: youtubeIsAvailable});
|
||||
}
|
||||
},
|
||||
|
||||
saveState: function(async, data) {
|
||||
if (!($.isPlainObject(data))) {
|
||||
data = {
|
||||
saved_video_position: this.state.videoPlayer.currentTime
|
||||
};
|
||||
}
|
||||
|
||||
if (data.speed) {
|
||||
this.state.storage.setItem('speed', data.speed, true);
|
||||
}
|
||||
|
||||
if (_.has(data, 'saved_video_position')) {
|
||||
this.state.storage.setItem('savedVideoPosition', data.saved_video_position, true);
|
||||
data.saved_video_position = Time.formatFull(data.saved_video_position);
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: this.state.config.saveStateUrl,
|
||||
type: 'POST',
|
||||
async: async ? true : false,
|
||||
dataType: 'json',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
saveState: function (async, data) {
|
||||
if (!($.isPlainObject(data))) {
|
||||
data = {
|
||||
saved_video_position: this.state.videoPlayer.currentTime
|
||||
};
|
||||
}
|
||||
|
||||
if (data.speed) {
|
||||
this.state.storage.setItem('speed', data.speed, true);
|
||||
}
|
||||
|
||||
if (_.has(data, 'saved_video_position')) {
|
||||
this.state.storage.setItem('savedVideoPosition', data.saved_video_position, true);
|
||||
data.saved_video_position = Time.formatFull(data.saved_video_position);
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: this.state.config.saveStateUrl,
|
||||
type: 'POST',
|
||||
async: async ? true : false,
|
||||
dataType: 'json',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return SaveStatePlugin;
|
||||
});
|
||||
return SaveStatePlugin;
|
||||
});
|
||||
}(RequireJS.define));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(function(define) {
|
||||
'use strict';
|
||||
'use strict';
|
||||
// VideoSkipControl module.
|
||||
define(
|
||||
define(
|
||||
'video/09_skip_control.js', [],
|
||||
function() {
|
||||
/**
|
||||
@@ -29,13 +29,13 @@ function() {
|
||||
SkipControl.prototype = {
|
||||
template: [
|
||||
'<button class="control video_control skip skip-control" aria-disabled="false" title="',
|
||||
gettext('Do not show again'),
|
||||
gettext('Do not show again'),
|
||||
'">',
|
||||
'<span class="icon fa fa-step-forward" aria-hidden="true"></span>',
|
||||
'<span class="icon fa fa-step-forward" aria-hidden="true"></span>',
|
||||
'</button>'
|
||||
].join(''),
|
||||
|
||||
destroy: function () {
|
||||
destroy: function() {
|
||||
this.el.remove();
|
||||
this.state.el.off('.skip');
|
||||
delete this.state.videoSkipControl;
|
||||
@@ -64,7 +64,7 @@ function() {
|
||||
});
|
||||
},
|
||||
|
||||
onClick: function (event) {
|
||||
onClick: function(event) {
|
||||
event.preventDefault();
|
||||
this.state.videoCommands.execute('skip', true);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
// 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',
|
||||
'edx-ui-toolkit/js/utils/html-utils',
|
||||
'draggabilly'
|
||||
], function (Sjson, AsyncProcess, HtmlUtils, Draggabilly) {
|
||||
|
||||
], function(Sjson, AsyncProcess, HtmlUtils, Draggabilly) {
|
||||
/**
|
||||
* @desc VideoCaption module exports a function.
|
||||
*
|
||||
@@ -23,7 +22,7 @@
|
||||
*
|
||||
* @returns {jquery Promise}
|
||||
*/
|
||||
var VideoCaption = function (state) {
|
||||
var VideoCaption = function(state) {
|
||||
if (!(this instanceof VideoCaption)) {
|
||||
return new VideoCaption(state);
|
||||
}
|
||||
@@ -48,7 +47,7 @@
|
||||
|
||||
VideoCaption.prototype = {
|
||||
|
||||
destroy: function () {
|
||||
destroy: function() {
|
||||
this.state.el
|
||||
.off({
|
||||
'caption:fetch': this.fetchCaption,
|
||||
@@ -75,29 +74,29 @@
|
||||
* @desc Initiate rendering of elements, and set their initial configuration.
|
||||
*
|
||||
*/
|
||||
renderElements: function () {
|
||||
renderElements: function() {
|
||||
var languages = this.state.config.transcriptLanguages;
|
||||
|
||||
var langHtml = HtmlUtils.interpolateHtml(
|
||||
HtmlUtils.HTML(
|
||||
[
|
||||
'<div class="grouped-controls">',
|
||||
'<button class="control toggle-captions" aria-disabled="false">',
|
||||
'<span class="icon fa fa-cc" aria-hidden="true"></span>',
|
||||
'</button>',
|
||||
'<button class="control toggle-transcript" aria-disabled="false">',
|
||||
'<span class="icon fa fa-quote-left" aria-hidden="true"></span>',
|
||||
'</button>',
|
||||
'<div class="lang menu-container" role="application">',
|
||||
'<p class="sr instructions" id="lang-instructions"></p>',
|
||||
'<button class="control language-menu" aria-disabled="false"',
|
||||
'aria-describedby="lang-instructions" ',
|
||||
'title="{langTitle}">',
|
||||
'<span class="icon fa fa-caret-left" aria-hidden="true"></span>',
|
||||
'</button>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join(''),
|
||||
[
|
||||
'<div class="grouped-controls">',
|
||||
'<button class="control toggle-captions" aria-disabled="false">',
|
||||
'<span class="icon fa fa-cc" aria-hidden="true"></span>',
|
||||
'</button>',
|
||||
'<button class="control toggle-transcript" aria-disabled="false">',
|
||||
'<span class="icon fa fa-quote-left" aria-hidden="true"></span>',
|
||||
'</button>',
|
||||
'<div class="lang menu-container" role="application">',
|
||||
'<p class="sr instructions" id="lang-instructions"></p>',
|
||||
'<button class="control language-menu" aria-disabled="false"',
|
||||
'aria-describedby="lang-instructions" ',
|
||||
'title="{langTitle}">',
|
||||
'<span class="icon fa fa-caret-left" aria-hidden="true"></span>',
|
||||
'</button>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join(''),
|
||||
{
|
||||
langTitle: gettext('Open language menu')
|
||||
}
|
||||
@@ -109,8 +108,8 @@
|
||||
HtmlUtils.HTML(
|
||||
[
|
||||
'<div class="subtitles" role="region" id="transcript-{courseId}">',
|
||||
'<h3 id="transcript-label-{courseId}" class="transcript-title sr"></h3>',
|
||||
'<ol id="transcript-captions" class="subtitles-menu" lang="{courseLang}"></ol>',
|
||||
'<h3 id="transcript-label-{courseId}" class="transcript-title sr"></h3>',
|
||||
'<ol id="transcript-captions" class="subtitles-menu" lang="{courseLang}"></ol>',
|
||||
'</div>'
|
||||
].join('')),
|
||||
{
|
||||
@@ -140,7 +139,7 @@
|
||||
* mousemove, etc.).
|
||||
*
|
||||
*/
|
||||
bindHandlers: function () {
|
||||
bindHandlers: function() {
|
||||
var state = this.state,
|
||||
events = [
|
||||
'mouseover', 'mouseout', 'mousedown', 'click', 'focus', 'blur',
|
||||
@@ -195,7 +194,7 @@
|
||||
}
|
||||
},
|
||||
|
||||
onCaptionUpdate: function (event, time) {
|
||||
onCaptionUpdate: function(event, time) {
|
||||
this.updatePlayTime(time);
|
||||
},
|
||||
|
||||
@@ -203,11 +202,11 @@
|
||||
var KEY = $.ui.keyCode,
|
||||
keyCode = event.keyCode;
|
||||
|
||||
switch(keyCode) {
|
||||
case KEY.SPACE:
|
||||
case KEY.ENTER:
|
||||
event.preventDefault();
|
||||
this.toggleClosedCaptions(event);
|
||||
switch (keyCode) {
|
||||
case KEY.SPACE:
|
||||
case KEY.ENTER:
|
||||
event.preventDefault();
|
||||
this.toggleClosedCaptions(event);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -215,11 +214,11 @@
|
||||
var KEY = $.ui.keyCode,
|
||||
keyCode = event.keyCode;
|
||||
|
||||
switch(keyCode) {
|
||||
case KEY.SPACE:
|
||||
case KEY.ENTER:
|
||||
event.preventDefault();
|
||||
this.toggle(event);
|
||||
switch (keyCode) {
|
||||
case KEY.SPACE:
|
||||
case KEY.ENTER:
|
||||
event.preventDefault();
|
||||
this.toggle(event);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -228,32 +227,32 @@
|
||||
keyCode = event.keyCode,
|
||||
focused, index, total;
|
||||
|
||||
switch(keyCode) {
|
||||
case KEY.UP:
|
||||
event.preventDefault();
|
||||
focused = $(':focus').parent();
|
||||
index = this.languageChooserEl.find('li').index(focused);
|
||||
total = this.languageChooserEl.find('li').size() - 1;
|
||||
switch (keyCode) {
|
||||
case KEY.UP:
|
||||
event.preventDefault();
|
||||
focused = $(':focus').parent();
|
||||
index = this.languageChooserEl.find('li').index(focused);
|
||||
total = this.languageChooserEl.find('li').size() - 1;
|
||||
|
||||
this.previousLanguageMenuItem(event, index);
|
||||
break;
|
||||
this.previousLanguageMenuItem(event, index);
|
||||
break;
|
||||
|
||||
case KEY.DOWN:
|
||||
event.preventDefault();
|
||||
focused = $(':focus').parent();
|
||||
index = this.languageChooserEl.find('li').index(focused);
|
||||
total = this.languageChooserEl.find('li').size() - 1;
|
||||
case KEY.DOWN:
|
||||
event.preventDefault();
|
||||
focused = $(':focus').parent();
|
||||
index = this.languageChooserEl.find('li').index(focused);
|
||||
total = this.languageChooserEl.find('li').size() - 1;
|
||||
|
||||
this.nextLanguageMenuItem(event, index, total);
|
||||
break;
|
||||
this.nextLanguageMenuItem(event, index, total);
|
||||
break;
|
||||
|
||||
case KEY.ESCAPE:
|
||||
this.closeLanguageMenu(event);
|
||||
break;
|
||||
case KEY.ESCAPE:
|
||||
this.closeLanguageMenu(event);
|
||||
break;
|
||||
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
return true;
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -261,18 +260,18 @@
|
||||
var KEY = $.ui.keyCode,
|
||||
keyCode = event.keyCode;
|
||||
|
||||
switch(keyCode) {
|
||||
switch (keyCode) {
|
||||
// Handle keypresses
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
case KEY.UP:
|
||||
event.preventDefault();
|
||||
this.openLanguageMenu(event);
|
||||
break;
|
||||
case KEY.ENTER:
|
||||
case KEY.SPACE:
|
||||
case KEY.UP:
|
||||
event.preventDefault();
|
||||
this.openLanguageMenu(event);
|
||||
break;
|
||||
|
||||
case KEY.ESCAPE:
|
||||
this.closeLanguageMenu(event);
|
||||
break;
|
||||
case KEY.ESCAPE:
|
||||
this.closeLanguageMenu(event);
|
||||
break;
|
||||
}
|
||||
|
||||
return event.keyCode === KEY.TAB;
|
||||
@@ -347,27 +346,27 @@
|
||||
.focus();
|
||||
},
|
||||
|
||||
onCaptionHandler: function (event) {
|
||||
onCaptionHandler: function(event) {
|
||||
switch (event.type) {
|
||||
case 'mouseover':
|
||||
case 'mouseout':
|
||||
this.captionMouseOverOut(event);
|
||||
break;
|
||||
case 'mousedown':
|
||||
this.captionMouseDown(event);
|
||||
break;
|
||||
case 'click':
|
||||
this.captionClick(event);
|
||||
break;
|
||||
case 'focusin':
|
||||
this.captionFocus(event);
|
||||
break;
|
||||
case 'focusout':
|
||||
this.captionBlur(event);
|
||||
break;
|
||||
case 'keydown':
|
||||
this.captionKeyDown(event);
|
||||
break;
|
||||
case 'mouseover':
|
||||
case 'mouseout':
|
||||
this.captionMouseOverOut(event);
|
||||
break;
|
||||
case 'mousedown':
|
||||
this.captionMouseDown(event);
|
||||
break;
|
||||
case 'click':
|
||||
this.captionClick(event);
|
||||
break;
|
||||
case 'focusin':
|
||||
this.captionFocus(event);
|
||||
break;
|
||||
case 'focusout':
|
||||
this.captionBlur(event);
|
||||
break;
|
||||
case 'keydown':
|
||||
this.captionKeyDown(event);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -376,7 +375,7 @@
|
||||
*
|
||||
* @param {jquery Event} event
|
||||
*/
|
||||
onContainerMouseEnter: function (event) {
|
||||
onContainerMouseEnter: function(event) {
|
||||
event.preventDefault();
|
||||
$(event.currentTarget).find('.lang').addClass('is-opened');
|
||||
|
||||
@@ -393,7 +392,7 @@
|
||||
*
|
||||
* @param {jquery Event} event
|
||||
*/
|
||||
onContainerMouseLeave: function (event) {
|
||||
onContainerMouseLeave: function(event) {
|
||||
event.preventDefault();
|
||||
$(event.currentTarget).find('.lang').removeClass('is-opened');
|
||||
|
||||
@@ -410,7 +409,7 @@
|
||||
*
|
||||
* @param {jquery Event} event
|
||||
*/
|
||||
onMouseEnter: function () {
|
||||
onMouseEnter: function() {
|
||||
if (this.frozen) {
|
||||
clearTimeout(this.frozen);
|
||||
}
|
||||
@@ -426,7 +425,7 @@
|
||||
*
|
||||
* @param {jquery Event} event
|
||||
*/
|
||||
onMouseLeave: function () {
|
||||
onMouseLeave: function() {
|
||||
if (this.frozen) {
|
||||
clearTimeout(this.frozen);
|
||||
}
|
||||
@@ -443,7 +442,7 @@
|
||||
*
|
||||
* @param {jquery Event} event
|
||||
*/
|
||||
onMovement: function () {
|
||||
onMovement: function() {
|
||||
this.onMouseEnter();
|
||||
},
|
||||
|
||||
@@ -452,7 +451,7 @@
|
||||
*
|
||||
* @returns {array} if [startTime, endTime] are defined
|
||||
*/
|
||||
getStartEndTimes: function () {
|
||||
getStartEndTimes: function() {
|
||||
// due to the way config.startTime/endTime are
|
||||
// processed in 03_video_player.js, we assume
|
||||
// endTime can be an integer or null,
|
||||
@@ -469,7 +468,7 @@
|
||||
* @returns {object} {start, captions} parallel arrays of
|
||||
* start times and corresponding captions
|
||||
*/
|
||||
getBoundedCaptions: function () {
|
||||
getBoundedCaptions: function() {
|
||||
// get start and caption. If startTime and endTime
|
||||
// are specified, filter by that range.
|
||||
var times = this.getStartEndTimes();
|
||||
@@ -478,8 +477,8 @@
|
||||
var captions = results.captions;
|
||||
|
||||
return {
|
||||
'start': start,
|
||||
'captions': captions
|
||||
'start': start,
|
||||
'captions': captions
|
||||
};
|
||||
},
|
||||
|
||||
@@ -495,7 +494,7 @@
|
||||
* false: No caption file was specified, or an empty string was
|
||||
* specified for the Youtube type player.
|
||||
*/
|
||||
fetchCaption: function (fetchWithYoutubeId) {
|
||||
fetchCaption: function(fetchWithYoutubeId) {
|
||||
var self = this,
|
||||
state = this.state,
|
||||
language = state.getCurrentLanguage(),
|
||||
@@ -531,7 +530,7 @@
|
||||
url: url,
|
||||
notifyOnError: false,
|
||||
data: data,
|
||||
success: function (sjson) {
|
||||
success: function(sjson) {
|
||||
self.sjson = new Sjson(sjson);
|
||||
var results = self.getBoundedCaptions();
|
||||
var start = results.start;
|
||||
@@ -569,7 +568,7 @@
|
||||
|
||||
self.loaded = true;
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
error: function(jqXHR, textStatus, errorThrown) {
|
||||
console.log('[Video info]: ERROR while fetching captions.');
|
||||
console.log(
|
||||
'[Video info]: STATUS:', textStatus +
|
||||
@@ -603,14 +602,14 @@
|
||||
*
|
||||
* @returns {jquery Promise}
|
||||
*/
|
||||
fetchAvailableTranslations: function () {
|
||||
fetchAvailableTranslations: function() {
|
||||
var self = this,
|
||||
state = this.state;
|
||||
|
||||
this.availableTranslationsXHR = $.ajaxWithPrefix({
|
||||
url: state.config.transcriptAvailableTranslationsUrl,
|
||||
notifyOnError: false,
|
||||
success: function (response) {
|
||||
success: function(response) {
|
||||
var currentLanguages = state.config.transcriptLanguages,
|
||||
newLanguages = _.pick(currentLanguages, response);
|
||||
|
||||
@@ -625,7 +624,7 @@
|
||||
self.renderLanguageMenu(newLanguages);
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
error: function() {
|
||||
self.hideCaptions(true, false);
|
||||
self.state.el.find('.lang').hide();
|
||||
self.state.el.find('.transcript-control').hide();
|
||||
@@ -640,7 +639,7 @@
|
||||
* @desc Recalculates and updates the height of the container of captions.
|
||||
*
|
||||
*/
|
||||
onResize: function () {
|
||||
onResize: function() {
|
||||
this.subtitlesEl
|
||||
.find('.spacing').first()
|
||||
.height(this.topSpacingHeight());
|
||||
@@ -661,7 +660,7 @@
|
||||
* value - language label
|
||||
*
|
||||
*/
|
||||
renderLanguageMenu: function (languages) {
|
||||
renderLanguageMenu: function(languages) {
|
||||
var self = this,
|
||||
state = this.state,
|
||||
$menu = $('<ol class="langs-list menu">'),
|
||||
@@ -677,7 +676,7 @@
|
||||
this.showLanguageMenu = true;
|
||||
|
||||
$.each(languages, function(code, label) {
|
||||
$li = $('<li />', { 'data-lang-code': code });
|
||||
$li = $('<li />', {'data-lang-code': code});
|
||||
linkHtml = HtmlUtils.joinHtml(
|
||||
HtmlUtils.HTML('<button class="control control-lang">'),
|
||||
label,
|
||||
@@ -699,14 +698,14 @@
|
||||
HtmlUtils.HTML($menu)
|
||||
);
|
||||
|
||||
$menu.on('click', '.control-lang', function (e) {
|
||||
$menu.on('click', '.control-lang', function(e) {
|
||||
var el = $(e.currentTarget).parent(),
|
||||
state = self.state,
|
||||
langCode = el.data('lang-code');
|
||||
|
||||
if (state.lang !== langCode) {
|
||||
state.lang = langCode;
|
||||
el .addClass('is-active')
|
||||
el.addClass('is-active')
|
||||
.siblings('li')
|
||||
.removeClass('is-active')
|
||||
.find('.control-lang')
|
||||
@@ -738,21 +737,21 @@
|
||||
* @returns {object} jQuery's Promise object
|
||||
*
|
||||
*/
|
||||
buildCaptions: function (container, start, captions) {
|
||||
buildCaptions: function(container, start, captions) {
|
||||
var process = function(text, index) {
|
||||
var liEl = $('<li>', {
|
||||
'role': 'link',
|
||||
'data-index': index,
|
||||
'data-start': start[index],
|
||||
'tabindex': 0
|
||||
});
|
||||
var liEl = $('<li>', {
|
||||
'role': 'link',
|
||||
'data-index': index,
|
||||
'data-start': start[index],
|
||||
'tabindex': 0
|
||||
});
|
||||
|
||||
HtmlUtils.setHtml($(liEl), HtmlUtils.HTML(text.toString()));
|
||||
HtmlUtils.setHtml($(liEl), HtmlUtils.HTML(text.toString()));
|
||||
|
||||
return liEl[0];
|
||||
};
|
||||
return liEl[0];
|
||||
};
|
||||
|
||||
return AsyncProcess.array(captions, process).done(function (list) {
|
||||
return AsyncProcess.array(captions, process).done(function(list) {
|
||||
HtmlUtils.append(
|
||||
container,
|
||||
HtmlUtils.HTML(list)
|
||||
@@ -767,10 +766,10 @@
|
||||
* @param {array} captions List of captions for the video.
|
||||
*
|
||||
*/
|
||||
renderCaption: function (start, captions) {
|
||||
renderCaption: function(start, captions) {
|
||||
var self = this;
|
||||
|
||||
var onRender = function () {
|
||||
var onRender = function() {
|
||||
self.addPaddings();
|
||||
// Enables or disables automatic scrolling of the captions when the
|
||||
// video is playing. This feature has to be disabled when tabbing
|
||||
@@ -809,7 +808,6 @@
|
||||
|
||||
self.container.find('.menu-container .instructions')
|
||||
.text(gettext('Press the UP arrow key to enter the language menu then use UP and DOWN arrow keys to navigate language options. Press ENTER to change to the selected language.')); // eslint-disable-line max-len
|
||||
|
||||
};
|
||||
|
||||
this.rendered = false;
|
||||
@@ -830,10 +828,10 @@
|
||||
'<a href="#transcript-end-{id}" id="transcript-start-{id}" class="transcript-start"></a>', // eslint-disable-line max-len, indent
|
||||
'</li>'
|
||||
].join('')),
|
||||
{
|
||||
id: this.state.id,
|
||||
height: this.topSpacingHeight()
|
||||
}
|
||||
{
|
||||
id: this.state.id,
|
||||
height: this.topSpacingHeight()
|
||||
}
|
||||
);
|
||||
|
||||
var bottomSpacer = HtmlUtils.interpolateHtml(
|
||||
@@ -842,10 +840,10 @@
|
||||
'<a href="#transcript-start-{id}" id="transcript-end-{id}" class="transcript-end"></a>', // eslint-disable-line max-len, indent
|
||||
'</li>'
|
||||
].join('')),
|
||||
{
|
||||
id: this.state.id,
|
||||
height: this.bottomSpacingHeight()
|
||||
}
|
||||
{
|
||||
id: this.state.id,
|
||||
height: this.bottomSpacingHeight()
|
||||
}
|
||||
);
|
||||
|
||||
HtmlUtils.prepend(
|
||||
@@ -867,7 +865,7 @@
|
||||
* @param {jquery Event} event
|
||||
*
|
||||
*/
|
||||
captionMouseOverOut: function (event) {
|
||||
captionMouseOverOut: function(event) {
|
||||
var caption = $(event.target),
|
||||
captionIndex = parseInt(caption.attr('data-index'), 10);
|
||||
|
||||
@@ -887,7 +885,7 @@
|
||||
* @param {jquery Event} event
|
||||
*
|
||||
*/
|
||||
captionMouseDown: function (event) {
|
||||
captionMouseDown: function(event) {
|
||||
var caption = $(event.target);
|
||||
|
||||
this.isMouseFocus = true;
|
||||
@@ -902,7 +900,7 @@
|
||||
* @param {jquery Event} event
|
||||
*
|
||||
*/
|
||||
captionClick: function (event) {
|
||||
captionClick: function(event) {
|
||||
this.seekPlayer(event);
|
||||
},
|
||||
|
||||
@@ -912,7 +910,7 @@
|
||||
* @param {jquery Event} event
|
||||
*
|
||||
*/
|
||||
captionFocus: function (event) {
|
||||
captionFocus: function(event) {
|
||||
var caption = $(event.target),
|
||||
captionIndex = parseInt(caption.attr('data-index'), 10);
|
||||
// If the focus comes from a mouse click, hide the outline, turn on
|
||||
@@ -945,7 +943,7 @@
|
||||
* @param {jquery Event} event
|
||||
*
|
||||
*/
|
||||
captionBlur: function (event) {
|
||||
captionBlur: function(event) {
|
||||
var caption = $(event.target),
|
||||
captionIndex = parseInt(caption.attr('data-index'), 10);
|
||||
|
||||
@@ -957,7 +955,6 @@
|
||||
// forward out of the captions.
|
||||
if (captionIndex === 0 ||
|
||||
captionIndex === this.sjson.getSize() - 1) {
|
||||
|
||||
this.autoScrolling = true;
|
||||
}
|
||||
},
|
||||
@@ -968,9 +965,9 @@
|
||||
* @param {jquery Event} event
|
||||
*
|
||||
*/
|
||||
captionKeyDown: function (event) {
|
||||
captionKeyDown: function(event) {
|
||||
this.isMouseFocus = false;
|
||||
if (event.which === 13) { //Enter key
|
||||
if (event.which === 13) { // Enter key
|
||||
this.seekPlayer(event);
|
||||
}
|
||||
},
|
||||
@@ -979,7 +976,7 @@
|
||||
* @desc Scrolls caption container to make active caption visible.
|
||||
*
|
||||
*/
|
||||
scrollCaption: function () {
|
||||
scrollCaption: function() {
|
||||
var el = this.subtitlesEl.find('.current:first');
|
||||
|
||||
// Automatic scrolling gets disabled if one of the captions has
|
||||
@@ -1002,7 +999,7 @@
|
||||
* @desc Updates flags on play
|
||||
*
|
||||
*/
|
||||
play: function () {
|
||||
play: function() {
|
||||
var captions, startAndCaptions, start;
|
||||
if (this.loaded) {
|
||||
if (!this.rendered) {
|
||||
@@ -1020,7 +1017,7 @@
|
||||
* @desc Updates flags on pause
|
||||
*
|
||||
*/
|
||||
pause: function () {
|
||||
pause: function() {
|
||||
if (this.loaded) {
|
||||
this.playing = false;
|
||||
}
|
||||
@@ -1032,7 +1029,7 @@
|
||||
* @param {number} time Time in seconds.
|
||||
*
|
||||
*/
|
||||
updatePlayTime: function (time) {
|
||||
updatePlayTime: function(time) {
|
||||
var state = this.state,
|
||||
params, newIndex;
|
||||
|
||||
@@ -1076,7 +1073,7 @@
|
||||
* @param {jquery Event} event
|
||||
*
|
||||
*/
|
||||
seekPlayer: function (event) {
|
||||
seekPlayer: function(event) {
|
||||
var state = this.state,
|
||||
time = parseInt($(event.target).data('start'), 10);
|
||||
|
||||
@@ -1088,7 +1085,7 @@
|
||||
'videoPlayer.onCaptionSeek',
|
||||
{
|
||||
'type': 'onCaptionSeek',
|
||||
'time': time/1000
|
||||
'time': time / 1000
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1102,7 +1099,7 @@
|
||||
* @returns {number} Offset for the passed padding element.
|
||||
*
|
||||
*/
|
||||
calculateOffset: function (element) {
|
||||
calculateOffset: function(element) {
|
||||
return this.captionHeight() / 2 - element.height() / 2;
|
||||
},
|
||||
|
||||
@@ -1112,7 +1109,7 @@
|
||||
* @returns {number} Offset for the passed top padding element.
|
||||
*
|
||||
*/
|
||||
topSpacingHeight: function () {
|
||||
topSpacingHeight: function() {
|
||||
return this.calculateOffset(
|
||||
this.subtitlesEl.find('li:not(.spacing)').first()
|
||||
);
|
||||
@@ -1124,7 +1121,7 @@
|
||||
* @returns {number} Offset for the passed bottom padding element.
|
||||
*
|
||||
*/
|
||||
bottomSpacingHeight: function () {
|
||||
bottomSpacingHeight: function() {
|
||||
return this.calculateOffset(
|
||||
this.subtitlesEl.find('li:not(.spacing)').last()
|
||||
);
|
||||
@@ -1136,7 +1133,7 @@
|
||||
* @param {jquery Event} event
|
||||
*
|
||||
*/
|
||||
toggle: function (event) {
|
||||
toggle: function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
if (this.state.el.hasClass('closed')) {
|
||||
@@ -1229,8 +1226,8 @@
|
||||
var captions = document.querySelector('.closed-captions'),
|
||||
draggable;
|
||||
|
||||
if (typeof Draggabilly === "function") {
|
||||
draggable = new Draggabilly(captions, { containment: true });
|
||||
if (typeof Draggabilly === 'function') {
|
||||
draggable = new Draggabilly(captions, {containment: true});
|
||||
} else {
|
||||
console.log('Closed captioning available but not draggable');
|
||||
}
|
||||
@@ -1244,7 +1241,7 @@
|
||||
* @param {boolean} update_cookie Flag to update or not the cookie.
|
||||
*
|
||||
*/
|
||||
hideCaptions: function (hide_captions, update_cookie, trigger_event) {
|
||||
hideCaptions: function(hide_captions, update_cookie, trigger_event) {
|
||||
var transcriptControlEl = this.transcriptControlEl,
|
||||
state = this.state, text;
|
||||
|
||||
@@ -1300,7 +1297,7 @@
|
||||
* @returns {number} event Height of the container in pixels.
|
||||
*
|
||||
*/
|
||||
captionHeight: function () {
|
||||
captionHeight: function() {
|
||||
var state = this.state;
|
||||
if (state.isFullScreen) {
|
||||
return state.container.height() - state.videoFullScreen.height;
|
||||
@@ -1313,11 +1310,11 @@
|
||||
* @desc Sets the height of the caption container element.
|
||||
*
|
||||
*/
|
||||
setSubtitlesHeight: function () {
|
||||
setSubtitlesHeight: function() {
|
||||
var height = 0,
|
||||
state = this.state;
|
||||
// on page load captionHidden = undefined
|
||||
if ((state.captionsHidden === undefined && state.hide_captions) ||
|
||||
if ((state.captionsHidden === undefined && state.hide_captions) ||
|
||||
state.captionsHidden === true
|
||||
) {
|
||||
// In case of html5 autoshowing subtitles, we adjust height of
|
||||
@@ -1337,5 +1334,4 @@
|
||||
|
||||
return VideoCaption;
|
||||
});
|
||||
|
||||
}(RequireJS.define));
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define('video/10_commands.js', [], function() {
|
||||
var VideoCommands, Command, playCommand, pauseCommand, togglePlaybackCommand,
|
||||
toggleMuteCommand, toggleFullScreenCommand, setSpeedCommand, skipCommand;
|
||||
'use strict';
|
||||
define('video/10_commands.js', [], function() {
|
||||
var VideoCommands, Command, playCommand, pauseCommand, togglePlaybackCommand,
|
||||
toggleMuteCommand, toggleFullScreenCommand, setSpeedCommand, skipCommand;
|
||||
/**
|
||||
* Video commands module.
|
||||
* @exports video/10_commands.js
|
||||
@@ -11,100 +11,100 @@ define('video/10_commands.js', [], function() {
|
||||
* @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);
|
||||
}
|
||||
VideoCommands = function(state, i18n) {
|
||||
if (!(this instanceof VideoCommands)) {
|
||||
return new VideoCommands(state, i18n);
|
||||
}
|
||||
|
||||
_.bindAll(this, 'destroy');
|
||||
this.state = state;
|
||||
this.state.videoCommands = this;
|
||||
this.i18n = i18n;
|
||||
this.commands = [];
|
||||
this.initialize();
|
||||
_.bindAll(this, 'destroy');
|
||||
this.state = state;
|
||||
this.state.videoCommands = this;
|
||||
this.i18n = i18n;
|
||||
this.commands = [];
|
||||
this.initialize();
|
||||
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
|
||||
VideoCommands.prototype = {
|
||||
destroy: function () {
|
||||
this.state.el.off('destroy', this.destroy);
|
||||
delete this.state.videoCommands;
|
||||
},
|
||||
VideoCommands.prototype = {
|
||||
destroy: function() {
|
||||
this.state.el.off('destroy', this.destroy);
|
||||
delete this.state.videoCommands;
|
||||
},
|
||||
|
||||
/** Initializes the module. */
|
||||
initialize: function() {
|
||||
this.commands = this.getCommands();
|
||||
this.state.el.on('destroy', this.destroy);
|
||||
},
|
||||
initialize: function() {
|
||||
this.commands = this.getCommands();
|
||||
this.state.el.on('destroy', this.destroy);
|
||||
},
|
||||
|
||||
execute: function (command) {
|
||||
var args = [].slice.call(arguments, 1) || [];
|
||||
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.');
|
||||
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,
|
||||
skipCommand
|
||||
];
|
||||
|
||||
_.each(commandsList, function(command) {
|
||||
commands[command.name] = command;
|
||||
}, this);
|
||||
|
||||
return commands;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
getCommands: function () {
|
||||
var commands = {},
|
||||
commandsList = [
|
||||
playCommand, pauseCommand, togglePlaybackCommand,
|
||||
toggleMuteCommand, toggleFullScreenCommand, setSpeedCommand,
|
||||
skipCommand
|
||||
];
|
||||
Command = function(name, execute) {
|
||||
this.name = name;
|
||||
this.execute = execute;
|
||||
};
|
||||
|
||||
_.each(commandsList, function(command) {
|
||||
commands[command.name] = command;
|
||||
}, this);
|
||||
playCommand = new Command('play', function(state) {
|
||||
state.videoPlayer.play();
|
||||
});
|
||||
|
||||
return commands;
|
||||
}
|
||||
};
|
||||
pauseCommand = new Command('pause', function(state) {
|
||||
state.videoPlayer.pause();
|
||||
});
|
||||
|
||||
Command = function (name, execute) {
|
||||
this.name = name;
|
||||
this.execute = execute;
|
||||
};
|
||||
togglePlaybackCommand = new Command('togglePlayback', function(state) {
|
||||
if (state.videoPlayer.isPlaying()) {
|
||||
pauseCommand.execute(state);
|
||||
} else {
|
||||
playCommand.execute(state);
|
||||
}
|
||||
});
|
||||
|
||||
playCommand = new Command('play', function (state) {
|
||||
state.videoPlayer.play();
|
||||
toggleMuteCommand = new Command('toggleMute', function(state) {
|
||||
state.videoVolumeControl.toggleMute();
|
||||
});
|
||||
|
||||
toggleFullScreenCommand = new Command('toggleFullScreen', function(state) {
|
||||
state.videoFullScreen.toggle();
|
||||
});
|
||||
|
||||
setSpeedCommand = new Command('speed', function(state, speed) {
|
||||
state.videoSpeedControl.setSpeed(state.speedToString(speed));
|
||||
});
|
||||
|
||||
skipCommand = new Command('skip', function(state, doNotShowAgain) {
|
||||
if (doNotShowAgain) {
|
||||
state.videoBumper.skipAndDoNotShowAgain();
|
||||
} else {
|
||||
state.videoBumper.skip();
|
||||
}
|
||||
});
|
||||
|
||||
return VideoCommands;
|
||||
});
|
||||
|
||||
pauseCommand = new Command('pause', function (state) {
|
||||
state.videoPlayer.pause();
|
||||
});
|
||||
|
||||
togglePlaybackCommand = new Command('togglePlayback', function (state) {
|
||||
if (state.videoPlayer.isPlaying()) {
|
||||
pauseCommand.execute(state);
|
||||
} else {
|
||||
playCommand.execute(state);
|
||||
}
|
||||
});
|
||||
|
||||
toggleMuteCommand = new Command('toggleMute', function (state) {
|
||||
state.videoVolumeControl.toggleMute();
|
||||
});
|
||||
|
||||
toggleFullScreenCommand = new Command('toggleFullScreen', function (state) {
|
||||
state.videoFullScreen.toggle();
|
||||
});
|
||||
|
||||
setSpeedCommand = new Command('speed', function (state, speed) {
|
||||
state.videoSpeedControl.setSpeed(state.speedToString(speed));
|
||||
});
|
||||
|
||||
skipCommand = new Command('skip', function (state, doNotShowAgain) {
|
||||
if (doNotShowAgain) {
|
||||
state.videoBumper.skipAndDoNotShowAgain();
|
||||
} else {
|
||||
state.videoBumper.skip();
|
||||
}
|
||||
});
|
||||
|
||||
return VideoCommands;
|
||||
});
|
||||
}(RequireJS.define));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(function (require, $) {
|
||||
(function(require, $) {
|
||||
'use strict';
|
||||
// In the case when the Video constructor will be called before RequireJS finishes loading all of the Video
|
||||
// dependencies, we will have a mock function that will collect all the elements that must be initialized as
|
||||
@@ -7,15 +7,15 @@
|
||||
// Once RequireJS will load all of the necessary dependencies, main code will invoke the mock function with
|
||||
// the second parameter set to truthy value. This will trigger the actual Video constructor on all elements
|
||||
// that are stored in a temporary list.
|
||||
window.Video = (function () {
|
||||
window.Video = (function() {
|
||||
// Temporary storage place for elements that must be initialized as Video elements.
|
||||
var tempCallStack = [];
|
||||
|
||||
return function (element, processTempCallStack) {
|
||||
return function(element, processTempCallStack) {
|
||||
// If mock function was called with second parameter set to truthy value, we invoke the real `window.Video`
|
||||
// on all the stored elements so far.
|
||||
if (processTempCallStack) {
|
||||
$.each(tempCallStack, function (index, element) {
|
||||
$.each(tempCallStack, function(index, element) {
|
||||
// By now, `window.Video` is the real constructor.
|
||||
window.Video(element);
|
||||
});
|
||||
@@ -57,7 +57,7 @@
|
||||
'video/10_commands.js',
|
||||
'video/095_video_context_menu.js'
|
||||
],
|
||||
function (
|
||||
function(
|
||||
VideoStorage, initialize, FocusGrabber, VideoAccessibleMenu, VideoControl, VideoFullScreen,
|
||||
VideoQualityControl, VideoProgressSlider, VideoVolumeControl, VideoSpeedControl, VideoCaption,
|
||||
VideoPlayPlaceholder, VideoPlayPauseControl, VideoPlaySkipControl, VideoSkipControl, VideoBumper,
|
||||
@@ -67,7 +67,7 @@
|
||||
var youtubeXhr = null,
|
||||
oldVideo = window.Video;
|
||||
|
||||
window.Video = function (element) {
|
||||
window.Video = function(element) {
|
||||
var el = $(element).find('.video'),
|
||||
id = el.attr('id').replace(/video_/, ''),
|
||||
storage = VideoStorage('VideoState', id),
|
||||
@@ -88,14 +88,14 @@
|
||||
modules: mainVideoModules
|
||||
};
|
||||
|
||||
var getBumperState = function (metadata) {
|
||||
var getBumperState = function(metadata) {
|
||||
var bumperState = $.extend(true, {
|
||||
el: el,
|
||||
id: id,
|
||||
storage: storage,
|
||||
options: {},
|
||||
youtubeXhr: youtubeXhr
|
||||
}, {metadata: metadata});
|
||||
el: el,
|
||||
id: id,
|
||||
storage: storage,
|
||||
options: {},
|
||||
youtubeXhr: youtubeXhr
|
||||
}, {metadata: metadata});
|
||||
|
||||
bumperState.modules = bumperVideoModules;
|
||||
bumperState.options = {
|
||||
@@ -104,8 +104,8 @@
|
||||
return bumperState;
|
||||
};
|
||||
|
||||
var player = function (state) {
|
||||
return function () {
|
||||
var player = function(state) {
|
||||
return function() {
|
||||
_.extend(state.metadata, {autoplay: true, focusFirstControl: true});
|
||||
initialize(state, element);
|
||||
};
|
||||
@@ -119,7 +119,7 @@
|
||||
if (bumperMetadata) {
|
||||
new VideoPoster(el, {
|
||||
poster: el.data('poster'),
|
||||
onClick: _.once(function () {
|
||||
onClick: _.once(function() {
|
||||
var mainVideoPlayer = player(state), bumper, bumperState;
|
||||
if (storage.getItem('isBumperShown')) {
|
||||
mainVideoPlayer();
|
||||
@@ -127,7 +127,7 @@
|
||||
bumperState = getBumperState(bumperMetadata);
|
||||
bumper = new VideoBumper(player(bumperState), bumperState);
|
||||
state.bumperState = bumperState;
|
||||
bumper.getPromise().done(function () {
|
||||
bumper.getPromise().done(function() {
|
||||
delete state.bumperState;
|
||||
mainVideoPlayer();
|
||||
});
|
||||
@@ -143,7 +143,7 @@
|
||||
}
|
||||
|
||||
el.data('video-player-state', state);
|
||||
var onSequenceChange = function onSequenceChange () {
|
||||
var onSequenceChange = function onSequenceChange() {
|
||||
if (state && state.videoPlayer) {
|
||||
state.videoPlayer.destroy();
|
||||
}
|
||||
@@ -156,7 +156,7 @@
|
||||
return state;
|
||||
};
|
||||
|
||||
window.Video.clearYoutubeXhr = function () {
|
||||
window.Video.clearYoutubeXhr = function() {
|
||||
youtubeXhr = null;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
window.WordCloud = function (el) {
|
||||
RequireJS.require(['WordCloudMain'], function (WordCloudMain) {
|
||||
window.WordCloud = function(el) {
|
||||
RequireJS.require(['WordCloudMain'], function(WordCloudMain) {
|
||||
new WordCloudMain(el);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -11,9 +11,8 @@
|
||||
* @external d3, $, RequireJS
|
||||
*/
|
||||
|
||||
(function (requirejs, require, define) {
|
||||
define('WordCloudMain', [], function () {
|
||||
|
||||
(function(requirejs, require, define) {
|
||||
define('WordCloudMain', [], function() {
|
||||
/**
|
||||
* @function WordCloudMain
|
||||
*
|
||||
@@ -27,26 +26,26 @@ define('WordCloudMain', [], function () {
|
||||
*
|
||||
* @param {jQuery} el DOM element where the word cloud will be processed and created.
|
||||
*/
|
||||
var WordCloudMain = function (el) {
|
||||
var _this = this;
|
||||
var WordCloudMain = function(el) {
|
||||
var _this = this;
|
||||
|
||||
this.wordCloudEl = $(el).find('.word_cloud');
|
||||
this.wordCloudEl = $(el).find('.word_cloud');
|
||||
|
||||
// Get the URL to which we will post the users words.
|
||||
this.ajax_url = this.wordCloudEl.data('ajax-url');
|
||||
this.ajax_url = this.wordCloudEl.data('ajax-url');
|
||||
|
||||
// Dimensions of the box where the word cloud will be drawn.
|
||||
this.width = 635;
|
||||
this.height = 635;
|
||||
this.width = 635;
|
||||
this.height = 635;
|
||||
|
||||
// Hide WordCloud container before Ajax request done
|
||||
this.wordCloudEl.hide();
|
||||
this.wordCloudEl.hide();
|
||||
|
||||
// Retriveing response from the server as an AJAX request. Attach a callback that will
|
||||
// be fired on server's response.
|
||||
$.postWithPrefix(
|
||||
$.postWithPrefix(
|
||||
_this.ajax_url + '/' + 'get_state', null,
|
||||
function (response) {
|
||||
function(response) {
|
||||
if (response.status !== 'success') {
|
||||
console.log('ERROR: ' + response.error);
|
||||
|
||||
@@ -56,7 +55,7 @@ define('WordCloudMain', [], function () {
|
||||
_this.configJson = response;
|
||||
}
|
||||
)
|
||||
.done(function () {
|
||||
.done(function() {
|
||||
// Show WordCloud container after Ajax request done
|
||||
_this.wordCloudEl.show();
|
||||
|
||||
@@ -67,10 +66,10 @@ define('WordCloudMain', [], function () {
|
||||
}
|
||||
});
|
||||
|
||||
$(el).find('input.save').on('click', function () {
|
||||
_this.submitAnswer();
|
||||
});
|
||||
}; // End-of: var WordCloudMain = function (el) {
|
||||
$(el).find('input.save').on('click', function() {
|
||||
_this.submitAnswer();
|
||||
});
|
||||
}; // End-of: var WordCloudMain = function (el) {
|
||||
|
||||
/**
|
||||
* @function submitAnswer
|
||||
@@ -79,20 +78,20 @@ define('WordCloudMain', [], function () {
|
||||
* server, and upon receiving correct response, will call the function to generate the
|
||||
* word cloud.
|
||||
*/
|
||||
WordCloudMain.prototype.submitAnswer = function () {
|
||||
var _this = this,
|
||||
data = {'student_words': []};
|
||||
WordCloudMain.prototype.submitAnswer = function() {
|
||||
var _this = this,
|
||||
data = {'student_words': []};
|
||||
|
||||
// Populate the data to be sent to the server with user's words.
|
||||
this.wordCloudEl.find('input.input-cloud').each(function (index, value) {
|
||||
data.student_words.push($(value).val());
|
||||
});
|
||||
this.wordCloudEl.find('input.input-cloud').each(function(index, value) {
|
||||
data.student_words.push($(value).val());
|
||||
});
|
||||
|
||||
// Send the data to the server as an AJAX request. Attach a callback that will
|
||||
// be fired on server's response.
|
||||
$.postWithPrefix(
|
||||
$.postWithPrefix(
|
||||
_this.ajax_url + '/' + 'submit', $.param(data),
|
||||
function (response) {
|
||||
function(response) {
|
||||
if (response.status !== 'success') {
|
||||
console.log('ERROR: ' + response.error);
|
||||
|
||||
@@ -102,8 +101,7 @@ define('WordCloudMain', [], function () {
|
||||
_this.showWordCloud(response);
|
||||
}
|
||||
);
|
||||
|
||||
}; // End-of: WordCloudMain.prototype.submitAnswer = function () {
|
||||
}; // End-of: WordCloudMain.prototype.submitAnswer = function () {
|
||||
|
||||
/**
|
||||
* @function showWordCloud
|
||||
@@ -114,71 +112,71 @@ define('WordCloudMain', [], function () {
|
||||
* This function will set up everything for d3 and launch the draw method. Among other things,
|
||||
* iw will determine maximum word size.
|
||||
*/
|
||||
WordCloudMain.prototype.showWordCloud = function (response) {
|
||||
var words,
|
||||
_this = this,
|
||||
maxSize, minSize, scaleFactor, maxFontSize, minFontSize;
|
||||
WordCloudMain.prototype.showWordCloud = function(response) {
|
||||
var words,
|
||||
_this = this,
|
||||
maxSize, minSize, scaleFactor, maxFontSize, minFontSize;
|
||||
|
||||
this.wordCloudEl.find('.input_cloud_section').hide();
|
||||
this.wordCloudEl.find('.input_cloud_section').hide();
|
||||
|
||||
words = response.top_words;
|
||||
maxSize = 0;
|
||||
minSize = 10000;
|
||||
scaleFactor = 1;
|
||||
maxFontSize = 200;
|
||||
minFontSize = 15;
|
||||
words = response.top_words;
|
||||
maxSize = 0;
|
||||
minSize = 10000;
|
||||
scaleFactor = 1;
|
||||
maxFontSize = 200;
|
||||
minFontSize = 15;
|
||||
|
||||
// Find the word with the maximum percentage. I.e. the most popular word.
|
||||
$.each(words, function (index, word) {
|
||||
if (word.size > maxSize) {
|
||||
maxSize = word.size;
|
||||
}
|
||||
if (word.size < minSize) {
|
||||
minSize = word.size;
|
||||
}
|
||||
});
|
||||
$.each(words, function(index, word) {
|
||||
if (word.size > maxSize) {
|
||||
maxSize = word.size;
|
||||
}
|
||||
if (word.size < minSize) {
|
||||
minSize = word.size;
|
||||
}
|
||||
});
|
||||
|
||||
// Find the longest word, and calculate the scale appropriately. This is
|
||||
// required so that even long words fit into the drawing area.
|
||||
//
|
||||
// This is a fix for: if the word is very long and/or big, it is discarded by
|
||||
// for unknown reason.
|
||||
$.each(words, function (index, word) {
|
||||
var tempScaleFactor = 1.0,
|
||||
size = ((word.size / maxSize) * maxFontSize);
|
||||
$.each(words, function(index, word) {
|
||||
var tempScaleFactor = 1.0,
|
||||
size = ((word.size / maxSize) * maxFontSize);
|
||||
|
||||
if (size * 0.7 * word.text.length > _this.width) {
|
||||
tempScaleFactor = ((_this.width / word.text.length) / 0.7) / size;
|
||||
}
|
||||
if (size * 0.7 * word.text.length > _this.width) {
|
||||
tempScaleFactor = ((_this.width / word.text.length) / 0.7) / size;
|
||||
}
|
||||
|
||||
if (scaleFactor > tempScaleFactor) {
|
||||
scaleFactor = tempScaleFactor;
|
||||
}
|
||||
});
|
||||
if (scaleFactor > tempScaleFactor) {
|
||||
scaleFactor = tempScaleFactor;
|
||||
}
|
||||
});
|
||||
|
||||
// Update the maximum font size based on the longest word.
|
||||
maxFontSize *= scaleFactor;
|
||||
maxFontSize *= scaleFactor;
|
||||
|
||||
// Generate the word cloud.
|
||||
d3.layout.cloud().size([this.width, this.height])
|
||||
d3.layout.cloud().size([this.width, this.height])
|
||||
.words(words)
|
||||
.rotate(function () {
|
||||
.rotate(function() {
|
||||
return Math.floor((Math.random() * 2)) * 90;
|
||||
})
|
||||
.font('Impact')
|
||||
.fontSize(function (d) {
|
||||
.fontSize(function(d) {
|
||||
var size = (d.size / maxSize) * maxFontSize;
|
||||
|
||||
size = size >= minFontSize ? size : minFontSize;
|
||||
|
||||
return size;
|
||||
})
|
||||
.on('end', function (words, bounds) {
|
||||
.on('end', function(words, bounds) {
|
||||
// Draw the word cloud.
|
||||
_this.drawWordCloud(response, words, bounds);
|
||||
})
|
||||
.start();
|
||||
}; // End-of: WordCloudMain.prototype.showWordCloud = function (response) {
|
||||
}; // End-of: WordCloudMain.prototype.showWordCloud = function (response) {
|
||||
|
||||
/**
|
||||
* @function drawWordCloud
|
||||
@@ -198,52 +196,52 @@ define('WordCloudMain', [], function () {
|
||||
* box where all of the words fir, second object is the bottom-right coordinates of the bounding box. Each
|
||||
* coordinate object contains two properties: 'x', and 'y'.
|
||||
*/
|
||||
WordCloudMain.prototype.drawWordCloud = function (response, words, bounds) {
|
||||
WordCloudMain.prototype.drawWordCloud = function(response, words, bounds) {
|
||||
// Color words in different colors.
|
||||
var fill = d3.scale.category20(),
|
||||
var fill = d3.scale.category20(),
|
||||
|
||||
// Will be populated by words the user enetered.
|
||||
studentWordsKeys = [],
|
||||
studentWordsKeys = [],
|
||||
|
||||
// Comma separated string of user enetered words.
|
||||
studentWordsStr,
|
||||
studentWordsStr,
|
||||
|
||||
// By default we do not scale.
|
||||
scale = 1,
|
||||
scale = 1,
|
||||
|
||||
// Caсhing of DOM element
|
||||
cloudSectionEl = this.wordCloudEl.find('.result_cloud_section'),
|
||||
cloudSectionEl = this.wordCloudEl.find('.result_cloud_section'),
|
||||
|
||||
// Needed for caсhing of d3 group elements
|
||||
groupEl;
|
||||
groupEl;
|
||||
|
||||
// If bounding rectangle is given, scale based on the bounding box of all the words.
|
||||
if (bounds) {
|
||||
scale = 0.5 * Math.min(
|
||||
if (bounds) {
|
||||
scale = 0.5 * Math.min(
|
||||
this.width / Math.abs(bounds[1].x - this.width / 2),
|
||||
this.width / Math.abs(bounds[0].x - this.width / 2),
|
||||
this.height / Math.abs(bounds[1].y - this.height / 2),
|
||||
this.height / Math.abs(bounds[0].y - this.height / 2)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$.each(response.student_words, function (word, stat) {
|
||||
var percent = (response.display_student_percents) ? ' ' + (Math.round(100 * (stat / response.total_count))) + '%' : '';
|
||||
$.each(response.student_words, function(word, stat) {
|
||||
var percent = (response.display_student_percents) ? ' ' + (Math.round(100 * (stat / response.total_count))) + '%' : '';
|
||||
|
||||
studentWordsKeys.push('<strong>' + word + '</strong>' + percent);
|
||||
});
|
||||
studentWordsStr = '' + studentWordsKeys.join(', ');
|
||||
studentWordsKeys.push('<strong>' + word + '</strong>' + percent);
|
||||
});
|
||||
studentWordsStr = '' + studentWordsKeys.join(', ');
|
||||
|
||||
cloudSectionEl
|
||||
cloudSectionEl
|
||||
.addClass('active')
|
||||
.find('.your_words').html(studentWordsStr)
|
||||
.end()
|
||||
.find('.total_num_words').html(response.total_count);
|
||||
|
||||
$(cloudSectionEl.attr('id') + ' .word_cloud').empty();
|
||||
$(cloudSectionEl.attr('id') + ' .word_cloud').empty();
|
||||
|
||||
// Actual drawing of word cloud.
|
||||
groupEl = d3.select('#' + cloudSectionEl.attr('id') + ' .word_cloud').append('svg')
|
||||
groupEl = d3.select('#' + cloudSectionEl.attr('id') + ' .word_cloud').append('svg')
|
||||
.attr('width', this.width)
|
||||
.attr('height', this.height)
|
||||
.append('g')
|
||||
@@ -252,12 +250,12 @@ define('WordCloudMain', [], function () {
|
||||
.data(words)
|
||||
.enter().append('g');
|
||||
|
||||
groupEl
|
||||
groupEl
|
||||
.append('title')
|
||||
.text(function (d) {
|
||||
.text(function(d) {
|
||||
var res = '';
|
||||
|
||||
$.each(response.top_words, function(index, value){
|
||||
$.each(response.top_words, function(index, value) {
|
||||
if (value.text === d.text) {
|
||||
res = value.percent + '%';
|
||||
|
||||
@@ -268,25 +266,24 @@ define('WordCloudMain', [], function () {
|
||||
return res;
|
||||
});
|
||||
|
||||
groupEl
|
||||
groupEl
|
||||
.append('text')
|
||||
.style('font-size', function (d) {
|
||||
.style('font-size', function(d) {
|
||||
return d.size + 'px';
|
||||
})
|
||||
.style('font-family', 'Impact')
|
||||
.style('fill', function (d, i) {
|
||||
.style('fill', function(d, i) {
|
||||
return fill(i);
|
||||
})
|
||||
.attr('text-anchor', 'middle')
|
||||
.attr('transform', function (d) {
|
||||
.attr('transform', function(d) {
|
||||
return 'translate(' + [d.x, d.y] + ')rotate(' + d.rotate + ')scale(' + scale + ')';
|
||||
})
|
||||
.text(function (d) {
|
||||
.text(function(d) {
|
||||
return d.text;
|
||||
});
|
||||
}; // End-of: WordCloudMain.prototype.drawWordCloud = function (words, bounds) {
|
||||
}; // End-of: WordCloudMain.prototype.drawWordCloud = function (words, bounds) {
|
||||
|
||||
return WordCloudMain;
|
||||
|
||||
}); // End-of: define('WordCloudMain', [], function () {
|
||||
return WordCloudMain;
|
||||
}); // End-of: define('WordCloudMain', [], function () {
|
||||
}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(function () {
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var XModule = {};
|
||||
|
||||
XModule.Descriptor = (function () {
|
||||
XModule.Descriptor = (function() {
|
||||
/*
|
||||
* Bind the module to an element. This may be called multiple times,
|
||||
* if the element content has changed and so the module needs to be rebound
|
||||
@@ -11,7 +11,7 @@
|
||||
* @method: constructor
|
||||
* @param {html element} the .xmodule_edit section containing all of the descriptor content
|
||||
*/
|
||||
var Descriptor = function (element) {
|
||||
var Descriptor = function(element) {
|
||||
this.element = element;
|
||||
this.update = _.bind(this.update, this);
|
||||
};
|
||||
@@ -21,7 +21,7 @@
|
||||
* descriptor is updated. The callback will be passed the results
|
||||
* of calling the save method on this descriptor.
|
||||
*/
|
||||
Descriptor.prototype.onUpdate = function (callback) {
|
||||
Descriptor.prototype.onUpdate = function(callback) {
|
||||
if (!this.callbacks) {
|
||||
this.callbacks = [];
|
||||
}
|
||||
@@ -32,14 +32,14 @@
|
||||
/*
|
||||
* Notify registered callbacks that the state of this descriptor has changed
|
||||
*/
|
||||
Descriptor.prototype.update = function () {
|
||||
Descriptor.prototype.update = function() {
|
||||
var data, callbacks, i, length;
|
||||
|
||||
data = this.save();
|
||||
callbacks = this.callbacks;
|
||||
length = callbacks.length;
|
||||
|
||||
$.each(callbacks, function (index, callback) {
|
||||
$.each(callbacks, function(index, callback) {
|
||||
callback(data);
|
||||
});
|
||||
};
|
||||
@@ -51,14 +51,14 @@
|
||||
* @returns {object} An object containing children and data attributes (both optional).
|
||||
* The contents of the attributes will be saved to the server
|
||||
*/
|
||||
Descriptor.prototype.save = function () {
|
||||
Descriptor.prototype.save = function() {
|
||||
return {};
|
||||
};
|
||||
|
||||
return Descriptor;
|
||||
}());
|
||||
|
||||
this.XBlockToXModuleShim = function (runtime, element, initArgs) {
|
||||
this.XBlockToXModuleShim = function(runtime, element, initArgs) {
|
||||
/*
|
||||
* Load a single module (either an edit module or a display module)
|
||||
* from the supplied element, which should have a data-type attribute
|
||||
|
||||
@@ -216,4 +216,4 @@ class ContentTest(unittest.TestCase):
|
||||
js_file_paths = _write_js(output_root, _list_descriptors())
|
||||
js_file_paths = [file_path for file_path in js_file_paths if os.path.basename(file_path).startswith('000-')]
|
||||
self.assertEqual(len(js_file_paths), 1)
|
||||
self.assertIn("XModule.Descriptor = (function () {", open(js_file_paths[0]).read())
|
||||
self.assertIn("XModule.Descriptor = (function() {", open(js_file_paths[0]).read())
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
define([
|
||||
'edx-ui-toolkit/js/utils/string-utils',
|
||||
'edx-ui-toolkit/js/utils/html-utils',
|
||||
'domReady!',
|
||||
'jquery',
|
||||
'jquery-migrate',
|
||||
'backbone',
|
||||
'underscore',
|
||||
'gettext'
|
||||
],
|
||||
'edx-ui-toolkit/js/utils/string-utils',
|
||||
'edx-ui-toolkit/js/utils/html-utils',
|
||||
'domReady!',
|
||||
'jquery',
|
||||
'jquery-migrate',
|
||||
'backbone',
|
||||
'underscore',
|
||||
'gettext'
|
||||
],
|
||||
function(StringUtils, HtmlUtils) {
|
||||
'use strict';
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* Provides useful utilities for views.
|
||||
*/
|
||||
;(function (define, require) {
|
||||
(function(define, require) {
|
||||
'use strict';
|
||||
|
||||
define(["jquery", "underscore", "gettext", "common/js/components/views/feedback_notification",
|
||||
"common/js/components/views/feedback_prompt"],
|
||||
function ($, _, gettext, NotificationView, PromptView) {
|
||||
define(['jquery', 'underscore', 'gettext', 'common/js/components/views/feedback_notification',
|
||||
'common/js/components/views/feedback_prompt'],
|
||||
function($, _, gettext, NotificationView, PromptView) {
|
||||
var toggleExpandCollapse, showLoadingIndicator, hideLoadingIndicator, confirmThenRunOperation,
|
||||
runOperationShowingMessage, withDisabledElement, disableElementWhileRunning,
|
||||
getScrollOffset, setScrollOffset, setScrollTop, redirect, reload, hasChangedAttributes,
|
||||
@@ -102,7 +102,7 @@
|
||||
return function(event) {
|
||||
var view = this;
|
||||
disableElementWhileRunning($(event.currentTarget), function() {
|
||||
//call view.functionName(event), with view as the current this
|
||||
// call view.functionName(event), with view as the current this
|
||||
return view[functionName].apply(view, [event]);
|
||||
});
|
||||
};
|
||||
@@ -116,9 +116,9 @@
|
||||
* a JQuery promise.
|
||||
*/
|
||||
disableElementWhileRunning = function(element, operation) {
|
||||
element.addClass("is-disabled").attr('aria-disabled', true);
|
||||
element.addClass('is-disabled').attr('aria-disabled', true);
|
||||
return operation().always(function() {
|
||||
element.removeClass("is-disabled").attr('aria-disabled', false);
|
||||
element.removeClass('is-disabled').attr('aria-disabled', false);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
* @param callback function to call when deletion succeeds
|
||||
*/
|
||||
deleteNotificationHandler = function(callback) {
|
||||
return function (event) {
|
||||
return function(event) {
|
||||
event.preventDefault();
|
||||
$.ajax({
|
||||
url: $(this).data('dismiss-link'),
|
||||
@@ -193,7 +193,7 @@
|
||||
if (!changedAttributes) {
|
||||
return false;
|
||||
}
|
||||
for (i=0; i < attributes.length; i++) {
|
||||
for (i = 0; i < attributes.length; i++) {
|
||||
if (_.has(changedAttributes, attributes[i])) {
|
||||
return true;
|
||||
}
|
||||
@@ -204,7 +204,7 @@
|
||||
/**
|
||||
* Helper method for course/library creation - verifies a required field is not blank.
|
||||
*/
|
||||
validateRequiredField = function (msg) {
|
||||
validateRequiredField = function(msg) {
|
||||
return msg.length === 0 ? gettext('Required field.') : '';
|
||||
};
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
* Helper method for course/library creation.
|
||||
* Check that a course (org, number, run) doesn't use any special characters
|
||||
*/
|
||||
validateURLItemEncoding = function (item, allowUnicode) {
|
||||
validateURLItemEncoding = function(item, allowUnicode) {
|
||||
var required = validateRequiredField(item);
|
||||
if (required) {
|
||||
return required;
|
||||
@@ -231,10 +231,10 @@
|
||||
};
|
||||
|
||||
// Ensure that sum length of key field values <= ${MAX_SUM_KEY_LENGTH} chars.
|
||||
validateTotalKeyLength = function (key_field_selectors) {
|
||||
validateTotalKeyLength = function(key_field_selectors) {
|
||||
var totalLength = _.reduce(
|
||||
key_field_selectors,
|
||||
function (sum, ele) { return sum + $(ele).val().length;},
|
||||
function(sum, ele) { return sum + $(ele).val().length; },
|
||||
0
|
||||
);
|
||||
return totalLength <= MAX_SUM_KEY_LENGTH;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
;(function (define) {
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define(["jquery",
|
||||
"underscore",
|
||||
"underscore.string",
|
||||
"backbone",
|
||||
"text!common/templates/components/system-feedback.underscore"],
|
||||
define(['jquery',
|
||||
'underscore',
|
||||
'underscore.string',
|
||||
'backbone',
|
||||
'text!common/templates/components/system-feedback.underscore'],
|
||||
function($, _, str, Backbone, systemFeedbackTemplate) {
|
||||
var tabbable_elements = [
|
||||
"a[href]:not([tabindex='-1'])",
|
||||
@@ -19,8 +19,8 @@
|
||||
];
|
||||
var SystemFeedback = Backbone.View.extend({
|
||||
options: {
|
||||
title: "",
|
||||
message: "",
|
||||
title: '',
|
||||
message: '',
|
||||
intent: null, // "warning", "confirmation", "error", "announcement", "step-required", etc
|
||||
type: null, // "alert", "notification", or "prompt": set by subclass
|
||||
shown: true, // is this view currently being shown?
|
||||
@@ -62,14 +62,14 @@
|
||||
initialize: function(options) {
|
||||
this.options = _.extend({}, this.options, options);
|
||||
if (!this.options.type) {
|
||||
throw "SystemFeedback: type required (given " +
|
||||
JSON.stringify(this.options) + ")";
|
||||
throw 'SystemFeedback: type required (given ' +
|
||||
JSON.stringify(this.options) + ')';
|
||||
}
|
||||
if (!this.options.intent) {
|
||||
throw "SystemFeedback: intent required (given " +
|
||||
JSON.stringify(this.options) + ")";
|
||||
throw 'SystemFeedback: intent required (given ' +
|
||||
JSON.stringify(this.options) + ')';
|
||||
}
|
||||
this.setElement($("#page-" + this.options.type));
|
||||
this.setElement($('#page-' + this.options.type));
|
||||
// handle single "secondary" action
|
||||
if (this.options.actions && this.options.actions.secondary &&
|
||||
!_.isArray(this.options.actions.secondary)) {
|
||||
@@ -82,13 +82,13 @@
|
||||
this.options.outFocusElement = this.options.outFocusElement || document.activeElement;
|
||||
|
||||
// Set focus to the container.
|
||||
this.$(".wrapper").first().focus();
|
||||
this.$('.wrapper').first().focus();
|
||||
|
||||
|
||||
// Make tabs within the prompt loop rather than setting focus
|
||||
// back to the main content of the page.
|
||||
var tabbables = this.$(tabbable_elements.join());
|
||||
tabbables.on("keydown", function (event) {
|
||||
tabbables.on('keydown', function(event) {
|
||||
// On tab backward from the first tabbable item in the prompt
|
||||
if (event.which === 9 && event.shiftKey && event.target === tabbables.first()[0]) {
|
||||
event.preventDefault();
|
||||
@@ -105,7 +105,7 @@
|
||||
},
|
||||
|
||||
outFocus: function() {
|
||||
var tabbables = this.$(tabbable_elements.join()).off("keydown");
|
||||
var tabbables = this.$(tabbable_elements.join()).off('keydown');
|
||||
if (this.options.outFocusElement) {
|
||||
this.options.outFocusElement.focus();
|
||||
}
|
||||
@@ -141,22 +141,22 @@
|
||||
|
||||
// the rest of the API should be considered semi-private
|
||||
events: {
|
||||
"click .action-close": "hide",
|
||||
"click .action-primary": "primaryClick",
|
||||
"click .action-secondary": "secondaryClick"
|
||||
'click .action-close': 'hide',
|
||||
'click .action-primary': 'primaryClick',
|
||||
'click .action-secondary': 'secondaryClick'
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// there can be only one active view of a given type at a time: only
|
||||
// one alert, only one notification, only one prompt. Therefore, we'll
|
||||
// use a singleton approach.
|
||||
var singleton = SystemFeedback["active_" + this.options.type];
|
||||
var singleton = SystemFeedback['active_' + this.options.type];
|
||||
if (singleton && singleton !== this) {
|
||||
singleton.stopListening();
|
||||
singleton.undelegateEvents();
|
||||
}
|
||||
this.$el.html(_.template(systemFeedbackTemplate)(this.options));
|
||||
SystemFeedback["active_" + this.options.type] = this;
|
||||
SystemFeedback['active_' + this.options.type] = this;
|
||||
return this;
|
||||
},
|
||||
|
||||
@@ -183,7 +183,7 @@
|
||||
// which secondary action was clicked?
|
||||
i = 0; // default to the first secondary action (easier for testing)
|
||||
if (event && event.target) {
|
||||
i = _.indexOf(this.$(".action-secondary"), event.target);
|
||||
i = _.indexOf(this.$('.action-secondary'), event.target);
|
||||
}
|
||||
secondary = secondaryList[i];
|
||||
if (secondary.preventDefault !== false) {
|
||||
|
||||
@@ -1,42 +1,41 @@
|
||||
;(function (define) {
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define(["jquery", "underscore", "underscore.string", "common/js/components/views/feedback"],
|
||||
define(['jquery', 'underscore', 'underscore.string', 'common/js/components/views/feedback'],
|
||||
function($, _, str, SystemFeedbackView) {
|
||||
|
||||
var Alert = SystemFeedbackView.extend({
|
||||
options: $.extend({}, SystemFeedbackView.prototype.options, {
|
||||
type: "alert"
|
||||
}),
|
||||
slide_speed: 900,
|
||||
show: function() {
|
||||
SystemFeedbackView.prototype.show.apply(this, arguments);
|
||||
this.$el.hide();
|
||||
this.$el.slideDown(this.slide_speed);
|
||||
return this;
|
||||
},
|
||||
hide: function () {
|
||||
this.$el.slideUp({
|
||||
duration: this.slide_speed
|
||||
});
|
||||
setTimeout(_.bind(SystemFeedbackView.prototype.hide, this, arguments),
|
||||
var Alert = SystemFeedbackView.extend({
|
||||
options: $.extend({}, SystemFeedbackView.prototype.options, {
|
||||
type: 'alert'
|
||||
}),
|
||||
slide_speed: 900,
|
||||
show: function() {
|
||||
SystemFeedbackView.prototype.show.apply(this, arguments);
|
||||
this.$el.hide();
|
||||
this.$el.slideDown(this.slide_speed);
|
||||
return this;
|
||||
},
|
||||
hide: function() {
|
||||
this.$el.slideUp({
|
||||
duration: this.slide_speed
|
||||
});
|
||||
setTimeout(_.bind(SystemFeedbackView.prototype.hide, this, arguments),
|
||||
this.slideSpeed);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// create Alert.Warning, Alert.Confirmation, etc
|
||||
var capitalCamel, intents;
|
||||
capitalCamel = _.compose(str.capitalize, str.camelize);
|
||||
intents = ["warning", "error", "confirmation", "announcement", "step-required", "help", "mini"];
|
||||
_.each(intents, function(intent) {
|
||||
var subclass;
|
||||
subclass = Alert.extend({
|
||||
options: $.extend({}, Alert.prototype.options, {
|
||||
intent: intent
|
||||
})
|
||||
var capitalCamel, intents;
|
||||
capitalCamel = _.compose(str.capitalize, str.camelize);
|
||||
intents = ['warning', 'error', 'confirmation', 'announcement', 'step-required', 'help', 'mini'];
|
||||
_.each(intents, function(intent) {
|
||||
var subclass;
|
||||
subclass = Alert.extend({
|
||||
options: $.extend({}, Alert.prototype.options, {
|
||||
intent: intent
|
||||
})
|
||||
});
|
||||
Alert[capitalCamel(intent)] = subclass;
|
||||
});
|
||||
Alert[capitalCamel(intent)] = subclass;
|
||||
});
|
||||
|
||||
return Alert;
|
||||
});
|
||||
return Alert;
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -1,34 +1,33 @@
|
||||
;(function (define) {
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define(["jquery", "underscore", "underscore.string", "common/js/components/views/feedback"],
|
||||
define(['jquery', 'underscore', 'underscore.string', 'common/js/components/views/feedback'],
|
||||
function($, _, str, SystemFeedbackView) {
|
||||
|
||||
var Notification = SystemFeedbackView.extend({
|
||||
options: $.extend({}, SystemFeedbackView.prototype.options, {
|
||||
type: "notification",
|
||||
closeIcon: false
|
||||
})
|
||||
});
|
||||
|
||||
// create Notification.Warning, Notification.Confirmation, etc
|
||||
var capitalCamel, intents;
|
||||
capitalCamel = _.compose(str.capitalize, str.camelize);
|
||||
intents = ["warning", "error", "confirmation", "announcement", "step-required", "help", "mini"];
|
||||
_.each(intents, function(intent) {
|
||||
var subclass;
|
||||
subclass = Notification.extend({
|
||||
options: $.extend({}, Notification.prototype.options, {
|
||||
intent: intent
|
||||
var Notification = SystemFeedbackView.extend({
|
||||
options: $.extend({}, SystemFeedbackView.prototype.options, {
|
||||
type: 'notification',
|
||||
closeIcon: false
|
||||
})
|
||||
});
|
||||
Notification[capitalCamel(intent)] = subclass;
|
||||
});
|
||||
|
||||
// create Notification.Warning, Notification.Confirmation, etc
|
||||
var capitalCamel, intents;
|
||||
capitalCamel = _.compose(str.capitalize, str.camelize);
|
||||
intents = ['warning', 'error', 'confirmation', 'announcement', 'step-required', 'help', 'mini'];
|
||||
_.each(intents, function(intent) {
|
||||
var subclass;
|
||||
subclass = Notification.extend({
|
||||
options: $.extend({}, Notification.prototype.options, {
|
||||
intent: intent
|
||||
})
|
||||
});
|
||||
Notification[capitalCamel(intent)] = subclass;
|
||||
});
|
||||
|
||||
// set more sensible defaults for Notification.Mini views
|
||||
var miniOptions = Notification.Mini.prototype.options;
|
||||
miniOptions.minShown = 1250;
|
||||
miniOptions.closeIcon = false;
|
||||
var miniOptions = Notification.Mini.prototype.options;
|
||||
miniOptions.minShown = 1250;
|
||||
miniOptions.closeIcon = false;
|
||||
|
||||
return Notification;
|
||||
});
|
||||
return Notification;
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
;(function (define) {
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define(["jquery", "underscore", "underscore.string", "common/js/components/views/feedback"],
|
||||
define(['jquery', 'underscore', 'underscore.string', 'common/js/components/views/feedback'],
|
||||
function($, _, str, SystemFeedbackView) {
|
||||
|
||||
var Prompt = SystemFeedbackView.extend({
|
||||
options: $.extend({}, SystemFeedbackView.prototype.options, {
|
||||
type: "prompt",
|
||||
type: 'prompt',
|
||||
closeIcon: false,
|
||||
icon: false
|
||||
}),
|
||||
render: function() {
|
||||
if(!window.$body) { window.$body = $(document.body); }
|
||||
if(this.options.shown) {
|
||||
if (!window.$body) { window.$body = $(document.body); }
|
||||
if (this.options.shown) {
|
||||
$body.addClass('prompt-is-shown');
|
||||
} else {
|
||||
$body.removeClass('prompt-is-shown');
|
||||
@@ -33,7 +32,7 @@
|
||||
// create Prompt.Warning, Prompt.Confirmation, etc
|
||||
var capitalCamel, intents;
|
||||
capitalCamel = _.compose(str.capitalize, str.camelize);
|
||||
intents = ["warning", "error", "confirmation", "announcement", "step-required", "help", "mini"];
|
||||
intents = ['warning', 'error', 'confirmation', 'announcement', 'step-required', 'help', 'mini'];
|
||||
_.each(intents, function(intent) {
|
||||
var subclass;
|
||||
subclass = Prompt.extend({
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Generic view to render a collection.
|
||||
*/
|
||||
;(function (define) {
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define(['backbone', 'underscore'], function(Backbone, _) {
|
||||
var ListView = Backbone.View.extend({
|
||||
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
itemViewClass: Backbone.View,
|
||||
|
||||
initialize: function (options) {
|
||||
initialize: function(options) {
|
||||
this.itemViewClass = options.itemViewClass || this.itemViewClass;
|
||||
// TODO: at some point we will want 'add' and 'remove'
|
||||
// not to re-render the whole collection, but this is
|
||||
@@ -30,16 +30,16 @@
|
||||
* This should push each rendered item to this.itemViews
|
||||
* to ensure garbage collection works.
|
||||
*/
|
||||
this.collection.each(function (model) {
|
||||
this.collection.each(function(model) {
|
||||
var itemView = new this.itemViewClass({model: model});
|
||||
this.$el.append(itemView.render().el);
|
||||
this.itemViews.push(itemView);
|
||||
}, this);
|
||||
},
|
||||
|
||||
render: function () {
|
||||
render: function() {
|
||||
// Remove old children views
|
||||
_.each(this.itemViews, function (childView) {
|
||||
_.each(this.itemViews, function(childView) {
|
||||
childView.remove();
|
||||
});
|
||||
this.itemViews = [];
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* will be used to connect each card's title with the header text via
|
||||
* the ARIA describedby attribute.
|
||||
*/
|
||||
;(function(define) {
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define([
|
||||
'backbone',
|
||||
@@ -24,18 +24,18 @@
|
||||
'common/js/components/views/paging_footer',
|
||||
'common/js/components/views/list',
|
||||
'text!common/templates/components/paginated-view.underscore'
|
||||
], function (Backbone, _, HtmlUtils, PagingHeader, PagingFooter, ListView, paginatedViewTemplate) {
|
||||
], function(Backbone, _, HtmlUtils, PagingHeader, PagingFooter, ListView, paginatedViewTemplate) {
|
||||
var PaginatedView = Backbone.View.extend({
|
||||
initialize: function () {
|
||||
initialize: function() {
|
||||
var ItemListView = this.listViewClass.extend({
|
||||
tagName: 'div',
|
||||
className: this.type + '-container',
|
||||
className: this.type + '-container',
|
||||
itemViewClass: this.itemViewClass
|
||||
});
|
||||
this.listView = new ItemListView({collection: this.collection});
|
||||
this.headerView = this.createHeaderView();
|
||||
this.footerView = this.createFooterView();
|
||||
this.collection.on('page_changed', function () {
|
||||
this.collection.on('page_changed', function() {
|
||||
this.$('.sr-is-focusable.sr-' + this.type + '-view').focus();
|
||||
}, this);
|
||||
},
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
viewTemplate: paginatedViewTemplate,
|
||||
|
||||
paginationLabel: gettext("Pagination"),
|
||||
paginationLabel: gettext('Pagination'),
|
||||
|
||||
createHeaderView: function() {
|
||||
return new PagingHeader({collection: this.collection, srInfo: this.srInfo});
|
||||
@@ -58,7 +58,7 @@
|
||||
});
|
||||
},
|
||||
|
||||
render: function () {
|
||||
render: function() {
|
||||
HtmlUtils.setHtml(this.$el, HtmlUtils.template(this.viewTemplate)({type: this.type}));
|
||||
this.assign(this.listView, '.' + this.type + '-list');
|
||||
if (this.headerView) {
|
||||
@@ -70,13 +70,13 @@
|
||||
return this;
|
||||
},
|
||||
|
||||
renderError: function () {
|
||||
renderError: function() {
|
||||
this.$el.text(
|
||||
gettext('Your request could not be completed. Reload the page and try again. If the issue persists, click the Help tab to report the problem.') // eslint-disable-line max-len
|
||||
);
|
||||
},
|
||||
|
||||
assign: function (view, selector) {
|
||||
assign: function(view, selector) {
|
||||
view.setElement(this.$(selector)).render();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
;(function (define) {
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define([
|
||||
"underscore",
|
||||
"gettext",
|
||||
"backbone",
|
||||
"edx-ui-toolkit/js/utils/html-utils",
|
||||
"text!common/templates/components/paging-footer.underscore"
|
||||
],
|
||||
'underscore',
|
||||
'gettext',
|
||||
'backbone',
|
||||
'edx-ui-toolkit/js/utils/html-utils',
|
||||
'text!common/templates/components/paging-footer.underscore'
|
||||
],
|
||||
function(_, gettext, Backbone, HtmlUtils, pagingFooterTemplate) {
|
||||
|
||||
var PagingFooter = Backbone.View.extend({
|
||||
events : {
|
||||
"click .next-page-link": "nextPage",
|
||||
"click .previous-page-link": "previousPage",
|
||||
"change .page-number-input": "changePage"
|
||||
events: {
|
||||
'click .next-page-link': 'nextPage',
|
||||
'click .previous-page-link': 'previousPage',
|
||||
'change .page-number-input': 'changePage'
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
this.collection = options.collection;
|
||||
this.hideWhenOnePage = options.hideWhenOnePage || false;
|
||||
this.paginationLabel = options.paginationLabel || gettext("Pagination");
|
||||
this.paginationLabel = options.paginationLabel || gettext('Pagination');
|
||||
this.collection.bind('add', _.bind(this.render, this));
|
||||
this.collection.bind('remove', _.bind(this.render, this));
|
||||
this.collection.bind('reset', _.bind(this.render, this));
|
||||
@@ -44,15 +43,15 @@
|
||||
paginationLabel: this.paginationLabel
|
||||
})
|
||||
);
|
||||
this.$(".previous-page-link").toggleClass("is-disabled", onFirstPage).attr('aria-disabled', onFirstPage);
|
||||
this.$(".next-page-link").toggleClass("is-disabled", onLastPage).attr('aria-disabled', onLastPage);
|
||||
this.$('.previous-page-link').toggleClass('is-disabled', onFirstPage).attr('aria-disabled', onFirstPage);
|
||||
this.$('.next-page-link').toggleClass('is-disabled', onLastPage).attr('aria-disabled', onLastPage);
|
||||
return this;
|
||||
},
|
||||
|
||||
changePage: function() {
|
||||
var collection = this.collection,
|
||||
currentPage = collection.getPageNumber(),
|
||||
pageInput = this.$("#page-number-input"),
|
||||
pageInput = this.$('#page-number-input'),
|
||||
pageNumber = parseInt(pageInput.val(), 10),
|
||||
validInput = true;
|
||||
if (!pageNumber || pageNumber > collection.getTotalPages() || pageNumber < 1) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;(function (define) {
|
||||
(function(define) {
|
||||
'use strict';
|
||||
define([
|
||||
'backbone',
|
||||
@@ -7,9 +7,9 @@
|
||||
'edx-ui-toolkit/js/utils/html-utils',
|
||||
'edx-ui-toolkit/js/utils/string-utils',
|
||||
'text!common/templates/components/paging-header.underscore'
|
||||
], function (Backbone, _, gettext, HtmlUtils, StringUtils, headerTemplate) {
|
||||
], function(Backbone, _, gettext, HtmlUtils, StringUtils, headerTemplate) {
|
||||
var PagingHeader = Backbone.View.extend({
|
||||
initialize: function (options) {
|
||||
initialize: function(options) {
|
||||
this.srInfo = options.srInfo;
|
||||
this.showSortControls = options.showSortControls;
|
||||
this.collection.bind('add', _.bind(this.render, this));
|
||||
@@ -21,7 +21,7 @@
|
||||
'change #paging-header-select': 'sortCollection'
|
||||
},
|
||||
|
||||
render: function () {
|
||||
render: function() {
|
||||
var message,
|
||||
start = (this.collection.getPageNumber() - 1) * this.collection.getPageSize(),
|
||||
end = start + this.collection.size(),
|
||||
@@ -43,7 +43,7 @@
|
||||
context
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
HtmlUtils.setHtml(
|
||||
this.$el,
|
||||
HtmlUtils.template(headerTemplate)({
|
||||
@@ -62,7 +62,7 @@
|
||||
* results.
|
||||
* @returns {*} A promise for the collection being updated
|
||||
*/
|
||||
sortCollection: function () {
|
||||
sortCollection: function() {
|
||||
var selected = this.$('#paging-header-select option:selected');
|
||||
this.sortOrder = selected.attr('value');
|
||||
this.collection.setSortField(this.sortOrder);
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
* performs a search, the collection's search string will be updated and then the
|
||||
* collection will be refreshed to show the first page of results.
|
||||
*/
|
||||
;(function (define) {
|
||||
(function(define) {
|
||||
'use strict';
|
||||
|
||||
define([
|
||||
'backbone',
|
||||
'jquery',
|
||||
'underscore',
|
||||
'edx-ui-toolkit/js/utils/html-utils',
|
||||
'text!common/templates/components/search-field.underscore'
|
||||
],
|
||||
function (Backbone, $, _, HtmlUtils, searchFieldTemplate) {
|
||||
'backbone',
|
||||
'jquery',
|
||||
'underscore',
|
||||
'edx-ui-toolkit/js/utils/html-utils',
|
||||
'text!common/templates/components/search-field.underscore'
|
||||
],
|
||||
function(Backbone, $, _, HtmlUtils, searchFieldTemplate) {
|
||||
return Backbone.View.extend({
|
||||
|
||||
events: {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user