Commit 09d86c22 by Adam

Merge pull request #4832 from edx/hotfix/2014-08-14

Hotfix/2014 08 14
parents 9b53c809 b5aaf8b0
......@@ -248,10 +248,19 @@ def create_unit_from_course_outline():
world.wait_for_mathjax()
world.wait_for_xmodule()
world.wait_for_loading()
assert world.is_css_present('ul.new-component-type')
@world.absorb
def wait_for_loading():
"""
Waits for the loading indicator to be hidden.
"""
world.wait_for(lambda _driver: len(world.browser.find_by_css('div.ui-loading.is-hidden')) > 0)
@step('I have clicked the new unit button$')
@step(u'I am in Studio editing a new unit$')
def edit_new_unit(step):
......
......@@ -6,7 +6,6 @@ from nose.tools import assert_equal, assert_in # pylint: disable=E0611
from terrain.steps import reload_the_page
from common import type_in_codemirror
from selenium.webdriver.common.keys import Keys
from cms.envs.common import FEATURES
@world.absorb
......@@ -123,6 +122,9 @@ def ensure_settings_visible():
@world.absorb
def edit_component(index=0):
# Verify that the "loading" indication has been hidden.
world.wait_for_loading()
# Verify that the "edit" button is present.
world.wait_for(lambda _driver: world.css_visible('a.edit-button'))
world.css_click('a.edit-button', index)
world.wait_for_ajax_complete()
......
......@@ -371,6 +371,23 @@ PIPELINE_CSS = {
],
'output_filename': 'css/cms-style-xmodule.css',
},
'style-xmodule-annotations': {
'source_filenames': [
'css/vendor/ova/annotator.css',
'css/vendor/ova/edx-annotator.css',
'css/vendor/ova/video-js.min.css',
'css/vendor/ova/rangeslider.css',
'css/vendor/ova/share-annotator.css',
'css/vendor/ova/richText-annotator.css',
'css/vendor/ova/tags-annotator.css',
'css/vendor/ova/flagging-annotator.css',
'css/vendor/ova/diacritic-annotator.css',
'css/vendor/ova/grouping-annotator.css',
'css/vendor/ova/ova.css',
'js/vendor/ova/catch/css/main.css'
],
'output_filename': 'css/cms-style-xmodule-annotations.css',
},
}
# test_order: Determines the position of this chunk of javascript on
......@@ -549,7 +566,10 @@ INSTALLED_APPS = (
'monitoring',
# Course action state
'course_action_state'
'course_action_state',
# Additional problem types
'edx_jsme', # Molecular Structure
)
......
......@@ -82,6 +82,27 @@
"URI": "js/vendor/URI.min",
"ieshim": "js/src/ie_shim",
"tooltip_manager": "js/src/tooltip_manager",
// Files needed for Annotations feature
"annotator": "js/vendor/ova/annotator-full",
"annotator-harvardx": "js/vendor/ova/annotator-full-firebase-auth",
"video.dev": "js/vendor/ova/video.dev",
"vjs.youtube": 'js/vendor/ova/vjs.youtube',
"rangeslider": 'js/vendor/ova/rangeslider',
"share-annotator": 'js/vendor/ova/share-annotator',
"richText-annotator": 'js/vendor/ova/richText-annotator',
"reply-annotator": 'js/vendor/ova/reply-annotator',
"grouping-annotator": 'js/vendor/ova/grouping-annotator',
"tags-annotator": 'js/vendor/ova/tags-annotator',
"diacritic-annotator": 'js/vendor/ova/diacritic-annotator',
"flagging-annotator": 'js/vendor/ova/flagging-annotator',
"jquery-Watch": 'js/vendor/ova/jquery-Watch',
"openseadragon": 'js/vendor/ova/openseadragon',
"osda": 'js/vendor/ova/OpenSeaDragonAnnotation',
"ova": 'js/vendor/ova/ova',
"catch": 'js/vendor/ova/catch/js/catch',
"handlebars": 'js/vendor/ova/catch/js/handlebars-1.1.2',
// end of Annotation tool files
// externally hosted files
"tender": [
......@@ -217,6 +238,9 @@
"tooltip_manager": {
deps: ["jquery", "underscore"]
},
"jquery.immediateDescendents": {
deps: ["jquery"]
},
"xblock/core": {
exports: "XBlock",
deps: ["jquery", "jquery.immediateDescendents"]
......@@ -232,7 +256,54 @@
"coffee/src/logger": {
exports: "Logger",
deps: ["coffee/src/ajax_prefix"]
}
},
// the following are all needed for annotation tools
"video.dev": {
exports:"videojs"
},
"vjs.youtube": {
deps: ["video.dev"]
},
"rangeslider": {
deps: ["video.dev"]
},
"annotator": {
exports: "Annotator"
},
"annotator-harvardx":{
deps: ["annotator"]
},
"share-annotator": {
deps: ["annotator"]
},
"richText-annotator": {
deps: ["annotator", "tinymce"]
},
"reply-annotator": {
deps: ["annotator"]
},
"tags-annotator": {
deps: ["annotator"]
},
"diacritic-annotator": {
deps: ["annotator"]
},
"flagging-annotator": {
deps: ["annotator"]
},
"grouping-annotator": {
deps: ["annotator"]
},
"ova":{
exports: "ova",
deps: ["annotator", "annotator-harvardx", "video.dev", "vjs.youtube", "rangeslider", "share-annotator", "richText-annotator", "reply-annotator", "tags-annotator", "flagging-annotator", "grouping-annotator", "diacritic-annotator", "jquery-Watch", "catch", "handlebars", "URI"]
},
"osda":{
exports: "osda",
deps: ["annotator", "annotator-harvardx", "video.dev", "vjs.youtube", "rangeslider", "share-annotator", "richText-annotator", "reply-annotator", "tags-annotator", "flagging-annotator", "grouping-annotator", "diacritic-annotator", "openseadragon", "jquery-Watch", "catch", "handlebars", "URI"]
},
// end of annotation tool files
},
// load jquery and gettext automatically
deps: ["jquery", "gettext"],
......
......@@ -92,7 +92,7 @@ def render_to_string(template_name, dictionary, context=None, namespace='main'):
context_instance['marketing_link'] = marketing_link
# In various testing contexts, there might not be a current request context.
if edxmako.middleware.REQUEST_CONTEXT.context is not None:
if getattr(edxmako.middleware.REQUEST_CONTEXT, "context", None):
for d in edxmako.middleware.REQUEST_CONTEXT.context:
context_dictionary.update(d)
for d in context_instance:
......
......@@ -48,7 +48,7 @@ class Template(MakoTemplate):
context_dictionary = {}
# In various testing contexts, there might not be a current request context.
if edxmako.middleware.REQUEST_CONTEXT.context is not None:
if getattr(edxmako.middleware.REQUEST_CONTEXT, "context", None):
for d in edxmako.middleware.REQUEST_CONTEXT.context:
context_dictionary.update(d)
for d in context_instance:
......
from mock import patch, Mock
import unittest
from django.conf import settings
from django.http import HttpResponse
from django.test import TestCase
from django.test.utils import override_settings
......@@ -7,7 +10,7 @@ from django.test.client import RequestFactory
from django.core.urlresolvers import reverse
import edxmako.middleware
from edxmako import add_lookup, LOOKUP
from edxmako.shortcuts import marketing_link
from edxmako.shortcuts import marketing_link, render_to_string
from student.tests.factories import UserFactory
from util.testing import UrlResetMixin
......@@ -71,6 +74,26 @@ class MakoMiddlewareTest(TestCase):
# requestcontext should be None.
self.assertIsNone(edxmako.middleware.REQUEST_CONTEXT.context)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
@patch("edxmako.middleware.REQUEST_CONTEXT")
def test_render_to_string_when_no_global_context_lms(self, context_mock):
"""
Test render_to_string() when makomiddleware has not initialized
the threadlocal REQUEST_CONTEXT.context. This is meant to run in LMS.
"""
del context_mock.context
self.assertIn("this module is temporarily unavailable", render_to_string("courseware/error-message.html", None))
@unittest.skipUnless(settings.ROOT_URLCONF == 'cms.urls', 'Test only valid in cms')
@patch("edxmako.middleware.REQUEST_CONTEXT")
def test_render_to_string_when_no_global_context_cms(self, context_mock):
"""
Test render_to_string() when makomiddleware has not initialized
the threadlocal REQUEST_CONTEXT.context. This is meant to run in CMS.
"""
del context_mock.context
self.assertIn("We're having trouble rendering your component", render_to_string("html_error.html", None))
def mako_middleware_process_request(request):
"""
......
......@@ -130,8 +130,8 @@ class ImageAnnotationModule(AnnotatableFields, XModule):
'annotation_mode': self.annotation_mode,
}
fragment = Fragment(self.system.render_template('imageannotation.html', context))
fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js")
fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js")
fragment.add_javascript_url(self.runtime.STATIC_URL + "js/vendor/tinymce/js/tinymce/tinymce.full.min.js")
fragment.add_javascript_url(self.runtime.STATIC_URL + "js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js")
return fragment
......
......@@ -106,7 +106,7 @@ class MongoModulestoreBuilder(object):
db.connection.close()
# Delete the created directory on the filesystem
rmtree(fs_root)
rmtree(fs_root, ignore_errors=True)
def __repr__(self):
return 'MongoModulestoreBuilder()'
......@@ -152,7 +152,7 @@ class VersioningModulestoreBuilder(object):
db.connection.close()
# Delete the created directory on the filesystem
rmtree(fs_root)
rmtree(fs_root, ignore_errors=True)
def __repr__(self):
return 'SplitModulestoreBuilder()'
......@@ -248,7 +248,7 @@ class CrossStoreXMLRoundtrip(CourseComparisonTest):
def setUp(self):
super(CrossStoreXMLRoundtrip, self).setUp()
self.export_dir = mkdtemp()
self.addCleanup(rmtree, self.export_dir)
self.addCleanup(rmtree, self.export_dir, ignore_errors=True)
@ddt.data(*itertools.product(
MODULESTORE_SETUPS,
......
......@@ -127,8 +127,8 @@ class TextAnnotationModule(AnnotatableFields, XModule):
'annotation_mode': self.annotation_mode,
}
fragment = Fragment(self.system.render_template('textannotation.html', context))
fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js")
fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js")
fragment.add_javascript_url(self.runtime.STATIC_URL + "js/vendor/tinymce/js/tinymce/tinymce.full.min.js")
fragment.add_javascript_url(self.runtime.STATIC_URL + "js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js")
return fragment
......
......@@ -133,8 +133,8 @@ class VideoAnnotationModule(AnnotatableFields, XModule):
'annotation_mode': self.annotation_mode,
}
fragment = Fragment(self.system.render_template('videoannotation.html', context))
fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js")
fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js")
fragment.add_javascript_url(self.runtime.STATIC_URL + "js/vendor/tinymce/js/tinymce/tinymce.full.min.js")
fragment.add_javascript_url(self.runtime.STATIC_URL + "js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js")
return fragment
......
......@@ -352,7 +352,7 @@ CatchAnnotation.prototype = {
// if the default tab is instructor, we must refresh the catch to pull the ones
// under the instructor's email. Calling changeUserId will update this.options.userId
// and most importantly refresh not only the highlights (from Annotator)
// but also the table below from the annotations database server (called Catch).
// but also the table below from the annotations database server (called Catch).
if(this.options.default_tab.toLowerCase() === 'instructor') {
this.changeUserId(this.options.instructor_email);
}
......@@ -717,7 +717,7 @@ CatchAnnotation.prototype = {
var isInList = false;
var list = $('#mainCatch .annotationList .annotationRow.item');
for (_i = 0, _len = list.length; _i < _len; _i++) {
if ($(list[_i]).parent().attr('annotationid') === an.id)
if (parseInt($(list[_i]).parent().attr('annotationid'), 10) === an.id)
isInList = true;
}
return isInList;
......@@ -800,7 +800,7 @@ CatchAnnotation.prototype = {
$(evt.target).parents('.detailHeader:first').find('#myLocationMap .map').html(imgSrc);
},
_onPlaySelectionClick: function(evt) {
var id = $(evt.target).find('.idAnnotation').html();
var id = parseInt($(evt.target).find('.idAnnotation').html(), 10);
var uri = $(evt.target).find('.uri').html();
var container = $(evt.target).find('.container').html();
if (this.options.externalLink) {
......@@ -858,7 +858,7 @@ CatchAnnotation.prototype = {
},
_onZoomToImageBoundsButtonClick: function(evt){
var zoomToBounds = $(evt.target).hasClass('zoomToImageBounds')?$(evt.target):$(evt.target).parents('.zoomToImageBounds:first');
var osdaId = zoomToBounds.find('.idAnnotation').html();
var osdaId = parseInt(zoomToBounds.find('.idAnnotation').html(), 10);
var uri = zoomToBounds.find('.uri').html();
var allannotations = this.annotator.plugins['Store'].annotations;
......@@ -887,7 +887,7 @@ CatchAnnotation.prototype = {
},
_onQuoteMediaButton: function(evt) {
var quote = $(evt.target).hasClass('quote')?$(evt.target):$(evt.target).parents('.quote:first');
var id = quote.find('.idAnnotation').html();
var id = parseInt(quote.find('.idAnnotation').html(), 10);
var uri = quote.find('.uri').html();
if (typeof id === 'undefined' || id === ''){
this.refreshCatch();
......@@ -927,7 +927,7 @@ CatchAnnotation.prototype = {
},
_refreshReplies: function(evt) {
var item = $(evt.target).parents('.annotationItem:first');
var anId = item.attr('annotationId');
var anId = parseInt(item.attr('annotationId'), 10);
var replyElem = $(evt.target).parents('.annotationItem:first').find('.replies');
var annotator = this.annotator;
......@@ -954,7 +954,7 @@ CatchAnnotation.prototype = {
if (typeof replyItems !== 'undefined' && replyItems.length > 0) {
annotations.forEach(function(ann) {
replyItems.each(function(item) {
var id = $(replyItems[item]).attr('annotationid');
var id = parseInt($(replyItems[item]).attr('annotationid'), 10);
if (id === ann.id) {
var perm = self.annotator.plugins.Permissions;
if (!perm.options.userAuthorize('delete', ann, perm.user)) {
......@@ -1031,7 +1031,7 @@ CatchAnnotation.prototype = {
if (confirm("Would you like to delete the annotation?")) {
var annotator = this.annotator;
var item = $(evt.target).parents('.annotationItem:first');
var id = item.attr('annotationId');
var id = parseInt(item.attr('annotationId'), 10);
var store = annotator.plugins.Store;
var annotations = store.annotations;
var permissions = annotator.plugins.Permissions;
......@@ -1048,7 +1048,7 @@ CatchAnnotation.prototype = {
var annotator = this.annotator;
var item = $(evt.target).parents('.annotationItem:first');
var id = item.attr('annotationId');
var id = parseInt(item.attr('annotationId'), 10);
var store = annotator.plugins.Store;
var annotations = store.annotations;
var permissions = annotator.plugins.Permissions;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -433,5 +433,8 @@ ADVANCED_SECURITY_CONFIG = ENV_TOKENS.get('ADVANCED_SECURITY_CONFIG', {})
GOOGLE_ANALYTICS_ACCOUNT = AUTH_TOKENS.get('GOOGLE_ANALYTICS_ACCOUNT')
GOOGLE_ANALYTICS_LINKEDIN = AUTH_TOKENS.get('GOOGLE_ANALYTICS_LINKEDIN')
##### OPTIMIZELY PROJECT ID #####
OPTIMIZELY_PROJECT_ID = AUTH_TOKENS.get('OPTIMIZELY_PROJECT_ID', OPTIMIZELY_PROJECT_ID)
#### Course Registration Code length ####
REGISTRATION_CODE_LENGTH = ENV_TOKENS.get('REGISTRATION_CODE_LENGTH', 8)
......@@ -148,10 +148,7 @@ FEATURES = {
# Staff Debug tool.
'ENABLE_STUDENT_HISTORY_VIEW': True,
# Optimizely for the LMS--need to explicitly turn on for production.
'OPTIMIZELY_LMS': False,
# Segment.io for LMS--need to explicitly turn on for production.
# Segment.io for LMS--need to explicitly turn it on for production.
'SEGMENT_IO_LMS': False,
# Provide a UI to allow users to submit feedback from the LMS (left-hand help modal)
......@@ -474,6 +471,9 @@ if FEATURES.get('ENABLE_SQL_TRACKING_LOGS'):
GOOGLE_ANALYTICS_ACCOUNT = None
GOOGLE_ANALYTICS_LINKEDIN = 'GOOGLE_ANALYTICS_LINKEDIN_DUMMY'
######################## OPTIMIZELY ###########################
OPTIMIZELY_PROJECT_ID = None
######################## subdomain specific settings ###########################
COURSE_LISTINGS = {}
SUBDOMAIN_BRANDING = {}
......@@ -934,18 +934,6 @@ PIPELINE_CSS = {
'css/vendor/jquery.qtip.min.css',
'css/vendor/responsive-carousel/responsive-carousel.css',
'css/vendor/responsive-carousel/responsive-carousel.slide.css',
'css/vendor/ova/annotator.css',
'css/vendor/ova/edx-annotator.css',
'css/vendor/ova/video-js.min.css',
'css/vendor/ova/rangeslider.css',
'css/vendor/ova/share-annotator.css',
'css/vendor/ova/richText-annotator.css',
'css/vendor/ova/tags-annotator.css',
'css/vendor/ova/flagging-annotator.css',
'css/vendor/ova/diacritic-annotator.css',
'css/vendor/ova/grouping-annotator.css',
'css/vendor/ova/ova.css',
'js/vendor/ova/catch/css/main.css'
],
'output_filename': 'css/lms-style-vendor.css',
},
......@@ -995,6 +983,23 @@ PIPELINE_CSS = {
],
'output_filename': 'css/lms-style-course.css',
},
'style-xmodule-annotations': {
'source_filenames': [
'css/vendor/ova/annotator.css',
'css/vendor/ova/edx-annotator.css',
'css/vendor/ova/video-js.min.css',
'css/vendor/ova/rangeslider.css',
'css/vendor/ova/share-annotator.css',
'css/vendor/ova/richText-annotator.css',
'css/vendor/ova/tags-annotator.css',
'css/vendor/ova/flagging-annotator.css',
'css/vendor/ova/diacritic-annotator.css',
'css/vendor/ova/grouping-annotator.css',
'css/vendor/ova/ova.css',
'js/vendor/ova/catch/css/main.css'
],
'output_filename': 'css/lms-style-xmodule-annotations.css',
},
}
......@@ -1326,7 +1331,10 @@ INSTALLED_APPS = (
'monitoring',
# Course action state
'course_action_state'
'course_action_state',
# Additional problem types
'edx_jsme', # Molecular Structure
)
######################### MARKETING SITE ###############################
......
......@@ -31,6 +31,7 @@
<%namespace name='static' file='/static_content.html'/>
${static.css(group='style-vendor-tinymce-content', raw=True)}
${static.css(group='style-vendor-tinymce-skin', raw=True)}
${static.css(group='style-xmodule-annotations', raw=True)}
</div>
<div id="catchDIV">
<div class="annotationListContainer">${_('Note: only instructors may annotate.')}</div>
......@@ -181,23 +182,23 @@
};
var imgURLRoot = "${settings.STATIC_URL}" + "js/vendor/ova/catch/img/";
if (typeof Annotator != 'undefined'){
//remove old instances
var osda, annotator, catchOptions, Catch;
var startosda = function() {
//remove old instances
if (Annotator._instances.length !== 0) {
$('#imageHolder').annotator("destroy");
}
delete osda;
//Load the plugin Image/Text Annotation
var osda = new OpenSeadragonAnnotation($('#imageHolder'),options);
osda = new OpenSeadragonAnnotation($('#imageHolder'),options);
var userId = ('${default_tab}'.toLowerCase() === 'instructor') ?
'${instructor_email}':
'${user.email}';
//Catch
var annotator = osda.annotator;
var catchOptions = {
annotator = osda.annotator;
catchOptions = {
media:'image',
externalLink:false,
imageUrlRoot:imgURLRoot,
......@@ -214,10 +215,23 @@
// if annotations are opened to everyone (2) or if they want to create no annotations (1 with no instructor)
// then the table at the bottom of the source should be displayed
if ("${annotation_mode}" == "everyone" || ("${annotation_mode}" == "instructor" && "${instructor_email}" != ""))
var Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
// if it is in instructor mode only (1), the annotator should be destroyed for all except the instructor
if ("${annotation_mode}" == "instructor" && "${instructor_email}" == "" && !is_staff)
osda.annotator.destroy();
}
// if the following is true, template is being rendered in LMS, otherwise it is in Studio
if (typeof Annotator !== 'undefined') {
startosda();
} else {
try {
require(["osda"], function(osda){
startosda();
});
} catch(error) {
console.log("Error: " + error.message + " - Annotator not loaded in LMS.");
}
}
</script>
\ No newline at end of file
......@@ -2,6 +2,7 @@
<%namespace name='static' file='/static_content.html'/>
${static.css(group='style-vendor-tinymce-content', raw=True)}
${static.css(group='style-vendor-tinymce-skin', raw=True)}
${static.css(group='style-xmodule-annotations', raw=True)}
<div class="annotatable-wrapper">
<div class="annotatable-header">
......@@ -168,36 +169,51 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)}
};
var imgURLRoot = "${settings.STATIC_URL}" + "js/vendor/ova/catch/img/";
var ova, Catch, annotator, catchOptions;
var startova = function(){
//remove old instances
if (Annotator._instances.length !== 0) {
$('#textHolder').annotator("destroy");
}
delete ova;
//Load the plugin Video/Text Annotation
ova = new OpenVideoAnnotation.Annotator($('#textHolder'),options);
//remove old instances
if (Annotator._instances.length !== 0) {
$('#textHolder').annotator("destroy");
}
delete ova;
//Load the plugin Video/Text Annotation
var ova = new OpenVideoAnnotation.Annotator($('#textHolder'),options);
if (typeof Annotator.Plugin["Grouping"] === 'function')
ova.annotator.addPlugin("Grouping");
if (typeof Annotator.Plugin["Grouping"] === 'function')
ova.annotator.addPlugin("Grouping");
var userId = ('${default_tab}'.toLowerCase() === 'instructor') ?
'${instructor_email}':
'${user.email}';
var userId = ('${default_tab}'.toLowerCase() === 'instructor') ?
'${instructor_email}':
'${user.email}';
//Catch
annotator = ova.annotator;
catchOptions = {
media:'text',
externalLink:false,
imageUrlRoot:imgURLRoot,
showMediaSelector: false,
showPublicPrivate: true,
userId:userId,
pagination:pagination,//Number of Annotations per load in the pagination,
flags:is_staff,
default_tab: "${default_tab}",
instructor_email: "${instructor_email}",
annotation_mode: "${annotation_mode}",
};
Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
}
//Catch
var annotator = ova.annotator;
var catchOptions = {
media:'text',
externalLink:false,
imageUrlRoot:imgURLRoot,
showMediaSelector: false,
showPublicPrivate: true,
userId:userId,
pagination:pagination,//Number of Annotations per load in the pagination,
flags:is_staff,
default_tab: "${default_tab}",
instructor_email: "${instructor_email}",
annotation_mode: "${annotation_mode}",
};
var Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
// if the following is true, template is being rendered in LMS, otherwise it is in Studio
if (typeof Annotator !== 'undefined') {
startova();
} else {
try {
require(["ova"], function(ova) {
startova();
});
} catch(error) {
console.log("Error: " + error.message + " - Annotator not loaded in LMS.");
}
}
</script>
......@@ -2,6 +2,7 @@
<%namespace name='static' file='/static_content.html'/>
${static.css(group='style-vendor-tinymce-content', raw=True)}
${static.css(group='style-vendor-tinymce-skin', raw=True)}
${static.css(group='style-xmodule-annotations', raw=True)}
<div class="annotatable-wrapper">
<div class="annotatable-header">
......@@ -165,34 +166,47 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)}
};
var imgURLRoot = "${settings.STATIC_URL}" + "js/vendor/ova/catch/img/";
var ova, Catch, annotator, catchOptions;
var startova = function() {
//remove old instances
if (Annotator._instances.length !== 0) {
$('#videoHolder').annotator("destroy");
}
delete ova;
//Load the plugin Video/Text Annotation
ova = new OpenVideoAnnotation.Annotator($('#videoHolder'),options);
//remove old instances
if (Annotator._instances.length !== 0) {
$('#videoHolder').annotator("destroy");
}
delete ova;
//Load the plugin Video/Text Annotation
var ova = new OpenVideoAnnotation.Annotator($('#videoHolder'),options);
ova.annotator.addPlugin('Tags');
var userId = ('${default_tab}'.toLowerCase() === 'instructor') ?
'${instructor_email}':
'${user.email}';
ova.annotator.addPlugin('Tags');
var userId = ('${default_tab}'.toLowerCase() === 'instructor') ?
'${instructor_email}':
'${user.email}';
//Catch
var annotator = ova.annotator;
var catchOptions = {
media:'video',
externalLink:false,
imageUrlRoot:imgURLRoot,
showMediaSelector: false,
showPublicPrivate: true,
userId:userId,
pagination:pagination,//Number of Annotations per load in the pagination,
flags:is_staff,
default_tab: "${default_tab}",
instructor_email: "${instructor_email}",
annotation_mode: "${annotation_mode}",
};
var Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
//Catch
annotator = ova.annotator;
catchOptions = {
media:'video',
externalLink:false,
imageUrlRoot:imgURLRoot,
showMediaSelector: false,
showPublicPrivate: true,
userId:userId,
pagination:pagination,//Number of Annotations per load in the pagination,
flags:is_staff,
default_tab: "${default_tab}",
instructor_email: "${instructor_email}",
annotation_mode: "${annotation_mode}",
};
Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
}
if (typeof Annotator !== 'undefined') {
startova();
} else {
try {
require(["ova"], function(ova) {
startova();
});
} catch(error) {
console.log("Error: " + error.message + " - Annotator not loaded in LMS.");
}
}
</script>
% if settings.FEATURES.get('OPTIMIZELY_LMS'):
<script src="//cdn.optimizely.com/js/1706490390.js"></script>
% if settings.OPTIMIZELY_PROJECT_ID:
<script src=${'//cdn.optimizely.com/js/{}.js'.format(settings.OPTIMIZELY_PROJECT_ID)}></script>
% endif
......@@ -15,6 +15,7 @@
-e git+https://github.com/eventbrite/zendesk.git@d53fe0e81b623f084e91776bcf6369f8b7b63879#egg=zendesk
-e git+https://github.com/un33k/django-ipware.git@42cb1bb1dc680a60c6452e8bb2b843c2a0382c90#egg=django-ipware
-e git+https://github.com/appliedsec/pygeoip.git@95e69341cebf5a6a9fbf7c4f5439d458898bdc3b#egg=pygeoip
-e git+https://github.com/jazkarta/edx-jsme.git@813079fd5218ed275248d2a1fcae2fcbf20a0838#egg=edx-jsme
# Our libraries:
-e git+https://github.com/edx/XBlock.git@aed7a2c51a59836e435259ad0fb41f8e865fa530#egg=XBlock
......
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