Commit db213bf3 by polesye

BLD-967: Fix regExp.

parent 926ce567
...@@ -5,6 +5,8 @@ These are notable changes in edx-platform. This is a rolling list of changes, ...@@ -5,6 +5,8 @@ These are notable changes in edx-platform. This is a rolling list of changes,
in roughly chronological order, most recent first. Add your entries at or near in roughly chronological order, most recent first. Add your entries at or near
the top. Include a label indicating the component affected. the top. Include a label indicating the component affected.
Blades: Fix Youtube regular expression in video player editor. BLD-967.
Blades: Fix displaying transcripts on touch devices. BLD-1033. Blades: Fix displaying transcripts on touch devices. BLD-1033.
Blades: Tolerance expressed in percentage now computes correctly. BLD-522. Blades: Tolerance expressed in percentage now computes correctly. BLD-522.
......
define( define(
[ [
"jquery", "underscore", 'jquery', 'underscore',
"js/views/video/transcripts/utils", 'js/views/video/transcripts/utils',
"underscore.string", "xmodule", "jasmine-jquery" 'underscore.string', 'xmodule', 'jasmine-jquery'
], ],
function ($, _, Utils, _str) { function ($, _, Utils, _str) {
describe('Transcripts.Utils', function () { 'use strict';
var videoId = 'OEoXaMPEzfM', describe('Transcripts.Utils', function () {
ytLinksList = (function (id) { var videoId = 'OEoXaMPEzfM',
var links = [ ytLinksList = (function (id) {
'http://www.youtube.com/watch?v=%s&feature=feedrec_grec_index', var links = [
'http://www.youtube.com/user/IngridMichaelsonVEVO#p/a/u/1/%s', 'http://www.youtube.com/watch?v=%s&feature=feedrec_grec_index',
'http://www.youtube.com/v/%s?fs=1&hl=en_US&rel=0', 'http://www.youtube.com/user/IngridMichaelsonVEVO#p/a/u/1/%s',
'http://www.youtube.com/watch?v=%s#t=0m10s', 'http://www.youtube.com/v/%s?fs=1&hl=en_US&rel=0',
'http://www.youtube.com/embed/%s?rel=0', 'http://www.youtube.com/watch?v=%s#t=0m10s',
'http://www.youtube.com/watch?v=%s', 'http://www.youtube.com/embed/%s?rel=0',
'http://youtu.be/%s' 'http://www.youtube.com/watch?v=%s',
]; 'http://youtu.be/%s'
];
return $.map(links, function (link) {
return _str.sprintf(link, id);
});
} (videoId)), return $.map(links, function (link) {
html5FileName = 'file_name', return _str.sprintf(link, id);
html5LinksList = (function (videoName) { });
var videoTypes = ['mp4', 'webm'],
links = [ } (videoId)),
'http://somelink.com/%s.%s?param=1&param=2#hash', html5FileName = 'file_name',
'http://somelink.com/%s.%s#hash', html5LinksList = (function (videoName) {
'http://somelink.com/%s.%s?param=1&param=2', var videoTypes = ['mp4', 'webm'],
'http://somelink.com/%s.%s', links = [
'ftp://somelink.com/%s.%s', 'http://somelink.com/%s.%s?param=1&param=2#hash',
'https://somelink.com/%s.%s', 'http://somelink.com/%s.%s#hash',
'somelink.com/%s.%s', 'http://somelink.com/%s.%s?param=1&param=2',
'%s.%s' 'http://somelink.com/%s.%s',
], 'ftp://somelink.com/%s.%s',
data = {}; 'https://somelink.com/%s.%s',
'http://cdn.somecdn.net/v/%s.%s',
$.each(videoTypes, function (index, type) { 'somelink.com/%s.%s',
data[type] = $.map(links, function (link) { '%s.%s'
return _str.sprintf(link, videoName, type); ],
}); data = {};
$.each(videoTypes, function (index, type) {
data[type] = $.map(links, function (link) {
return _str.sprintf(link, videoName, type);
}); });
});
return data; return data;
} (html5FileName)); } (html5FileName));
describe('Method: getField', function (){ describe('Method: getField', function (){
var collection, var collection,
testFieldName = 'test_field'; testFieldName = 'test_field';
beforeEach(function() { beforeEach(function() {
collection = jasmine.createSpyObj( collection = jasmine.createSpyObj(
'Collection', 'Collection',
[ [
'findWhere' 'findWhere'
] ]
); );
}); });
it('All works okay if all arguments are passed', function () { it('All works okay if all arguments are passed', function () {
Utils.getField(collection, testFieldName); Utils.getField(collection, testFieldName);
expect(collection.findWhere).toHaveBeenCalledWith({ expect(collection.findWhere).toHaveBeenCalledWith({
field_name: testFieldName field_name: testFieldName
});
}); });
});
var wrongArgumentLists = [ var wrongArgumentLists = [
{ {
argName: 'collection', argName: 'collection',
list: [undefined, testFieldName] list: [undefined, testFieldName]
}, },
{ {
argName: 'field name', argName: 'field name',
list: [collection, undefined] list: [collection, undefined]
}, },
{ {
argName: 'both', argName: 'both',
list: [undefined, undefined] list: [undefined, undefined]
} }
]; ];
$.each(wrongArgumentLists, function (index, element) {
it(element.argName + ' argument(s) is/are absent', function () {
var result = Utils.getField.apply(this, element.list);
expect(result).toBeUndefined();
});
});
});
$.each(wrongArgumentLists, function (index, element) { describe('Method: parseYoutubeLink', function () {
it(element.argName + ' argument(s) is/are absent', function () { describe('Supported urls', function () {
var result = Utils.getField.apply(this, element.list); $.each(ytLinksList, function (index, link) {
it(link, function () {
var result = Utils.parseYoutubeLink(link);
expect(result).toBeUndefined(); expect(result).toBe(videoId);
}); });
}); });
}); });
describe('Method: parseYoutubeLink', function () { describe('Wrong arguments ', function () {
describe('Supported urls', function () {
$.each(ytLinksList, function (index, link) {
it(link, function () {
var result = Utils.parseYoutubeLink(link);
expect(result).toBe(videoId); beforeEach(function(){
}); spyOn(console, 'log');
});
}); });
describe('Wrong arguments ', function () { it('no arguments', function () {
var result = Utils.parseYoutubeLink();
beforeEach(function(){ expect(result).toBeUndefined();
spyOn(console, 'log'); });
});
it('no arguments', function () { it('wrong data type', function () {
var result = Utils.parseYoutubeLink(); var result = Utils.parseYoutubeLink(1);
expect(result).toBeUndefined(); expect(result).toBeUndefined();
}); });
it('wrong data type', function () { it('videoId is wrong', function () {
var result = Utils.parseYoutubeLink(1); var videoId = 'wrong_id',
link = 'http://youtu.be/' + videoId,
result = Utils.parseYoutubeLink(link);
expect(result).toBeUndefined(); expect(result).toBeUndefined();
}); });
var wrongUrls = [
'http://youtu.bee/' + videoId,
'http://youtu.be/',
'example.com',
'http://google.com/somevideo.mp4'
];
it('videoId is wrong', function () { $.each(wrongUrls, function (index, link) {
var videoId = 'wrong_id', it(link, function () {
link = 'http://youtu.be/' + videoId, var result = Utils.parseYoutubeLink(link);
result = Utils.parseYoutubeLink(link);
expect(result).toBeUndefined(); expect(result).toBeUndefined();
}); });
});
});
});
var wrongUrls = [ describe('Method: parseHTML5Link', function () {
'http://youtu.bee/' + videoId, describe('Supported urls', function () {
'http://youtu.be/', $.each(html5LinksList, function (format, linksList) {
'example.com', $.each(linksList, function (index, link) {
'http://google.com/somevideo.mp4'
];
$.each(wrongUrls, function (index, link) {
it(link, function () { it(link, function () {
var result = Utils.parseYoutubeLink(link); var result = Utils.parseHTML5Link(link);
expect(result).toBeUndefined(); expect(result).toEqual({
video: html5FileName,
type: format
});
}); });
}); });
}); });
}); });
describe('Method: parseHTML5Link', function () { describe('Wrong arguments ', function () {
describe('Supported urls', function () {
$.each(html5LinksList, function (format, linksList) {
$.each(linksList, function (index, link) {
it(link, function () {
var result = Utils.parseHTML5Link(link);
expect(result).toEqual({
video: html5FileName,
type: format
});
});
});
});
});
describe('Wrong arguments ', function () { beforeEach(function(){
spyOn(console, 'log');
});
beforeEach(function(){ it('no arguments', function () {
spyOn(console, 'log'); var result = Utils.parseHTML5Link();
});
it('no arguments', function () { expect(result).toBeUndefined();
var result = Utils.parseHTML5Link(); });
expect(result).toBeUndefined(); it('wrong data type', function () {
}); var result = Utils.parseHTML5Link(1);
it('wrong data type', function () { expect(result).toBeUndefined();
var result = Utils.parseHTML5Link(1); });
expect(result).toBeUndefined(); var html5WrongUrls = [
}); 'http://youtu.bee/' + videoId,
'http://youtu.be/',
'example.com',
'http://google.com/somevideo.mp1',
'http://google.com/somevideomp4',
'http://google.com/somevideo_mp4',
'http://google.com/somevideo:mp4',
'http://google.com/somevideo',
'http://google.com/somevideo.webm_'
];
var html5WrongUrls = [ $.each(html5WrongUrls, function (index, link) {
'http://youtu.bee/' + videoId, it(link, function () {
'http://youtu.be/', var result = Utils.parseHTML5Link(link);
'example.com',
'http://google.com/somevideo.mp1',
'http://google.com/somevideomp4',
'http://google.com/somevideo_mp4',
'http://google.com/somevideo:mp4',
'http://google.com/somevideo',
'http://google.com/somevideo.webm_'
];
$.each(html5WrongUrls, function (index, link) {
it(link, function () {
var result = Utils.parseHTML5Link(link);
expect(result).toBeUndefined(); expect(result).toBeUndefined();
});
}); });
}); });
}); });
});
it('Method: getYoutubeLink', function () { it('Method: getYoutubeLink', function () {
var videoId = 'video_id', var videoId = 'video_id',
result = Utils.getYoutubeLink(videoId), result = Utils.getYoutubeLink(videoId),
expectedResult = 'http://youtu.be/' + videoId; expectedResult = 'http://youtu.be/' + videoId;
expect(result).toBe(expectedResult); expect(result).toBe(expectedResult);
}); });
describe('Method: parseLink', function () { describe('Method: parseLink', function () {
var resultDataDict = { var resultDataDict = {
'html5': { 'html5': {
link: html5LinksList['mp4'][0], link: html5LinksList.mp4[0],
resp: { resp: {
mode: 'html5', mode: 'html5',
video: html5FileName, video: html5FileName,
type: 'mp4' type: 'mp4'
} }
}, },
'youtube': { 'youtube': {
link: ytLinksList[0], link: ytLinksList[0],
resp: { resp: {
mode: 'youtube', mode: 'youtube',
video: videoId, video: videoId,
type: 'youtube' type: 'youtube'
} }
}, },
'incorrect': { 'incorrect': {
link: 'http://example.com', link: 'http://example.com',
resp: { resp: {
mode: 'incorrect' mode: 'incorrect'
}
} }
}; }
};
$.each(resultDataDict, function (mode, data) { $.each(resultDataDict, function (mode, data) {
it(mode, function () { it(mode, function () {
var result = Utils.parseLink(data.link); var result = Utils.parseLink(data.link);
expect(result).toEqual(data.resp); expect(result).toEqual(data.resp);
});
}); });
});
describe('Wrong arguments ', function () { describe('Wrong arguments ', function () {
it('no arguments', function () { it('no arguments', function () {
var result = Utils.parseLink(); var result = Utils.parseLink();
expect(result).toBeUndefined(); expect(result).toBeUndefined();
}); });
it('wrong data type', function () { it('wrong data type', function () {
var result = Utils.parseLink(1); var result = Utils.parseLink(1);
expect(result).toBeUndefined(); expect(result).toBeUndefined();
});
}); });
}); });
}); });
}); });
});
define(["jquery", "underscore", "jquery.ajaxQueue"], function($, _) { define(['jquery', 'underscore', 'jquery.ajaxQueue'], function($) {
var Utils = (function () { 'use strict';
var Storage = {}; return (function () {
var Storage = {};
/**
* @function /**
* * Adds some data to the Storage object. If data with existent `data_id`
* Adds some data to the Storage object. If data with existent `data_id` * is added, nothing happens.
* is added, nothing happens. * @function
* * @param {String} data_id Unique identifier for the data.
* @param {string} data_id Unique identifier for the data. * @param {Any} data Data that should be stored.
* @param {any} data Data that should be stored. * @return {Object} Object itself for chaining.
* */
* @returns {object} Object itself for chaining. Storage.set = function (data_id, data) {
*/ Storage[data_id] = data;
Storage.set = function (data_id, data) {
Storage[data_id] = data; return this;
};
return this;
}; /**
* Return data from the Storage object by identifier.
/** * @function
* @function * @param {String} data_id Unique identifier of the data.
* * @return {Any} Stored data.
* Return data from the Storage object by identifier. */
* Storage.get= function (data_id) {
* @param {string} data_id Unique identifier of the data.
* return Storage[data_id];
* @returns {any} Stored data. };
*/
Storage.get= function (data_id) {
/**
return Storage[data_id]; * Deletes data from the Storage object by identifier.
}; * @function
* @param {String} data_id Unique identifier of the data.
* @return {Boolean} Boolean value that indicate if data is removed.
/** */
* @function Storage.remove = function (data_id) {
*
* Deletes data from the Storage object by identifier. return (delete Storage[data_id]);
* };
* @param {string} data_id Unique identifier of the data.
* /**
* @returns {boolean} Boolean value that indicate if data is removed. * Returns model from collection by 'field_name' property.
*/ * @function
Storage.remove = function (data_id) { * @param {Object} collection The model (CMS.Models.Metadata) information
* about metadata setting editors.
return (delete Storage[data_id]); * @param {String} field_name Name of field that should be found.
}; * @return {
* Object: When model exist.
* Undefined: When model doesn't exist.
* }
*/
var _getField = function (collection, field_name) {
var model;
if (collection && field_name) {
model = collection.findWhere({
field_name: field_name
});
}
return model;
};
/**
* Parses Youtube link and return video id.
* @function
* These are the types of URLs supported:
* http://www.youtube.com/watch?v=OEoXaMPEzfM&feature=feedrec_grec_index
* http://www.youtube.com/user/IngridMichaelsonVEVO#p/a/u/1/OEoXaMPEzfM
* http://www.youtube.com/v/OEoXaMPEzfM?fs=1&hl=en_US&rel=0
* http://www.youtube.com/watch?v=OEoXaMPEzfM#t=0m10s
* http://www.youtube.com/embed/OEoXaMPEzfM?rel=0
* http://www.youtube.com/watch?v=OEoXaMPEzfM
* http://youtu.be/OEoXaMPEzfM
* @param {String} url Url that should be parsed.
* @return {
* String: Video Id.
* Undefined: When url has incorrect format or argument is
* non-string, video id's length is not equal 11.
* }
*/
var _youtubeParser = (function () {
var cache = {},
regExp = /(?:http|https|)(?:\:\/\/|)(?:www.|)(?:youtu\.be\/|youtube\.com(?:\/embed\/|\/v\/|\/watch\?v=|\/ytscreeningroom\?v=|\/feeds\/api\/videos\/|\/user\S*[^\w\-\s]|\S*[^\w\-\s]))([\w\-]{11})[a-z0-9;:@#?&%=+\/\$_.-]*/i;
return function (url) {
if (typeof url !== 'string') {
/** return void(0);
* @function
*
* Returns model from collection by 'field_name' property.
*
* @param {object} collection The model (CMS.Models.Metadata) containing
* information about metadata setting editors.
* @param {string} field_name Name of field that should be found.
*
* @returns {
* object: when model exist,
* undefined: when model doesn't exist.
* }
*/
var _getField = function (collection, field_name) {
var model;
if (collection && field_name) {
model = collection.findWhere({
field_name: field_name
});
} }
return model; if (cache[url]) {
};
/**
* @function
*
* Parses Youtube link and return video id.
*
* These are the types of URLs supported:
* http://www.youtube.com/watch?v=OEoXaMPEzfM&feature=feedrec_grec_index
* http://www.youtube.com/user/IngridMichaelsonVEVO#p/a/u/1/OEoXaMPEzfM
* http://www.youtube.com/v/OEoXaMPEzfM?fs=1&hl=en_US&rel=0
* http://www.youtube.com/watch?v=OEoXaMPEzfM#t=0m10s
* http://www.youtube.com/embed/OEoXaMPEzfM?rel=0
* http://www.youtube.com/watch?v=OEoXaMPEzfM
* http://youtu.be/OEoXaMPEzfM
*
* @param {string} url Url that should be parsed.
*
* @returns {
* string: Video Id,
* undefined: when url has incorrect format or argument is
* non-string, video id's length is not equal 11.
* }
*/
var _youtubeParser = (function () {
var cache = {};
return function (url) {
if (typeof url !== 'string') {
return void(0);
}
if (cache[url]) {
return cache[url];
}
var regExp = /.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#\&\?]*).*/;
var match = url.match(regExp);
cache[url] = (match && match[1].length === 11) ? match[1] : void(0);
return cache[url]; return cache[url];
}; }
}());
/**
* @function
*
* Parses links with html5 video sources in mp4 or webm formats.
*
* @param {string} url Url that should be parsed.
*
* @returns {
* object: Object with information about the video
* (file name, video type),
* undefined: when url has incorrect format or argument is
* non-string.
* }
*/
var _videoLinkParser = (function () {
var cache = {};
return function (url) {
if (typeof url !== 'string') {
return void(0);
}
if (cache[url]) {
return cache[url];
}
var link = document.createElement('a'), var match = url.match(regExp);
match; cache[url] = (match && match[1].length === 11) ?
match[1] :
void(0);
link.href = url; return cache[url];
match = link.pathname };
.split('/') }());
.pop()
.match(/(.+)\.(mp4|webm)$/);
if (match) {
cache[url] = {
video: match[1],
type: match[2]
};
}
return cache[url];
};
}());
/**
* @function
*
* Facade function that parses html5 and youtube links.
*
* @param {string} url Url that should be parsed.
*
* @returns {
* object: Object with information about the video:
* {
* mode: "youtube|html5|incorrect",
* video: "file_name|youtube_id",
* type: "youtube|mp4|webm"
* },
* undefined: when argument is non-string.
* }
*/
var _linkParser = function (url) {
var result;
/**
* Parses links with html5 video sources in mp4 or webm formats.
* @function
* @param {String} url Url that should be parsed.
* @return {
* object: Object with information about the video
* (file name, video type),
* undefined: when url has incorrect format or argument is
* non-string.
* }
*/
var _videoLinkParser = (function () {
var cache = {};
return function (url) {
if (typeof url !== 'string') { if (typeof url !== 'string') {
return void(0); return void(0);
} }
if (_youtubeParser(url)) { if (cache[url]) {
result = { return cache[url];
mode: 'youtube',
video: _youtubeParser(url),
type: 'youtube'
};
} else if (_videoLinkParser(url)) {
result = $.extend({mode: 'html5'}, _videoLinkParser(url));
} else {
result = {
mode: 'incorrect'
};
} }
return result; var link = document.createElement('a'),
}; match;
/** link.href = url;
* @function match = link.pathname
* .split('/')
* Returns short-hand youtube url. .pop()
* .match(/(.+)\.(mp?4v?|webm)$/);
* @param {string} video_id Youtube Video Id that will be added to the link.
*
* @returns {string} Short-hand Youtube url.
*
* @example
* _getYoutubeLink('OEoXaMPEzfM'); => 'http://youtu.be/OEoXaMPEzfM'
*/
var _getYoutubeLink = function (video_id) {
return 'http://youtu.be/' + video_id;
};
if (match) {
cache[url] = {
video: match[1],
type: match[2]
};
} /*else {
cache[url] = {
video: link.pathname
.split('/')
.pop(),
type: 'other'
};
}*/
return cache[url];
};
}());
/** /**
* @function * Facade function that parses html5 and youtube links.
* * @function
* Returns list of objects with information about the passed links. * @param {String} url Url that should be parsed.
* * @return {
* @param {array} links List of links that will be processed. * object: Object with information about the video:
* * {
* @returns {array} List of objects. * mode: "youtube|html5|incorrect",
* * video: "file_name|youtube_id",
* @examples * type: "youtube|mp4|webm"
* var links = [ * },
* 'http://youtu.be/OEoXaMPEzfM', * undefined: when argument is non-string.
* 'video_name.mp4', * }
* 'video_name.webm' */
* ] var _linkParser = function (url) {
* var result;
* _getVideoList(links); // =>
* [ if (typeof url !== 'string') {
* {mode: `youtube`, type: `youtube`, ...},
* {mode: `html5`, type: `mp4`, ...}, return void(0);
* {mode: `html5`, type: `webm`, ...} }
* ]
* if (_youtubeParser(url)) {
*/ result = {
var _getVideoList = function (links) { mode: 'youtube',
if ($.isArray(links)) { video: _youtubeParser(url),
var arr = [], type: 'youtube'
data; };
} else if (_videoLinkParser(url)) {
for (var i = 0, len = links.length; i < len; i += 1) { result = $.extend({mode: 'html5'}, _videoLinkParser(url));
data = _linkParser(links[i]); } else {
result = {
if (data.mode !== 'incorrect') { mode: 'incorrect'
arr.push(data); };
} }
return result;
};
/**
* Returns short-hand youtube url.
* @function
* @param {string} video_id Youtube Video Id that will be added to the
* link.
* @return {string} Short-hand Youtube url.
* @examples
* _getYoutubeLink('OEoXaMPEzfM'); => 'http://youtu.be/OEoXaMPEzfM'
*/
var _getYoutubeLink = function (video_id) {
return 'http://youtu.be/' + video_id;
};
/**
* Returns list of objects with information about the passed links.
* @function
* @param {array} links List of links that will be processed.
* @returns {array} List of objects.
* @examples
* var links = [
* 'http://youtu.be/OEoXaMPEzfM',
* 'video_name.mp4',
* 'video_name.webm'
* ]
*
* _getVideoList(links); // =>
* [
* {mode: `youtube`, type: `youtube`, ...},
* {mode: `html5`, type: `mp4`, ...},
* {mode: `html5`, type: `webm`, ...}
* ]
*/
var _getVideoList = function (links) {
if ($.isArray(links)) {
var arr = [],
data;
for (var i = 0, len = links.length; i < len; i += 1) {
data = _linkParser(links[i]);
if (data.mode !== 'incorrect') {
arr.push(data);
} }
return arr;
} }
};
return arr;
}
};
/**
* Synchronizes 2 Backbone collections by 'field_name' property.
* @function
* @param {Object} fromCollection Collection with which synchronization will
* happens.
* @param {Object} toCollection Collection which will synchronized.
*/
var _syncCollections = function (fromCollection, toCollection) {
fromCollection.each(function (m) {
var model = toCollection.findWhere({
field_name: m.getFieldName()
});
/** if (model) {
* @function model.setValue(m.getDisplayValue());
* }
* Synchronizes 2 Backbone collections by 'field_name' property. });
* };
* @param {object} fromCollection Collection with which synchronization
* will happens. /**
* @param {object} toCollection Collection which will synchronized. * Sends Ajax requests in appropriate format.
* * @function
*/ * @param {String} action Action that will be invoked on server.
var _syncCollections = function (fromCollection, toCollection) { * @param {String} component_locator the locator of component.
fromCollection.each(function (m) { * @param {Array} videoList List of object with information about inserted
var model = toCollection.findWhere({ * urls.
field_name: m.getFieldName() * @param {Object} extraParams Extra parameters that can be send to the
}); * server.
* @return {Object} XMLHttpRequest object. Using this object, we can
if (model) { * attach callbacks to AJAX request events (for example on 'done',
model.setValue(m.getDisplayValue()); * 'fail', etc.).
} */
}); var _command = (function () {
}; // We will store the XMLHttpRequest object that $.ajax() function
// returns, to abort an ongoing AJAX request (if necessary) upon
/** // subsequent invocations of _command() function.
* @function //
* // A new AJAX request will be made on each invocation of the
* Sends Ajax requests in appropriate format. // _command() function.
* var xhr = null;
* @param {string} action Action that will be invoked on server. Is a part
* of url. return function (action, locator, videoList, extraParams) {
* @param {string} component_locator the locator of component. var params, data;
* @param {array} videoList List of object with information about inserted
* urls. if (extraParams) {
* @param {object} extraParams Extra parameters that can be send to the if ($.isPlainObject(extraParams)) {
* server params = extraParams;
* } else {
* @returns {object} XMLHttpRequest object. Using this object, we can attach params = {params: extraParams};
* callbacks to AJAX request events (for example on 'done', 'fail',
* etc.).
*/
var _command = (function () {
// We will store the XMLHttpRequest object that $.ajax() function
// returns, to abort an ongoing AJAX request (if necessary) upon
// subsequent invocations of _command() function.
//
// A new AJAX request will be made on each invocation of the
// _command() function.
var xhr = null;
return function (action, component_locator, videoList, extraParams) {
var params, data;
if (extraParams) {
if ($.isPlainObject(extraParams)) {
params = extraParams;
} else {
params = {params: extraParams};
}
} }
}
data = $.extend( data = $.extend(
{ locator: component_locator }, { locator: locator },
{ videos: videoList }, { videos: videoList },
params params
); );
xhr = $.ajaxQueue({ xhr = $.ajaxQueue({
url: '/transcripts/' + action, url: '/transcripts/' + action,
data: { data: JSON.stringify(data) }, data: { data: JSON.stringify(data) },
notifyOnError: false, notifyOnError: false,
type: 'get' type: 'get'
}); });
return xhr; return xhr;
};
}());
return {
getField: _getField,
parseYoutubeLink: _youtubeParser,
parseHTML5Link: _videoLinkParser,
parseLink: _linkParser,
getYoutubeLink: _getYoutubeLink,
syncCollections: _syncCollections,
command: _command,
getVideoList: _getVideoList,
Storage: {
set: Storage.set,
get: Storage.get,
remove: Storage.remove
}
}; };
}()); }());
return Utils; return {
getField: _getField,
parseYoutubeLink: _youtubeParser,
parseHTML5Link: _videoLinkParser,
parseLink: _linkParser,
getYoutubeLink: _getYoutubeLink,
syncCollections: _syncCollections,
command: _command,
getVideoList: _getVideoList,
Storage: {
set: Storage.set,
get: Storage.get,
remove: Storage.remove
}
};
}());
}); });
...@@ -37,6 +37,7 @@ from .video_handlers import VideoStudentViewHandlers, VideoStudioViewHandlers ...@@ -37,6 +37,7 @@ from .video_handlers import VideoStudentViewHandlers, VideoStudioViewHandlers
from urlparse import urlparse from urlparse import urlparse
def get_ext(filename): def get_ext(filename):
# Prevent incorrectly parsing urls like 'http://abc.com/path/video.mp4?xxxx'. # Prevent incorrectly parsing urls like 'http://abc.com/path/video.mp4?xxxx'.
path = urlparse(filename).path path = urlparse(filename).path
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment