From 8429897c82c0a3992b499bf64729feb08cb03839 Mon Sep 17 00:00:00 2001 From: lduarte1991 Date: Mon, 2 Jun 2014 23:22:26 -0400 Subject: [PATCH 1/8] Text Annotation Tool: Added Instructor Filter and Clear Search --- .../xmodule/xmodule/textannotation_module.py | 21 +++++ .../static/js/vendor/ova/catch/css/main.css | 20 +++-- common/static/js/vendor/ova/catch/js/catch.js | 84 +++++++++++++++---- lms/templates/textannotation.html | 14 +++- 4 files changed, 116 insertions(+), 23 deletions(-) diff --git a/common/lib/xmodule/xmodule/textannotation_module.py b/common/lib/xmodule/xmodule/textannotation_module.py index fe36d917d3..7d47ef87fa 100644 --- a/common/lib/xmodule/xmodule/textannotation_module.py +++ b/common/lib/xmodule/xmodule/textannotation_module.py @@ -65,6 +65,24 @@ class AnnotatableFields(object): scope=Scope.settings, default='', ) + default_tab = String( + display_name=_("Default Annotations Tab"), + help=_("Select which tab will be the default in the annotations table: myNotes, Instructor, or Public."), + scope=Scope.settings, + default="myNotes", + ) + instructor_username = String( + display_name=_("Username for 'Instructor' Annotations"), + help=_("Username that will be attached to all annotations that will be found in 'Instructor' tab."), + scope=Scope.settings, + default="", + ) + annotation_mode = String( + display_name=_("Mode for Annotation Tool"), + help=_("Type in number corresponding to following modes: 1 = only instructor can annotate , 2 = Everyone can annotate"), + scope=Scope.settings, + default="2", + ) class TextAnnotationModule(AnnotatableFields, XModule): @@ -101,6 +119,9 @@ class TextAnnotationModule(AnnotatableFields, XModule): 'annotation_storage': self.annotation_storage_url, 'token': retrieve_token(self.user_email, self.annotation_token_secret), 'diacritic_marks': self.diacritics, + 'default_tab': self.default_tab, + 'instructor_username': self.instructor_username, + '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") diff --git a/common/static/js/vendor/ova/catch/css/main.css b/common/static/js/vendor/ova/catch/css/main.css index b79bd80e0a..5f5406c560 100644 --- a/common/static/js/vendor/ova/catch/css/main.css +++ b/common/static/js/vendor/ova/catch/css/main.css @@ -379,14 +379,14 @@ display:inline-block; color:#302f2f; font-family:arial; - font-size:15px; + font-size:14px; font-weight:bold; padding:6px 24px; text-decoration:none; margin: 0px 0px 10px 0px; cursor:pointer; - width:140px; + width:115px; text-align:center; } @@ -468,7 +468,7 @@ #mainCatch .searchbox input{ margin: 0; padding: 0; - width: 60%; + width: 50%; margin-left: 10px; display: inline; float: left; @@ -493,19 +493,28 @@ cursor:pointer; } +#mainCatch .searchbox .clear-search-icon{ + font-size: 12px; + text-decoration: underline; + float: right; + margin-top: 10px; + padding-right: 3px; + cursor:pointer; +} + #mainCatch .searchbox .search-icon:hover{ opacity:0.5; box-shadow: 2px 4px 5px #888888; } #mainCatch .selectors{ - width:40%; + width:45%; position:relative; float:left; } #mainCatch .searchbox{ - width:60%; + width:52%; position:relative; float:right; } @@ -515,6 +524,7 @@ position:relative; padding-right:5px; margin-top:8px; + font-size:14px; } #mainCatch .replies .replyItem .deleteReply{ diff --git a/common/static/js/vendor/ova/catch/js/catch.js b/common/static/js/vendor/ova/catch/js/catch.js index 442873659f..950966fb07 100644 --- a/common/static/js/vendor/ova/catch/js/catch.js +++ b/common/static/js/vendor/ova/catch/js/catch.js @@ -76,6 +76,17 @@ annotationList: '
More
'+ '', +//Main->PublicPrivateInstructor +annotationPublicPrivateInstructor: + '
My NotesmyNotes
'+ + '
Instructorinstructor
'+ + '
Publicpublic
'+ + '', + //Main->PublicPrivate annotationPublicPrivate: '
My NotesmyNotes
'+ @@ -84,7 +95,7 @@ annotationPublicPrivate: ''+ ''+ ''+ - '
', + '
Clear
', //Main->MediaSelector annotationMediaSelector: @@ -290,14 +301,14 @@ CatchAnnotation = function (element, options) { //Reset element an create a new element div element.html('
'); - + this.current_tab = this.options.default_tab; //INIT var self = this; $( document ).ready(function() { self.init(); self.refreshCatch(true); - var moreBut = self.element.find('.annotationListButtons .moreButtonCatch'); - moreBut.hide(); + var moreBut = self.element.find('.annotationListButtons .moreButtonCatch'); + moreBut.hide(); }); return this; @@ -310,6 +321,7 @@ CatchAnnotation.prototype = { this.TEMPLATENAMES = [ "annotationList", //Main "annotationPublicPrivate", //Main->PublicPrivate + "annotationPublicPrivateInstructor", //Main->PublicPrivateInstructor "annotationMediaSelector", //Main->MediaSelector "annotationItem", //Main->ContainerRow "annotationReply",//Main->ContainerRow->Reply @@ -317,8 +329,8 @@ CatchAnnotation.prototype = { "annotationDetail",//Main->ContainerRow->DetailRow ]; //annotator - var wrapper = $('.annotator-wrapper').parent()[0], - annotator = $.data(wrapper, 'annotator'); + var wrapper = $('.annotator-wrapper').parent()[0]; + var annotator = $.data(wrapper, 'annotator'); this.annotator = annotator; //Subscribe to annotator @@ -336,6 +348,10 @@ CatchAnnotation.prototype = { this.HTMLTEMPLATES = CatchSources.HTMLTEMPLATES(this.options.imageUrlRoot); this.TEMPLATES = {}; this._compileTemplates(); + if(this.options.default_tab.toLowerCase() == 'instructor'){ + this.options.userId = this.options.instructor_username; + this._refresh('',''); + } }, // // GLOBAL UTILITIES @@ -380,10 +396,18 @@ CatchAnnotation.prototype = { if (newInstance){ var videoFormat = (mediaType === "video") ? true:false; + var publicprivatetemplate = ''; + if (self.options.showPublicPrivate) { + if(self.options.instructor_username != ''){ + publicprivatetemplate = self.TEMPLATES.annotationPublicPrivateInstructor(); + } else{ + publicprivatetemplate = self.TEMPLATES.annotationPublicPrivate(); + } + } el.html(self.TEMPLATES.annotationList({ annotationItems: annotationItems, videoFormat: videoFormat, - PublicPrivate: self.options.showPublicPrivate?self.TEMPLATES.annotationPublicPrivate():'', + PublicPrivate: publicprivatetemplate, MediaSelector: self.options.showMediaSelector?self.TEMPLATES.annotationMediaSelector():'', })); }else{ @@ -402,10 +426,21 @@ CatchAnnotation.prototype = { //Set PublicPrivate var PublicPrivateButtons = el.find('.annotationListButtons .PublicPrivate').removeClass('active'); //reset for (var index=0;index From 1dcf2dc10ab1916647664469a237ed0909595447 Mon Sep 17 00:00:00 2001 From: lduarte1991 Date: Mon, 2 Jun 2014 23:27:23 -0400 Subject: [PATCH 2/8] Video Annotation Tool: Added Instructor Filter --- .../xmodule/xmodule/videoannotation_module.py | 21 +++++++++++++++++++ lms/templates/textannotation.html | 2 -- lms/templates/videoannotation.html | 10 ++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/common/lib/xmodule/xmodule/videoannotation_module.py b/common/lib/xmodule/xmodule/videoannotation_module.py index 857ec5fcd9..e3fbde9944 100644 --- a/common/lib/xmodule/xmodule/videoannotation_module.py +++ b/common/lib/xmodule/xmodule/videoannotation_module.py @@ -57,6 +57,24 @@ class AnnotatableFields(object): default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", display_name=_("Secret Token String for Annotation") ) + default_tab = String( + display_name=_("Default Annotations Tab"), + help=_("Select which tab will be the default in the annotations table: myNotes, Instructor, or Public."), + scope=Scope.settings, + default="myNotes", + ) + instructor_username = String( + display_name=_("Username for 'Instructor' Annotations"), + help=_("Username that will be attached to all annotations that will be found in 'Instructor' tab."), + scope=Scope.settings, + default="", + ) + annotation_mode = String( + display_name=_("Mode for Annotation Tool"), + help=_("Type in number corresponding to following modes: 1 = only instructor can annotate , 2 = Everyone can annotate"), + scope=Scope.settings, + default="2", + ) class VideoAnnotationModule(AnnotatableFields, XModule): '''Video Annotation Module''' @@ -106,6 +124,9 @@ class VideoAnnotationModule(AnnotatableFields, XModule): 'content_html': self.content, 'annotation_storage': self.annotation_storage_url, 'token': retrieve_token(self.user_email, self.annotation_token_secret), + 'default_tab': self.default_tab, + 'instructor_username': self.instructor_username, + '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") diff --git a/lms/templates/textannotation.html b/lms/templates/textannotation.html index ba27390b62..4a817cafd8 100644 --- a/lms/templates/textannotation.html +++ b/lms/templates/textannotation.html @@ -182,8 +182,6 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)} userId = '${instructor_username}'; } - console.log("${user.is_staff}"); - //Catch var annotator = ova.annotator, catchOptions = { diff --git a/lms/templates/videoannotation.html b/lms/templates/videoannotation.html index 539e86909a..2259257d68 100644 --- a/lms/templates/videoannotation.html +++ b/lms/templates/videoannotation.html @@ -175,6 +175,10 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)} var ova = new OpenVideoAnnotation.Annotator($('#videoHolder'),options); ova.annotator.addPlugin('Tags'); + var userId = '${user.email}'; + if('${default_tab}'.toLowerCase() == 'instructor'){ + userId = '${instructor_username}'; + } //Catch var annotator = ova.annotator, @@ -184,9 +188,13 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)} imageUrlRoot:imgURLRoot, showMediaSelector: false, showPublicPrivate: true, - userId:'${user.email}', + userId:userId, pagination:pagination,//Number of Annotations per load in the pagination, flags:is_staff + flags:is_staff, + default_tab: "${default_tab}", + instructor_username: "${instructor_username}", + annotation_mode: "${annotation_mode}", }, Catch = new CatchAnnotation($('#catchDIV'),catchOptions); From 50e8ae9a6efeaf42fe3a98ad764cdd14bc1a7b3b Mon Sep 17 00:00:00 2001 From: lduarte1991 Date: Mon, 2 Jun 2014 23:31:14 -0400 Subject: [PATCH 3/8] Image Annotation Tool: Added Instructor Filter --- .../xmodule/xmodule/imageannotation_module.py | 21 +++++++++++++++++++ lms/templates/imageannotation.html | 14 ++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/common/lib/xmodule/xmodule/imageannotation_module.py b/common/lib/xmodule/xmodule/imageannotation_module.py index c6dc50d9ce..754c29359c 100644 --- a/common/lib/xmodule/xmodule/imageannotation_module.py +++ b/common/lib/xmodule/xmodule/imageannotation_module.py @@ -63,6 +63,24 @@ class AnnotatableFields(object): default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", display_name=_("Secret Token String for Annotation") ) + default_tab = String( + display_name=_("Default Annotations Tab"), + help=_("Select which tab will be the default in the annotations table: myNotes, Instructor, or Public."), + scope=Scope.settings, + default="myNotes", + ) + instructor_username = String( + display_name=_("Username for 'Instructor' Annotations"), + help=_("Username that will be attached to all annotations that will be found in 'Instructor' tab."), + scope=Scope.settings, + default="", + ) + annotation_mode = String( + display_name=_("Mode for Annotation Tool"), + help=_("Type in number corresponding to following modes: 1 = only instructor can annotate , 2 = Everyone can annotate"), + scope=Scope.settings, + default="2", + ) class ImageAnnotationModule(AnnotatableFields, XModule): @@ -104,6 +122,9 @@ class ImageAnnotationModule(AnnotatableFields, XModule): 'token': retrieve_token(self.user, self.annotation_token_secret), 'tag': self.instructor_tags, 'openseadragonjson': self.openseadragonjson, + 'default_tab': self.default_tab, + 'instructor_username': self.instructor_username, + 'annotation_mode': self.annotation_mode, } fragment = Fragment(self.system.render_template('imageannotation.html', context)) diff --git a/lms/templates/imageannotation.html b/lms/templates/imageannotation.html index e815c49506..dce0304516 100644 --- a/lms/templates/imageannotation.html +++ b/lms/templates/imageannotation.html @@ -189,6 +189,11 @@ //Load the plugin Image/Text Annotation var osda = new OpenSeadragonAnnotation($('#imageHolder'),options); + var userId = '${user.email}'; + if('${default_tab}'.toLowerCase() == 'instructor'){ + userId = '${instructor_username}'; + } + //Catch var annotator = osda.annotator, catchOptions = { @@ -197,9 +202,12 @@ imageUrlRoot:imgURLRoot, showMediaSelector: false, showPublicPrivate: true, - userId:'${user.email}', - pagination:pagination,//Number of Annotations per load in the pagination, - flags:is_staff + userId:userId, + pagination:pagination,//Number of Annotations per load in the pagination, + flags:is_staff, + default_tab: "${default_tab}", + instructor_username: "${instructor_username}", + annotation_mode: "${annotation_mode}", }, Catch = new CatchAnnotation($('#catchDIV'),catchOptions); From b22643adc2084d5ef53c0a5b40126c581c778668 Mon Sep 17 00:00:00 2001 From: lduarte1991 Date: Tue, 3 Jun 2014 11:01:58 -0400 Subject: [PATCH 4/8] Image Annotation Tool: Annotation Mode for AB Testing Annotation Tools PR Fixes - forgot to overwrite the previous line --- .../js/vendor/ova/OpenSeaDragonAnnotation.js | 27 ++++++++++--------- lms/templates/imageannotation.html | 18 ++++++++----- lms/templates/textannotation.html | 8 +++--- lms/templates/videoannotation.html | 9 +++---- 4 files changed, 33 insertions(+), 29 deletions(-) diff --git a/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js b/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js index d8c2f595c0..4fbadc4f47 100644 --- a/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js +++ b/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js @@ -380,19 +380,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. clickTimeThreshold: viewer.clickTimeThreshold, clickDistThreshold: viewer.clickDistThreshold }); - - /* Set elements to the control menu */ - viewer.annotatorControl = viewer.wrapperAnnotation.element; - if( viewer.toolbar ){ - viewer.toolbar.addControl( - viewer.annotatorControl, - {anchor: $.ControlAnchor.BOTTOM_RIGHT} - ); - }else{ - viewer.addControl( - viewer.annotatorControl, - {anchor: $.ControlAnchor.TOP_LEFT} - ); + if(this.options.viewer.annotation_mode == "2" || this.options.viewer.flags){ + /* Set elements to the control menu */ + viewer.annotatorControl = viewer.wrapperAnnotation.element; + if( viewer.toolbar ){ + viewer.toolbar.addControl( + viewer.annotatorControl, + {anchor: $.ControlAnchor.BOTTOM_RIGHT} + ); + }else{ + viewer.addControl( + viewer.annotatorControl, + {anchor: $.ControlAnchor.TOP_LEFT} + ); + } } }, _reset: function(){ diff --git a/lms/templates/imageannotation.html b/lms/templates/imageannotation.html index dce0304516..e938abee42 100644 --- a/lms/templates/imageannotation.html +++ b/lms/templates/imageannotation.html @@ -34,7 +34,7 @@
## Translators: Notes below refer to annotations. They wil later be put under a "Notes" section. -
${_('You do not have any notes.')}
+
${_('Note: only instructors may annotate.')}
@@ -72,7 +72,7 @@ var unit_id = $('#sequence-list').find('.active').attr("data-element"); uri += unit_id; var pagination = 100, - is_staff = !('${user.is_staff}'=='False'), + is_staff = ('${user.email}'=='${instructor_username}'), options = { optionsAnnotator: { permissions:{ @@ -172,6 +172,8 @@ }, optionsOpenSeadragon:{ id: "imageHolder", + annotation_mode: "${annotation_mode}", + flags: is_staff, prefixUrl: "${settings.STATIC_URL}" + "js/vendor/ova/images/", ${openseadragonjson} }, @@ -195,8 +197,8 @@ } //Catch - var annotator = osda.annotator, - catchOptions = { + var annotator = osda.annotator; + var catchOptions = { media:'image', externalLink:false, imageUrlRoot:imgURLRoot, @@ -208,8 +210,10 @@ default_tab: "${default_tab}", instructor_username: "${instructor_username}", annotation_mode: "${annotation_mode}", - }, - Catch = new CatchAnnotation($('#catchDIV'),catchOptions); - + }; + if ("${annotation_mode}" == "2" || ("${annotation_mode}" == 1 && "${instructor_username}" != "")) + var Catch = new CatchAnnotation($('#catchDIV'),catchOptions); + if ("${annotation_mode}" == 1 && "${instructor_username}" == "" && !is_staff) + osda.annotator.destroy(); } \ No newline at end of file diff --git a/lms/templates/textannotation.html b/lms/templates/textannotation.html index 4a817cafd8..5a55410434 100644 --- a/lms/templates/textannotation.html +++ b/lms/templates/textannotation.html @@ -183,8 +183,8 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)} } //Catch - var annotator = ova.annotator, - catchOptions = { + var annotator = ova.annotator; + var catchOptions = { media:'text', externalLink:false, imageUrlRoot:imgURLRoot, @@ -196,6 +196,6 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)} default_tab: "${default_tab}", instructor_username: "${instructor_username}", annotation_mode: "${annotation_mode}", - }, - Catch = new CatchAnnotation($('#catchDIV'),catchOptions); + }; + var Catch = new CatchAnnotation($('#catchDIV'),catchOptions); diff --git a/lms/templates/videoannotation.html b/lms/templates/videoannotation.html index 2259257d68..1ec4e18751 100644 --- a/lms/templates/videoannotation.html +++ b/lms/templates/videoannotation.html @@ -181,8 +181,8 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)} } //Catch - var annotator = ova.annotator, - catchOptions = { + var annotator = ova.annotator; + var catchOptions = { media:'video', externalLink:false, imageUrlRoot:imgURLRoot, @@ -190,11 +190,10 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)} showPublicPrivate: true, userId:userId, pagination:pagination,//Number of Annotations per load in the pagination, - flags:is_staff flags:is_staff, default_tab: "${default_tab}", instructor_username: "${instructor_username}", annotation_mode: "${annotation_mode}", - }, - Catch = new CatchAnnotation($('#catchDIV'),catchOptions); + }; + var Catch = new CatchAnnotation($('#catchDIV'),catchOptions); From 68acf66f6ca78512bed981ec64da1b8d395d18f8 Mon Sep 17 00:00:00 2001 From: lduarte1991 Date: Thu, 5 Jun 2014 12:44:36 -0400 Subject: [PATCH 5/8] Annotation Tools: PR Fixes - Fixed camel case for variable name - Fixed indentation in imageannotation.html - Changed all mentions of Instructor Username to Email - Turned annotation_mode into phrase - Fixed indentation in imageannotation.html - Added comments in imageannotation.html - Changing annotation_mode in OSDA --- .../xmodule/xmodule/imageannotation_module.py | 13 +- .../xmodule/xmodule/textannotation_module.py | 13 +- .../xmodule/xmodule/videoannotation_module.py | 15 +- .../js/vendor/ova/OpenSeaDragonAnnotation.js | 2 +- common/static/js/vendor/ova/catch/js/catch.js | 88 ++++----- lms/templates/imageannotation.html | 167 +++++++++--------- lms/templates/textannotation.html | 9 +- lms/templates/videoannotation.html | 9 +- 8 files changed, 163 insertions(+), 153 deletions(-) diff --git a/common/lib/xmodule/xmodule/imageannotation_module.py b/common/lib/xmodule/xmodule/imageannotation_module.py index 754c29359c..40d50b8b06 100644 --- a/common/lib/xmodule/xmodule/imageannotation_module.py +++ b/common/lib/xmodule/xmodule/imageannotation_module.py @@ -69,17 +69,18 @@ class AnnotatableFields(object): scope=Scope.settings, default="myNotes", ) - instructor_username = String( - display_name=_("Username for 'Instructor' Annotations"), - help=_("Username that will be attached to all annotations that will be found in 'Instructor' tab."), + # currently only supports one instructor, will build functionality for multiple later + instructor_email = String( + display_name=_("Email for 'Instructor' Annotations"), + help=_("Email of the user that will be attached to all annotations that will be found in 'Instructor' tab."), scope=Scope.settings, default="", ) annotation_mode = String( display_name=_("Mode for Annotation Tool"), - help=_("Type in number corresponding to following modes: 1 = only instructor can annotate , 2 = Everyone can annotate"), + help=_("Type in number corresponding to following modes: 'instructor' or 'everyone'"), scope=Scope.settings, - default="2", + default="everyone", ) @@ -123,7 +124,7 @@ class ImageAnnotationModule(AnnotatableFields, XModule): 'tag': self.instructor_tags, 'openseadragonjson': self.openseadragonjson, 'default_tab': self.default_tab, - 'instructor_username': self.instructor_username, + 'instructor_email': self.instructor_email, 'annotation_mode': self.annotation_mode, } diff --git a/common/lib/xmodule/xmodule/textannotation_module.py b/common/lib/xmodule/xmodule/textannotation_module.py index 7d47ef87fa..2bdda68ea2 100644 --- a/common/lib/xmodule/xmodule/textannotation_module.py +++ b/common/lib/xmodule/xmodule/textannotation_module.py @@ -71,17 +71,18 @@ class AnnotatableFields(object): scope=Scope.settings, default="myNotes", ) - instructor_username = String( - display_name=_("Username for 'Instructor' Annotations"), - help=_("Username that will be attached to all annotations that will be found in 'Instructor' tab."), + # currently only supports one instructor, will build functionality for multiple later + instructor_email = String( + display_name=_("Email for 'Instructor' Annotations"), + help=_("Email of the user that will be attached to all annotations that will be found in 'Instructor' tab."), scope=Scope.settings, default="", ) annotation_mode = String( display_name=_("Mode for Annotation Tool"), - help=_("Type in number corresponding to following modes: 1 = only instructor can annotate , 2 = Everyone can annotate"), + help=_("Type in number corresponding to following modes: 'instructor' or 'everyone'"), scope=Scope.settings, - default="2", + default="everyone", ) @@ -120,7 +121,7 @@ class TextAnnotationModule(AnnotatableFields, XModule): 'token': retrieve_token(self.user_email, self.annotation_token_secret), 'diacritic_marks': self.diacritics, 'default_tab': self.default_tab, - 'instructor_username': self.instructor_username, + 'instructor_email': self.instructor_email, 'annotation_mode': self.annotation_mode, } fragment = Fragment(self.system.render_template('textannotation.html', context)) diff --git a/common/lib/xmodule/xmodule/videoannotation_module.py b/common/lib/xmodule/xmodule/videoannotation_module.py index e3fbde9944..95848c0e9e 100644 --- a/common/lib/xmodule/xmodule/videoannotation_module.py +++ b/common/lib/xmodule/xmodule/videoannotation_module.py @@ -48,7 +48,7 @@ class AnnotatableFields(object): annotation_storage_url = String( help=_("Location of Annotation backend"), scope=Scope.settings, - default="http://your_annotation_storage.com", + default="http://your_annotation_storage.com", display_name=_("Url for Annotation Storage"), ) annotation_token_secret = String( @@ -63,17 +63,18 @@ class AnnotatableFields(object): scope=Scope.settings, default="myNotes", ) - instructor_username = String( - display_name=_("Username for 'Instructor' Annotations"), - help=_("Username that will be attached to all annotations that will be found in 'Instructor' tab."), + # currently only supports one instructor, will build functionality for multiple later + instructor_email = String( + display_name=_("Email for 'Instructor' Annotations"), + help=_("Email of the user that will be attached to all annotations that will be found in 'Instructor' tab."), scope=Scope.settings, default="", ) annotation_mode = String( display_name=_("Mode for Annotation Tool"), - help=_("Type in number corresponding to following modes: 1 = only instructor can annotate , 2 = Everyone can annotate"), + help=_("Type in number corresponding to following modes: 'instructor' or 'everyone'"), scope=Scope.settings, - default="2", + default="everyone", ) class VideoAnnotationModule(AnnotatableFields, XModule): @@ -125,7 +126,7 @@ class VideoAnnotationModule(AnnotatableFields, XModule): 'annotation_storage': self.annotation_storage_url, 'token': retrieve_token(self.user_email, self.annotation_token_secret), 'default_tab': self.default_tab, - 'instructor_username': self.instructor_username, + 'instructor_email': self.instructor_email, 'annotation_mode': self.annotation_mode, } fragment = Fragment(self.system.render_template('videoannotation.html', context)) diff --git a/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js b/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js index 4fbadc4f47..938af6e8d3 100644 --- a/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js +++ b/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js @@ -380,7 +380,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. clickTimeThreshold: viewer.clickTimeThreshold, clickDistThreshold: viewer.clickDistThreshold }); - if(this.options.viewer.annotation_mode == "2" || this.options.viewer.flags){ + if(this.options.viewer.annotation_mode == "everyone" || this.options.viewer.flags){ /* Set elements to the control menu */ viewer.annotatorControl = viewer.wrapperAnnotation.element; if( viewer.toolbar ){ diff --git a/common/static/js/vendor/ova/catch/js/catch.js b/common/static/js/vendor/ova/catch/js/catch.js index 950966fb07..c2f16b98e4 100644 --- a/common/static/js/vendor/ova/catch/js/catch.js +++ b/common/static/js/vendor/ova/catch/js/catch.js @@ -42,29 +42,29 @@ annotationList: ''+ '
'+ - 'User'+ + gettext('User')+ '
'+ '
'+ - 'Annotation'+ + gettext('Annotation')+ '
'+ '{{#if videoFormat}}'+ '
'+ - 'Start'+ + gettext('Start')+ '
'+ '
'+ - 'End'+ + gettext('End')+ '
'+ '{{/if}}'+ '
'+ - '#Replies'+ + gettext('#Replies')+ '
'+ '
'+ - 'Date posted'+ + gettext('Date posted')+ '
'+ ''+ ''+ @@ -73,41 +73,41 @@ annotationList: '{{/each}}'+ ''+ '
'+ - '
More
'+ + '
'+gettext('More')+'
'+ '
', //Main->PublicPrivateInstructor annotationPublicPrivateInstructor: - '
My NotesmyNotes
'+ - '
Instructorinstructor
'+ - '
Publicpublic
'+ - '', + '
'+gettext('My Notes')+'myNotes
'+ + '
'+gettext('Instructor')+'instructor
'+ + '
'+gettext('Public')+'public
'+ + '', //Main->PublicPrivate annotationPublicPrivate: - '
My NotesmyNotes
'+ - '
Publicpublic
'+ - '', + '
'+gettext('My Notes')+'myNotes
'+ + '
'+gettext('Public')+'public
'+ + '', //Main->MediaSelector annotationMediaSelector: '
    '+ '
  • '+ - 'Text'+ + gettext('Text')+ '
  • '+ '
  • '+ - 'Video'+ + gettext('Video')+ '
  • '+ 'li class="ui-state-default" media="image">'+ - 'Image'+ + gettext('Image')+ ''+ '
', @@ -137,7 +137,7 @@ annotationReply: '
'+ ''+ '{{/if}}'+ - '
Delete
'+ + '
'+gettext('Delete')+'
'+ '

'+ '

'+ '{{#if this.text}}'+ @@ -244,13 +244,13 @@ annotationDetail: ''+ '

'+ - '
Reply
 '+ + '
'+gettext('Reply')+'
 '+ '
Show Replies
 '+ '{{#if authToEditButton}}'+ - '
Edit
'+ + '
'+gettext('Edit')+'
'+ '{{/if}}'+ '{{#if authToDeleteButton}}'+ - '
Delete
'+ + '
'+gettext('Delete')+'
'+ '{{/if}}'+ '
'+ @@ -259,7 +259,7 @@ annotationDetail: '{{#if tags}}'+ '
'+ - '

Tags:

'+ + '

'+gettext('Tags:')+'

'+ '{{#each tags}}'+ '
'+ '{{this}}'+ @@ -348,14 +348,22 @@ CatchAnnotation.prototype = { this.HTMLTEMPLATES = CatchSources.HTMLTEMPLATES(this.options.imageUrlRoot); this.TEMPLATES = {}; this._compileTemplates(); + + // the default annotations are the user's personal ones instead of instructor + // if the default tab is instructor, we must refresh the catch to pull the ones + // under the instructor's email. passing empty strings as arguments will default + // to pulling the annotations for the email within this.options.userId. if(this.options.default_tab.toLowerCase() == 'instructor'){ - this.options.userId = this.options.instructor_username; + this.options.userId = this.options.instructor_email; this._refresh('',''); } }, // // GLOBAL UTILITIES // + getTemplate: function(templateName){ + return this.TEMPLATES[templateName]() || ''; + }, refreshCatch: function(newInstance) { var mediaType = this.options.media || 'text', annotationItems = [], @@ -396,18 +404,16 @@ CatchAnnotation.prototype = { if (newInstance){ var videoFormat = (mediaType === "video") ? true:false; - var publicprivatetemplate = ''; + var publicPrivateTemplate = ''; if (self.options.showPublicPrivate) { - if(self.options.instructor_username != ''){ - publicprivatetemplate = self.TEMPLATES.annotationPublicPrivateInstructor(); - } else{ - publicprivatetemplate = self.TEMPLATES.annotationPublicPrivate(); - } + var templateName = this.options.instructor_email ? + "annotationPublicPrivateInstructor" : + "annotationPublicPrivate"; } el.html(self.TEMPLATES.annotationList({ annotationItems: annotationItems, videoFormat: videoFormat, - PublicPrivate: publicprivatetemplate, + PublicPrivate: this.getTemplate(templateName), MediaSelector: self.options.showMediaSelector?self.TEMPLATES.annotationMediaSelector():'', })); }else{ @@ -433,7 +439,7 @@ CatchAnnotation.prototype = { self.options.userId = ''; break; case 'instructor': - self.options.userId = this.options.instructor_username; + self.options.userId = this.options.instructor_email; break; default: self.options.userId = this.annotator.plugins.Permissions.user.id; @@ -1055,7 +1061,7 @@ CatchAnnotation.prototype = { userId = ''; break; case 'instructor': - userId = this.options.instructor_username; + userId = this.options.instructor_email; break; default: userId = this.annotator.plugins.Permissions.user.id; @@ -1119,7 +1125,7 @@ CatchAnnotation.prototype = { }, _onClearSearchButtonClick: function(evt){ - this._refresh("",""); + this._refresh('',''); }, _clearAnnotator: function(){ var annotator = this.annotator, diff --git a/lms/templates/imageannotation.html b/lms/templates/imageannotation.html index e938abee42..74ce462560 100644 --- a/lms/templates/imageannotation.html +++ b/lms/templates/imageannotation.html @@ -9,70 +9,69 @@
-
- % if display_name is not UNDEFINED and display_name is not None: -
${display_name}
- % endif -
- % if instructions_html is not UNDEFINED and instructions_html is not None: -
-
- ${_('Instructions')} - ${_('Collapse Instructions')} -
-
- ${instructions_html} -
-
- % endif -
-
-
+
+ % if display_name is not UNDEFINED and display_name is not None: +
${display_name}
+ % endif +
+ % if instructions_html is not UNDEFINED and instructions_html is not None: +
+
+ ${_('Instructions')} + ${_('Collapse Instructions')} +
+
+ ${instructions_html} +
+
+ % endif +
+
+
<%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)}
-
- ## Translators: Notes below refer to annotations. They wil later be put under a "Notes" section. -
${_('Note: only instructors may annotate.')}
-
-
-
+
+
${_('Note: only instructors may annotate.')}
+
+
+
\ No newline at end of file diff --git a/lms/templates/textannotation.html b/lms/templates/textannotation.html index 5a55410434..19a261f7fa 100644 --- a/lms/templates/textannotation.html +++ b/lms/templates/textannotation.html @@ -177,10 +177,9 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)} //Load the plugin Video/Text Annotation var ova = new OpenVideoAnnotation.Annotator($('#textHolder'),options); - var userId = '${user.email}'; - if('${default_tab}'.toLowerCase() == 'instructor'){ - userId = '${instructor_username}'; - } + var userId = ('${default_tab}'.toLowerCase() === 'instructor') ? + '${instructor_email}': + '${user.email}'; //Catch var annotator = ova.annotator; @@ -194,7 +193,7 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)} pagination:pagination,//Number of Annotations per load in the pagination, flags:is_staff, default_tab: "${default_tab}", - instructor_username: "${instructor_username}", + instructor_email: "${instructor_email}", annotation_mode: "${annotation_mode}", }; var Catch = new CatchAnnotation($('#catchDIV'),catchOptions); diff --git a/lms/templates/videoannotation.html b/lms/templates/videoannotation.html index 1ec4e18751..07b61213c5 100644 --- a/lms/templates/videoannotation.html +++ b/lms/templates/videoannotation.html @@ -175,10 +175,9 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)} var ova = new OpenVideoAnnotation.Annotator($('#videoHolder'),options); ova.annotator.addPlugin('Tags'); - var userId = '${user.email}'; - if('${default_tab}'.toLowerCase() == 'instructor'){ - userId = '${instructor_username}'; - } + var userId = ('${default_tab}'.toLowerCase() === 'instructor') ? + '${instructor_email}': + '${user.email}'; //Catch var annotator = ova.annotator; @@ -192,7 +191,7 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)} pagination:pagination,//Number of Annotations per load in the pagination, flags:is_staff, default_tab: "${default_tab}", - instructor_username: "${instructor_username}", + instructor_email: "${instructor_email}", annotation_mode: "${annotation_mode}", }; var Catch = new CatchAnnotation($('#catchDIV'),catchOptions); From 9c0d14ea2b9b89c40d897d868202ab9b79fc5ae6 Mon Sep 17 00:00:00 2001 From: lduarte1991 Date: Thu, 5 Jun 2014 15:53:26 -0400 Subject: [PATCH 6/8] Annotator Tools: OpaqueKeys update for Notes --- common/static/js/vendor/ova/catch/js/catch.js | 6 ++- lms/djangoapps/notes/views.py | 8 +-- lms/templates/notes.html | 54 ++++++++++--------- 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/common/static/js/vendor/ova/catch/js/catch.js b/common/static/js/vendor/ova/catch/js/catch.js index c2f16b98e4..130d51a35e 100644 --- a/common/static/js/vendor/ova/catch/js/catch.js +++ b/common/static/js/vendor/ova/catch/js/catch.js @@ -106,7 +106,7 @@ annotationMediaSelector: '
  • '+ gettext('Video')+ '
  • '+ - 'li class="ui-state-default" media="image">'+ + '
  • '+ gettext('Image')+ '
  • '+ '', @@ -815,6 +815,10 @@ CatchAnnotation.prototype = { var allannotations = this.annotator.plugins['Store'].annotations, osda = this.annotator.osda; + if(this.options.externalLink){ + uri += (uri.indexOf('?') >= 0)?'&osdaId='+osdaId:'?osdaId='+osdaId; + location.href = uri; + } for(var item in allannotations){ var an = allannotations[item]; if (typeof an.id!='undefined' && an.id == osdaId){//this is the annotation diff --git a/lms/djangoapps/notes/views.py b/lms/djangoapps/notes/views.py index 88dc78f741..f121e2473a 100644 --- a/lms/djangoapps/notes/views.py +++ b/lms/djangoapps/notes/views.py @@ -1,6 +1,7 @@ from django.contrib.auth.decorators import login_required from django.http import Http404 from edxmako.shortcuts import render_to_response +from opaque_keys.edx.locations import SlashSeparatedCourseKey from courseware.courses import get_course_with_access from notes.models import Note from notes.utils import notes_enabled_for_course @@ -10,12 +11,12 @@ from xmodule.annotator_token import retrieve_token @login_required def notes(request, course_id): ''' Displays the student's notes. ''' - - course = get_course_with_access(request.user, 'load', course_id) + course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + course = get_course_with_access(request.user, 'load', course_key) if not notes_enabled_for_course(course): raise Http404 - notes = Note.objects.filter(course_id=course_id, user=request.user).order_by('-created', 'uri') + notes = Note.objects.filter(course_id=course_key, user=request.user).order_by('-created', 'uri') student = request.user storage = course.annotation_storage_url @@ -25,6 +26,7 @@ def notes(request, course_id): 'student': student, 'storage': storage, 'token': retrieve_token(student.email, course.annotation_token_secret), + 'default_tab': 'myNotes', } return render_to_response('notes.html', context) diff --git a/lms/templates/notes.html b/lms/templates/notes.html index 58f81be274..569393daaa 100644 --- a/lms/templates/notes.html +++ b/lms/templates/notes.html @@ -1,6 +1,10 @@ <%! from django.utils.translation import ugettext as _ %> <%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)} + + <%inherit file="main.html" /> <%! from django.core.urlresolvers import reverse @@ -102,7 +106,7 @@ if (annotation.permissions) { tokens = annotation.permissions[action] || []; if (is_staff){ - return true; + return true; } if (tokens.length === 0) { return true; @@ -128,7 +132,7 @@ }, }, auth: { - tokenUrl: location.protocol+'//'+location.host+"/token?course_id=${course.id.to_deprecated_string()}" + token: "${token}" }, store: { // The endpoint of the store on your server. @@ -158,37 +162,34 @@ optionsRichText: { tinymce:{ selector: "li.annotator-item textarea", - plugins: "media image insertdatetime link code", + plugins: "media image codemirror", menubar: false, toolbar_items_size: 'small', extended_valid_elements : "iframe[src|frameborder|style|scrolling|class|width|height|name|align|id]", - toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media rubric | code ", + toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | image rubric | code ", } - return true; - }, - }, - auth: { - token: "${token}" - }, - store: { - // The endpoint of the store on your server. - prefix: "${storage}", - - annotationData: {}, - - urls: { - // These are the default URLs. - create: '/create', - read: '/read/:id', - update: '/update/:id', - destroy: '/delete/:id', - search: '/search' }, + auth: { + token: "${token}" + }, + store: { + // The endpoint of the store on your server. + prefix: "${storage}", + + annotationData: {}, + + urls: { + // These are the default URLs. + create: '/create', + read: '/read/:id', + update: '/update/:id', + destroy: '/delete/:id', + search: '/search' + }, + } }; - tinyMCE.baseURL = "${settings.STATIC_URL}" + "js/vendor/ova"; var imgURLRoot = "${settings.STATIC_URL}" + "js/vendor/ova/catch/img/"; - //remove old instances if (Annotator._instances.length !== 0) { $('#notesHolder').annotator("destroy"); @@ -207,7 +208,8 @@ showMediaSelector: true, showPublicPrivate: true, pagination:pagination,//Number of Annotations per load in the pagination, - flags:is_staff + flags:is_staff, + default_tab: "${default_tab}", }, Catch = new CatchAnnotation($('#catchDIV'),catchOptions); From 54974a51ca9bc7bb3482c84705e4184435abb4f4 Mon Sep 17 00:00:00 2001 From: lduarte1991 Date: Fri, 6 Jun 2014 10:09:22 -0400 Subject: [PATCH 7/8] Annotation Tools: Added CommonAnnotatorMixin --- common/lib/xmodule/xmodule/annotator_mixin.py | 43 +++++++++++++++++++ .../xmodule/xmodule/imageannotation_module.py | 42 ++---------------- .../xmodule/xmodule/textannotation_module.py | 41 ++---------------- .../xmodule/xmodule/videoannotation_module.py | 42 +++--------------- 4 files changed, 56 insertions(+), 112 deletions(-) diff --git a/common/lib/xmodule/xmodule/annotator_mixin.py b/common/lib/xmodule/xmodule/annotator_mixin.py index aa597702db..114dde292c 100644 --- a/common/lib/xmodule/xmodule/annotator_mixin.py +++ b/common/lib/xmodule/xmodule/annotator_mixin.py @@ -6,7 +6,10 @@ from lxml import etree from urlparse import urlparse from os.path import splitext, basename from HTMLParser import HTMLParser +from xblock.core import Scope, String +# Make '_' a no-op so we can scrape strings +_ = lambda text: text def get_instructions(xmltree): """ Removes from the xmltree and returns them as a string, otherwise None. """ @@ -53,3 +56,43 @@ def html_to_text(html): htmlstripper = MLStripper() htmlstripper.feed(html) return htmlstripper.get_data() + + +class CommonAnnotatorMixin(object): + annotation_storage_url = String( + help=_("Location of Annotation backend"), + scope=Scope.settings, + default="http://your_annotation_storage.com", + display_name=_("Url for Annotation Storage") + ) + annotation_token_secret = String( + help=_("Secret string for annotation storage"), + scope=Scope.settings, + default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + display_name=_("Secret Token String for Annotation") + ) + default_tab = String( + display_name=_("Default Annotations Tab"), + help=_("Select which tab will be the default in the annotations table: myNotes, Instructor, or Public."), + scope=Scope.settings, + default="myNotes", + ) + # currently only supports one instructor, will build functionality for multiple later + instructor_email = String( + display_name=_("Email for 'Instructor' Annotations"), + help=_("Email of the user that will be attached to all annotations that will be found in 'Instructor' tab."), + scope=Scope.settings, + default="", + ) + annotation_mode = String( + display_name=_("Mode for Annotation Tool"), + help=_("Type in number corresponding to following modes: 'instructor' or 'everyone'"), + scope=Scope.settings, + default="everyone", + ) + extra_context = { + 'annotation_storage': annotation_storage_url, + 'default_tab': default_tab, + 'instructor_email': instructor_email, + 'annotation_mode': annotation_mode, + } \ No newline at end of file diff --git a/common/lib/xmodule/xmodule/imageannotation_module.py b/common/lib/xmodule/xmodule/imageannotation_module.py index 40d50b8b06..31c095da59 100644 --- a/common/lib/xmodule/xmodule/imageannotation_module.py +++ b/common/lib/xmodule/xmodule/imageannotation_module.py @@ -7,7 +7,7 @@ from pkg_resources import resource_string from xmodule.x_module import XModule from xmodule.raw_module import RawDescriptor from xblock.core import Scope, String -from xmodule.annotator_mixin import get_instructions, html_to_text +from xmodule.annotator_mixin import CommonAnnotatorMixin, get_instructions, html_to_text from xmodule.annotator_token import retrieve_token from xblock.fragment import Fragment @@ -51,40 +51,9 @@ class AnnotatableFields(object): scope=Scope.settings, default='professor:green,teachingAssistant:blue', ) - annotation_storage_url = String( - help=_("Location of Annotation backend"), - scope=Scope.settings, - default="http://your_annotation_storage.com", - display_name=_("Url for Annotation Storage") - ) - annotation_token_secret = String( - help=_("Secret string for annotation storage"), - scope=Scope.settings, - default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - display_name=_("Secret Token String for Annotation") - ) - default_tab = String( - display_name=_("Default Annotations Tab"), - help=_("Select which tab will be the default in the annotations table: myNotes, Instructor, or Public."), - scope=Scope.settings, - default="myNotes", - ) - # currently only supports one instructor, will build functionality for multiple later - instructor_email = String( - display_name=_("Email for 'Instructor' Annotations"), - help=_("Email of the user that will be attached to all annotations that will be found in 'Instructor' tab."), - scope=Scope.settings, - default="", - ) - annotation_mode = String( - display_name=_("Mode for Annotation Tool"), - help=_("Type in number corresponding to following modes: 'instructor' or 'everyone'"), - scope=Scope.settings, - default="everyone", - ) -class ImageAnnotationModule(AnnotatableFields, XModule): +class ImageAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule): '''Image Annotation Module''' js = { 'coffee': [ @@ -119,15 +88,12 @@ class ImageAnnotationModule(AnnotatableFields, XModule): context = { 'display_name': self.display_name_with_default, 'instructions_html': self.instructions, - 'annotation_storage': self.annotation_storage_url, 'token': retrieve_token(self.user, self.annotation_token_secret), 'tag': self.instructor_tags, 'openseadragonjson': self.openseadragonjson, - 'default_tab': self.default_tab, - 'instructor_email': self.instructor_email, - 'annotation_mode': self.annotation_mode, } - + context.update(self.extra_context) + print context 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") diff --git a/common/lib/xmodule/xmodule/textannotation_module.py b/common/lib/xmodule/xmodule/textannotation_module.py index 2bdda68ea2..1f10cea193 100644 --- a/common/lib/xmodule/xmodule/textannotation_module.py +++ b/common/lib/xmodule/xmodule/textannotation_module.py @@ -6,7 +6,7 @@ from pkg_resources import resource_string from xmodule.x_module import XModule from xmodule.raw_module import RawDescriptor from xblock.core import Scope, String -from xmodule.annotator_mixin import get_instructions +from xmodule.annotator_mixin import CommonAnnotatorMixin, get_instructions from xmodule.annotator_token import retrieve_token from xblock.fragment import Fragment import textwrap @@ -47,46 +47,15 @@ class AnnotatableFields(object): scope=Scope.settings, default='None', ) - annotation_storage_url = String( - help=_("Location of Annotation backend"), - scope=Scope.settings, - default="http://your_annotation_storage.com", - display_name=_("Url for Annotation Storage"), - ) - annotation_token_secret = String( - help=_("Secret string for annotation storage"), - scope=Scope.settings, - default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - display_name=_("Secret Token String for Annotation"), - ) diacritics = String( display_name=_("Diacritic Marks"), help=_("Add diacritic marks to be added to a text using the comma-separated form, i.e. markname;urltomark;baseline,markname2;urltomark2;baseline2"), scope=Scope.settings, default='', ) - default_tab = String( - display_name=_("Default Annotations Tab"), - help=_("Select which tab will be the default in the annotations table: myNotes, Instructor, or Public."), - scope=Scope.settings, - default="myNotes", - ) - # currently only supports one instructor, will build functionality for multiple later - instructor_email = String( - display_name=_("Email for 'Instructor' Annotations"), - help=_("Email of the user that will be attached to all annotations that will be found in 'Instructor' tab."), - scope=Scope.settings, - default="", - ) - annotation_mode = String( - display_name=_("Mode for Annotation Tool"), - help=_("Type in number corresponding to following modes: 'instructor' or 'everyone'"), - scope=Scope.settings, - default="everyone", - ) -class TextAnnotationModule(AnnotatableFields, XModule): +class TextAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule): ''' Text Annotation Module ''' js = {'coffee': [], 'js': []} @@ -117,13 +86,11 @@ class TextAnnotationModule(AnnotatableFields, XModule): 'source': self.source, 'instructions_html': self.instructions, 'content_html': self.content, - 'annotation_storage': self.annotation_storage_url, 'token': retrieve_token(self.user_email, self.annotation_token_secret), 'diacritic_marks': self.diacritics, - 'default_tab': self.default_tab, - 'instructor_email': self.instructor_email, - 'annotation_mode': self.annotation_mode, } + context.update(self.extra_context) + print context 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") diff --git a/common/lib/xmodule/xmodule/videoannotation_module.py b/common/lib/xmodule/xmodule/videoannotation_module.py index 95848c0e9e..cf93bf31d5 100644 --- a/common/lib/xmodule/xmodule/videoannotation_module.py +++ b/common/lib/xmodule/xmodule/videoannotation_module.py @@ -7,7 +7,7 @@ from pkg_resources import resource_string from xmodule.x_module import XModule from xmodule.raw_module import RawDescriptor from xblock.core import Scope, String -from xmodule.annotator_mixin import get_instructions, get_extension +from xmodule.annotator_mixin import CommonAnnotatorMixin, get_instructions, get_extension from xmodule.annotator_token import retrieve_token from xblock.fragment import Fragment @@ -45,39 +45,9 @@ class AnnotatableFields(object): scope=Scope.settings, default="" ) - annotation_storage_url = String( - help=_("Location of Annotation backend"), - scope=Scope.settings, - default="http://your_annotation_storage.com", - display_name=_("Url for Annotation Storage"), - ) - annotation_token_secret = String( - help=_("Secret string for annotation storage"), - scope=Scope.settings, - default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - display_name=_("Secret Token String for Annotation") - ) - default_tab = String( - display_name=_("Default Annotations Tab"), - help=_("Select which tab will be the default in the annotations table: myNotes, Instructor, or Public."), - scope=Scope.settings, - default="myNotes", - ) - # currently only supports one instructor, will build functionality for multiple later - instructor_email = String( - display_name=_("Email for 'Instructor' Annotations"), - help=_("Email of the user that will be attached to all annotations that will be found in 'Instructor' tab."), - scope=Scope.settings, - default="", - ) - annotation_mode = String( - display_name=_("Mode for Annotation Tool"), - help=_("Type in number corresponding to following modes: 'instructor' or 'everyone'"), - scope=Scope.settings, - default="everyone", - ) -class VideoAnnotationModule(AnnotatableFields, XModule): + +class VideoAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule): '''Video Annotation Module''' js = { 'coffee': [ @@ -123,12 +93,10 @@ class VideoAnnotationModule(AnnotatableFields, XModule): 'typeSource': extension, 'poster': self.poster_url, 'content_html': self.content, - 'annotation_storage': self.annotation_storage_url, 'token': retrieve_token(self.user_email, self.annotation_token_secret), - 'default_tab': self.default_tab, - 'instructor_email': self.instructor_email, - 'annotation_mode': self.annotation_mode, } + context.update(self.extra_context) + print context 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") From 3bfb633fd396d6a3c3b317915ccc95e4d3d117bc Mon Sep 17 00:00:00 2001 From: lduarte1991 Date: Fri, 6 Jun 2014 12:36:59 -0400 Subject: [PATCH 8/8] Annotator Tool: Fixed delete bug and factored out settings Removed print context --- common/lib/xmodule/xmodule/annotator_mixin.py | 6 ---- .../xmodule/xmodule/imageannotation_module.py | 6 ++-- .../xmodule/xmodule/textannotation_module.py | 6 ++-- .../xmodule/xmodule/videoannotation_module.py | 6 ++-- common/static/js/vendor/ova/catch/js/catch.js | 33 +++++++++++-------- 5 files changed, 31 insertions(+), 26 deletions(-) diff --git a/common/lib/xmodule/xmodule/annotator_mixin.py b/common/lib/xmodule/xmodule/annotator_mixin.py index 114dde292c..93768f564c 100644 --- a/common/lib/xmodule/xmodule/annotator_mixin.py +++ b/common/lib/xmodule/xmodule/annotator_mixin.py @@ -90,9 +90,3 @@ class CommonAnnotatorMixin(object): scope=Scope.settings, default="everyone", ) - extra_context = { - 'annotation_storage': annotation_storage_url, - 'default_tab': default_tab, - 'instructor_email': instructor_email, - 'annotation_mode': annotation_mode, - } \ No newline at end of file diff --git a/common/lib/xmodule/xmodule/imageannotation_module.py b/common/lib/xmodule/xmodule/imageannotation_module.py index 31c095da59..b605dfa131 100644 --- a/common/lib/xmodule/xmodule/imageannotation_module.py +++ b/common/lib/xmodule/xmodule/imageannotation_module.py @@ -91,9 +91,11 @@ class ImageAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule): 'token': retrieve_token(self.user, self.annotation_token_secret), 'tag': self.instructor_tags, 'openseadragonjson': self.openseadragonjson, + 'annotation_storage': self.annotation_storage_url, + 'default_tab': self.default_tab, + 'instructor_email': self.instructor_email, + 'annotation_mode': self.annotation_mode, } - context.update(self.extra_context) - print context 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") diff --git a/common/lib/xmodule/xmodule/textannotation_module.py b/common/lib/xmodule/xmodule/textannotation_module.py index 1f10cea193..cdfe43857d 100644 --- a/common/lib/xmodule/xmodule/textannotation_module.py +++ b/common/lib/xmodule/xmodule/textannotation_module.py @@ -88,9 +88,11 @@ class TextAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule): 'content_html': self.content, 'token': retrieve_token(self.user_email, self.annotation_token_secret), 'diacritic_marks': self.diacritics, + 'annotation_storage': self.annotation_storage_url, + 'default_tab': self.default_tab, + 'instructor_email': self.instructor_email, + 'annotation_mode': self.annotation_mode, } - context.update(self.extra_context) - print context 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") diff --git a/common/lib/xmodule/xmodule/videoannotation_module.py b/common/lib/xmodule/xmodule/videoannotation_module.py index cf93bf31d5..17dc49acb5 100644 --- a/common/lib/xmodule/xmodule/videoannotation_module.py +++ b/common/lib/xmodule/xmodule/videoannotation_module.py @@ -94,9 +94,11 @@ class VideoAnnotationModule(AnnotatableFields, CommonAnnotatorMixin, XModule): 'poster': self.poster_url, 'content_html': self.content, 'token': retrieve_token(self.user_email, self.annotation_token_secret), + 'annotation_storage': self.annotation_storage_url, + 'default_tab': self.default_tab, + 'instructor_email': self.instructor_email, + 'annotation_mode': self.annotation_mode, } - context.update(self.extra_context) - print context 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") diff --git a/common/static/js/vendor/ova/catch/js/catch.js b/common/static/js/vendor/ova/catch/js/catch.js index 130d51a35e..a45b778d99 100644 --- a/common/static/js/vendor/ova/catch/js/catch.js +++ b/common/static/js/vendor/ova/catch/js/catch.js @@ -613,21 +613,26 @@ CatchAnnotation.prototype = { var annotations = annotator.plugins['Store'].annotations, tot = typeof annotations !='undefined'?annotations.length:0, attempts = 0; // max 100 + if(annotation.media == "image"){ + self.refreshCatch(true); + self.checkTotAnnotations(); + } else { //This is to watch the annotations object, to see when is deleted the annotation - var ischanged = function(){ - var new_tot = annotator.plugins['Store'].annotations.length; - if (attempts<100) - setTimeout(function(){ - if (new_tot != tot){ - self.refreshCatch(true); - self.checkTotAnnotations(); - }else{ - attempts++; - ischanged(); - } - },100); //wait for the change in the annotations - }; - ischanged(); + var ischanged = function(){ + var new_tot = annotator.plugins['Store'].annotations.length; + if (attempts<100) + setTimeout(function(){ + if (new_tot != tot){ + self.refreshCatch(true); + self.checkTotAnnotations(); + }else{ + attempts++; + ischanged(); + } + },100); //wait for the change in the annotations + }; + ischanged(); + } }); annotator.subscribe("annotationCreated", function (annotation){ var attempts = 0; // max 100