From de5edcffbbaa52932f6ca64efc019f1979bee678 Mon Sep 17 00:00:00 2001 From: lduarte1991 Date: Fri, 25 Apr 2014 16:05:06 -0400 Subject: [PATCH 1/3] Diacritic Plugin for Annotator TooL: Added CSS and JS files - UI Fixes for Diacritic Mark Plugin --- .../css/vendor/ova/diacritic-annotator.css | 8 + .../static/css/vendor/ova/edx-annotator.css | 4 + .../css/vendor/ova/richText-annotator.css | 14 +- .../static/css/vendor/ova/tags-annotator.css | 2 +- .../js/vendor/ova/diacritic-annotator.js | 204 ++++++++++++++++++ .../js/vendor/ova/flagging-annotator.js | 1 - common/static/js/vendor/ova/ova.js | 17 +- common/static/js/vendor/ova/rangeslider.js | 2 +- .../static/js/vendor/ova/reply-annotator.js | 2 +- .../js/vendor/ova/richText-annotator.js | 5 +- .../static/js/vendor/ova/share-annotator.js | 3 +- common/static/js/vendor/ova/tags-annotator.js | 1 - lms/envs/common.py | 2 + 13 files changed, 237 insertions(+), 28 deletions(-) create mode 100644 common/static/css/vendor/ova/diacritic-annotator.css create mode 100644 common/static/js/vendor/ova/diacritic-annotator.js diff --git a/common/static/css/vendor/ova/diacritic-annotator.css b/common/static/css/vendor/ova/diacritic-annotator.css new file mode 100644 index 000000000000..f9055978c455 --- /dev/null +++ b/common/static/css/vendor/ova/diacritic-annotator.css @@ -0,0 +1,8 @@ +.mark{ + width: 10px; + height: 10px; + position: absolute; + background-size: contain; + background-repeat: no-repeat; + background-position: 50% 0%; +} diff --git a/common/static/css/vendor/ova/edx-annotator.css b/common/static/css/vendor/ova/edx-annotator.css index 9b0c0de0b8fa..a4bc6f91ca2f 100644 --- a/common/static/css/vendor/ova/edx-annotator.css +++ b/common/static/css/vendor/ova/edx-annotator.css @@ -1,4 +1,8 @@ /*This is written to fix some design problems with edX*/ +.annotatable-wrapper .annotatable-header .annotatable-title{ + padding-top: 20px !important; +} + .annotator-wrapper .annotator-adder button { opacity:0; } diff --git a/common/static/css/vendor/ova/richText-annotator.css b/common/static/css/vendor/ova/richText-annotator.css index bf384fa18da6..9512fad0a093 100644 --- a/common/static/css/vendor/ova/richText-annotator.css +++ b/common/static/css/vendor/ova/richText-annotator.css @@ -16,6 +16,14 @@ font-style: italic; } +.mce-floatpanel { + z-index: 700000000!important; +} + +.annotator-wrapper .mce-container { + z-index: 3000000000!important; /*To fix full-screen problems*/ +} + .mce-container-body { min-width: 400px; } @@ -25,10 +33,6 @@ min-width: 400px; } -.mce-floatpanel { - z-index: 700000000!important; -} - div.mce-tinymce.mce-container.mce-panel { min-width:400px; } @@ -42,4 +46,4 @@ div.mce-tinymce.mce-container.mce-panel { .mce-ico.mce-i-rubric{ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QkBBB07nraNoQAAAhZJREFUKM+NkstrE1EUxr+5c08ykztpJtVoazHBF8FgQQzonyBKEZS6FrQKLl0EXBRT0ZULJSs3oii4TyHgu90IlTaL6qouWlv7Ck1N0BSnmZk714WbPHz07M4534+Pw3eAHdTY8A9+Nd9/bshU1DpnO4HXjh2ZY2J9/OSTxHTrnP8PvJYf+BDQ6qEDaQBB43jrTusUFy4oPjsYWYzF+VS91nxLYfdhKgONaQT3W/KMxr1XY5e+qj86f8zsKYYsZ6AvjWFzA8ORHkAnwN8So7evzL/8pzMAXL/Hq8mMv1up371T7Z+/c3n9cKeuDS6Xy6dN07zLuZ56Onk2Ed2/ANJsnE/PQMpgyffle+kYzwazB1+3waVS6X48Hr9BRPB9H57nYXplFKeSt8D1Hriug9XKF0x+Lmw+ys8m2m42DOOn4zhQSsGyLOi6jqONm9isbmFVFlDbaGKx8QaB1rvdlbNhGLAsC0IIGIYBIQSy2ROQ0oOp7wOPraHXEugRvDtnzjmi0SiICEIIEBGklAB9B6cmbG0AUnrY5m73h+m6DsYYTNMEYwxEBMY0hGNVhHkcZigBO9qHlDHS7cwYg23bAIBQKAQigud7IH0XwtxDoHwEIQ9SLKx0wa7rPiaivYyxESklXNeFBg0mjyNQTQSuATMSm6ipuYt//eVcLhdeXl5+UKlUlur1upqamVAv3j3/VCyOD3VqfwF6uLp3q+vMcgAAAABJRU5ErkJggg=='); background-repeat: no-repeat; -} \ No newline at end of file +} diff --git a/common/static/css/vendor/ova/tags-annotator.css b/common/static/css/vendor/ova/tags-annotator.css index e1e58286286a..054e797e967e 100644 --- a/common/static/css/vendor/ova/tags-annotator.css +++ b/common/static/css/vendor/ova/tags-annotator.css @@ -43,7 +43,7 @@ li.token-input-input-token { div.token-input-dropdown { position: absolute; - width: 120px; + width: 400px; background-color: #fff; overflow: hidden; border-left: 1px solid #ccc; diff --git a/common/static/js/vendor/ova/diacritic-annotator.js b/common/static/js/vendor/ova/diacritic-annotator.js new file mode 100644 index 000000000000..87456096acaf --- /dev/null +++ b/common/static/js/vendor/ova/diacritic-annotator.js @@ -0,0 +1,204 @@ +/* + Diacritic Annotator Plugin v1.0 (https://github.com/lduarte1991/diacritic-annotator) + Copyright (C) 2014 Luis F Duarte + License: https://github.com/lduarte1991/diacritic-annotator/blob/master/LICENSE.rst + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +var _ref, + __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + +Annotator.Plugin.Diacritics = (function(_super) { + __extends(Diacritics, _super); + + //Options will include diacritic name, picture used, baseline + Diacritics.prototype.options = null; + Diacritics.prototype.diacriticmarks = null; + + //initiate diacritics elements + function Diacritics(element,options) { + this.pluginSubmit = __bind(this.pluginSubmit, this); + this.updateDiacritics = __bind(this.updateDiacritics, this); + this.updateViewer = __bind(this.updateViewer, this); + this.getDiacritics = __bind(this.getDiacritics, this); + this.getPos = __bind(this.getPos, this); + this.putMarkatLocation = __bind(this.putMarkatLocation, this); + this.updateEditorForDiacritics = __bind(this.updateEditorForDiacritics, this); + + this.options = options; + this.diacriticmarks = this.getDiacritics(); + _ref = Diacritics.__super__.constructor.apply(this, arguments); + return _ref; + } + + //example variables to be used to receive input in the annotator view + Diacritics.prototype.field = null; + Diacritics.prototype.input = null; + + //this function will initialize the plug in + Diacritics.prototype.pluginInit = function() { + console.log("Diacritics-pluginInit"); + + //Check that annotator is working + if (!Annotator.supported()) { + return; + } + var di = this.diacriticmarks; + + //-- Editor + var self = this; + if(di != 'undefined'){ + $.each(di,function(item){ + self.field = self.annotator.editor.addField({ + type: 'checkbox', //options (textarea,input,select,checkbox) + label: Annotator._t(item), + submit: self.pluginSubmit, + }); + }); + + //-- Viewer + var newview = this.annotator.viewer.addField({ + load: this.updateViewer, + }); + + this.annotator.subscribe('annotationsLoaded', this.updateDiacritics); + this.annotator.subscribe('annotationUploaded', this.updateDiacritics); + this.annotator.subscribe('annotationDeleted', this.updateDiacritics); + this.annotator.subscribe('annotationUpdated', this.updateDiacritics); + this.annotator.subscribe('annotationEditorShown', this.updateEditorForDiacritics, this.field); + + var self = this; + $(window).resize(function() { + self.updateDiacritics(); + }); + } + + return this.input = $(this.field).find(':input'); + }; + + //The following function is run when a person hits submit. + Diacritics.prototype.pluginSubmit = function(field, annotation) { + var checkedItems = $(this.field).find(':input'); + var self = this; + $.each(checkedItems, function(item){ + if(typeof annotation.tags != 'undefined'){ + var index = $.inArray(checkedItems[item].placeholder, annotation.tags); + if(index != -1){ + annotation.tags.splice(index, 1); + if (typeof $($('.annotator-wrapper')[0]).find('div.'+annotation.id)[0] != 'undefined'){ + $($('.annotator-wrapper')[0]).find('div.'+annotation.id)[0].remove(); + } else { + $($('.annotator-wrapper')[0]).find('div.undefined')[0].remove(); + } + } + + if(checkedItems[item].checked == true){ + annotation.tags.unshift(checkedItems[item].placeholder); + self.putMarkatLocation(annotation, checkedItems[item].placeholder); + } + } else { + if(checkedItems[item].checked == true){ + annotation['tags'] = [checkedItems[item].placeholder]; + self.putMarkatLocation(annotation, checkedItems[item].placeholder); + } + } + }); + + } + + Diacritics.prototype.putMarkatLocation = function (annotation, mark){ + var loc = this.getPos(annotation.highlights[0]); + var alignment = this.diacriticmarks[mark][1]; + var imgurl = this.diacriticmarks[mark][0]; + + var newdiv = document.createElement('div'); + var className = 'mark ' + annotation.id; + newdiv.setAttribute('class',className); + if(alignment == 'top'){ + $(newdiv).css('top',""+(loc.y-5)+"px"); + } else if(alignment == 'bottom'){ + $(newdiv).css('top',""+(loc.y+loc.height-5)+"px"); + } else{ + $(newdiv).css('top',""+loc.y+"px"); + } + $(newdiv).css('left',""+(loc.x+(loc.width/2.0)-5)+"px"); + $(newdiv).css('background-image', 'url('+imgurl+')'); + $('.annotator-wrapper')[0].appendChild(newdiv); + } + + Diacritics.prototype.getDiacritics = function(){ + if(typeof this.options.diacritics != 'undefined'){ + var self = this; + var final = new Object(), prelim = this.options.diacritics.split(","); + prelim.forEach(function(item){ + var temp = item.split(";"); + if (temp.length <3) {return undefined;} + final[temp[0]] = [temp[1],temp[2]]; + }); + return final; + } + console.log("Was undefined"); + return undefined; + } + + Diacritics.prototype.getPos = function(el) { + var off = $(el).offset(); + return {x: off.left-$($('.annotator-wrapper')[0]).offset().left, y: off.top-$($('.annotator-wrapper')[0]).offset().top, width:$(el).width(), height:$(el).height()}; + } + + Diacritics.prototype.updateDiacritics = function(){ + $('.mark').remove(); + var annotations = this.annotator.plugins['Store'].annotations; + var self = this; + annotations.forEach(function(ann){ + $.each(self.diacriticmarks, function(item){ + if($.inArray(item, ann.tags) != -1){ + self.putMarkatLocation(ann, item); + } + }); + }); + } + + Diacritics.prototype.updateViewer = function(field,annotation){ + $(field).remove(); + } + + Diacritics.prototype.updateEditorForDiacritics = function(field, annotation){ + if (typeof annotation.tags == 'undefined'){ + return; + } + var self = this; + + var inputItems = $(this.field).find(':input'); + var dictOfItems = {} + $.each(inputItems, function(item){ + inputItems[item].checked = false; + dictOfItems[inputItems[item].placeholder] = inputItems[item]; + }); + annotation.tags.forEach(function(tag){ + if(typeof self.diacriticmarks[tag] != 'undefined'){ + dictOfItems[tag].checked = true; + } + }); + } + + + + return Diacritics; + +})(Annotator.Plugin); \ No newline at end of file diff --git a/common/static/js/vendor/ova/flagging-annotator.js b/common/static/js/vendor/ova/flagging-annotator.js index 16b658d6de96..8aa792334ffe 100644 --- a/common/static/js/vendor/ova/flagging-annotator.js +++ b/common/static/js/vendor/ova/flagging-annotator.js @@ -1,4 +1,3 @@ -// Generated by CoffeeScript 1.6.3 var _ref, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, diff --git a/common/static/js/vendor/ova/ova.js b/common/static/js/vendor/ova/ova.js index 059af1322f6e..fc5bda3d3698 100644 --- a/common/static/js/vendor/ova/ova.js +++ b/common/static/js/vendor/ova/ova.js @@ -1,6 +1,6 @@ /* Open Video Annotation v1.0 (http://openvideoannotation.org/) -Copyright (C) 2014 CHS (Harvard University), Daniel Cebri‡n Robles and Phil Desenne +Copyright (C) 2014 CHS (Harvard University), Daniel Cebrian Robles and Phil Desenne License: https://github.com/CtrHellenicStudies/OpenVideoAnnotation/blob/master/License.rst This program is free software; you can redistribute it and/or @@ -2389,17 +2389,8 @@ OpenVideoAnnotation.Annotator = function (element, options) { if (typeof options.optionsAnnotator.highlightTags!='undefined') this.annotator.addPlugin("HighlightTags", options.optionsAnnotator.highlightTags); - - /* - this.annotator.addPlugin("Filter", { - filters: [ - { - label: 'Media', - property: 'media' - } - ] - });//it is obligatory to have - */ + if (typeof options.optionsAnnotator.diacriticMarks != 'undefined' && typeof Annotator.Plugin["Diacritics"] === 'function') + this.annotator.addPlugin("Diacritics", options.optionsAnnotator.diacriticMarks); if (typeof Annotator.Plugin["Geolocation"] === 'function') this.annotator.addPlugin("Geolocation",options.optionsAnnotator.geolocation); @@ -2415,7 +2406,7 @@ OpenVideoAnnotation.Annotator = function (element, options) { if (typeof Annotator.Plugin["Reply"] === 'function') this.annotator.addPlugin("Reply"); - if (typeof Annotator.Plugin["Flagging"] === 'function') + if (typeof Annotator.Plugin["Flagging"] === 'function') this.annotator.addPlugin("Flagging"); //Will be add the player and the annotations plugin for video-js in the annotator diff --git a/common/static/js/vendor/ova/rangeslider.js b/common/static/js/vendor/ova/rangeslider.js index 51e054fcbad7..e0250b936a80 100644 --- a/common/static/js/vendor/ova/rangeslider.js +++ b/common/static/js/vendor/ova/rangeslider.js @@ -1,6 +1,6 @@ /* RangeSlider v1.0 (https://github.com/danielcebrian/rangeslider-videojs) -Copyright (C) 2014 Daniel Cebri‡n Robles +Copyright (C) 2014 Daniel Cebrian Robles License: https://github.com/danielcebrian/rangeslider-videojs/blob/master/License.rst This program is free software; you can redistribute it and/or diff --git a/common/static/js/vendor/ova/reply-annotator.js b/common/static/js/vendor/ova/reply-annotator.js index 6ced09eb150a..cf3f31daa194 100644 --- a/common/static/js/vendor/ova/reply-annotator.js +++ b/common/static/js/vendor/ova/reply-annotator.js @@ -1,6 +1,6 @@ /* Reply Annotator Plugin v1.0 (https://github.com/danielcebrian/reply-annotator) - Copyright (C) 2014 Daniel Cebri‡n Robles + Copyright (C) 2014 Daniel Cebrian Robles License: https://github.com/danielcebrian/reply-annotator/blob/master/License.rst This program is free software; you can redistribute it and/or diff --git a/common/static/js/vendor/ova/richText-annotator.js b/common/static/js/vendor/ova/richText-annotator.js index fa7908d678b5..2179423382c0 100644 --- a/common/static/js/vendor/ova/richText-annotator.js +++ b/common/static/js/vendor/ova/richText-annotator.js @@ -1,6 +1,6 @@ /* Rich Text Annotator Plugin v1.0 (https://github.com/danielcebrian/richText-annotator) -Copyright (C) 2014 Daniel Cebri‡n Robles +Copyright (C) 2014 Daniel Cebrian Robles License: https://github.com/danielcebrian/richText-annotator/blob/master/License.rst This program is free software; you can redistribute it and/or @@ -17,7 +17,6 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -// Generated by CoffeeScript 1.6.3 var _ref, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, @@ -131,7 +130,7 @@ Annotator.Plugin.RichText = (function(_super) { RichText.prototype.updateEditor = function(field, annotation) { var text = typeof annotation.text!='undefined'?annotation.text:''; - tinymce.activeEditor.setContent(text); + tinymce.activeEditor.setContent(text); $(field).remove(); //this is the auto create field by annotator and it is not necessary } diff --git a/common/static/js/vendor/ova/share-annotator.js b/common/static/js/vendor/ova/share-annotator.js index 013933703f36..b6648e32456d 100644 --- a/common/static/js/vendor/ova/share-annotator.js +++ b/common/static/js/vendor/ova/share-annotator.js @@ -1,6 +1,6 @@ /* Share Annotation Plugin v1.0 (https://github.com/danielcebrian/share-annotator) -Copyright (C) 2014 Daniel Cebri‡n Robles +Copyright (C) 2014 Daniel Cebrian Robles License: https://github.com/danielcebrian/share-annotator/blob/master/License.rst This program is free software; you can redistribute it and/or @@ -17,7 +17,6 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -// Generated by CoffeeScript 1.6.3 var _ref, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, diff --git a/common/static/js/vendor/ova/tags-annotator.js b/common/static/js/vendor/ova/tags-annotator.js index 0083953a5f77..8ff387f9e3ee 100644 --- a/common/static/js/vendor/ova/tags-annotator.js +++ b/common/static/js/vendor/ova/tags-annotator.js @@ -886,7 +886,6 @@ $.TokenList.Cache = function (options) { }; }(jQuery)); -// Generated by CoffeeScript 1.6.3 var _ref, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, diff --git a/lms/envs/common.py b/lms/envs/common.py index afc9d39ca0ad..815d0756074e 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -848,6 +848,7 @@ 'js/vendor/ova/reply-annotator.js', 'js/vendor/ova/tags-annotator.js', 'js/vendor/ova/flagging-annotator.js', + 'js/vendor/ova/diacritic-annotator.js', 'js/vendor/ova/jquery-Watch.js', 'js/vendor/ova/openseadragon.js', 'js/vendor/ova/OpenSeaDragonAnnotation.js', @@ -878,6 +879,7 @@ '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/ova.css', 'js/vendor/ova/catch/css/main.css' ], From 88d8813942e7b769337eac67f1af551bc2438e3f Mon Sep 17 00:00:00 2001 From: lduarte1991 Date: Mon, 28 Apr 2014 17:41:56 -0400 Subject: [PATCH 2/3] Diacritic Plugin for Annotator Tool: Added studio input --- .../xmodule/xmodule/textannotation_module.py | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/common/lib/xmodule/xmodule/textannotation_module.py b/common/lib/xmodule/xmodule/textannotation_module.py index afbdd86f2766..ef27141b1eb1 100644 --- a/common/lib/xmodule/xmodule/textannotation_module.py +++ b/common/lib/xmodule/xmodule/textannotation_module.py @@ -47,8 +47,24 @@ 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")) + 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='', + ) class TextAnnotationModule(AnnotatableFields, XModule): @@ -84,6 +100,7 @@ def student_view(self, context): 'content_html': self.content, 'annotation_storage': self.annotation_storage_url, 'token': retrieve_token(self.user_email, self.annotation_token_secret), + 'diacritic_marks': self.diacritics, } fragment = Fragment(self.system.render_template('textannotation.html', context)) fragment.add_javascript_url("/static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js") From b83e27fc9d79819e3c95319279e1db726c6cf3cb Mon Sep 17 00:00:00 2001 From: lduarte1991 Date: Tue, 27 May 2014 17:37:17 -0400 Subject: [PATCH 3/3] Diacritic Plugin for Annotator Tool: Pull-request Fixes Making sure extension comes after annotator css --- .../xmodule/xmodule/textannotation_module.py | 20 +- .../xmodule/xmodule/videoannotation_module.py | 27 +- .../js/vendor/ova/diacritic-annotator.js | 278 +++++++++++------- lms/envs/common.py | 2 +- lms/templates/textannotation.html | 3 + 5 files changed, 209 insertions(+), 121 deletions(-) diff --git a/common/lib/xmodule/xmodule/textannotation_module.py b/common/lib/xmodule/xmodule/textannotation_module.py index ef27141b1eb1..fe36d917d3cc 100644 --- a/common/lib/xmodule/xmodule/textannotation_module.py +++ b/common/lib/xmodule/xmodule/textannotation_module.py @@ -48,20 +48,20 @@ class AnnotatableFields(object): 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" + 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" + 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", + 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='', ) diff --git a/common/lib/xmodule/xmodule/videoannotation_module.py b/common/lib/xmodule/xmodule/videoannotation_module.py index 72e3d8cab5c2..857ec5fcd9d4 100644 --- a/common/lib/xmodule/xmodule/videoannotation_module.py +++ b/common/lib/xmodule/xmodule/videoannotation_module.py @@ -34,10 +34,29 @@ class AnnotatableFields(object): scope=Scope.settings, default=_('Video Annotation'), ) - sourceurl = String(help=_("The external source URL for the video."), display_name=_("Source URL"), scope=Scope.settings, default="http://video-js.zencoder.com/oceans-clip.mp4") - poster_url = String(help=_("Poster Image URL"), display_name=_("Poster URL"), 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")) + sourceurl = String( + help=_("The external source URL for the video."), + display_name=_("Source URL"), + scope=Scope.settings, default="http://video-js.zencoder.com/oceans-clip.mp4" + ) + poster_url = String( + help=_("Poster Image URL"), + display_name=_("Poster URL"), + 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") + ) class VideoAnnotationModule(AnnotatableFields, XModule): '''Video Annotation Module''' diff --git a/common/static/js/vendor/ova/diacritic-annotator.js b/common/static/js/vendor/ova/diacritic-annotator.js index 87456096acaf..74ec051fe291 100644 --- a/common/static/js/vendor/ova/diacritic-annotator.js +++ b/common/static/js/vendor/ova/diacritic-annotator.js @@ -18,80 +18,101 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -var _ref, - __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +var _ref; +var __bind = function(fn, me){ + return function(){ + return fn.apply(me, arguments); + }; +}; +var __hasProp = {}.hasOwnProperty; +var __extends = function(child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) + child[key] = parent[key]; + } + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.__super__ = parent.prototype; + return child; +}; Annotator.Plugin.Diacritics = (function(_super) { - __extends(Diacritics, _super); - - //Options will include diacritic name, picture used, baseline + __extends(Diacritics, _super); + + //Options will include diacritic name, picture used, baseline Diacritics.prototype.options = null; Diacritics.prototype.diacriticmarks = null; - - //initiate diacritics elements - function Diacritics(element,options) { - this.pluginSubmit = __bind(this.pluginSubmit, this); - this.updateDiacritics = __bind(this.updateDiacritics, this); + + /** + * Declares all the functions and variables that the plugin will need. + * @constructor + */ + function Diacritics(element,options) { + this.pluginSubmit = __bind(this.pluginSubmit, this); + this.updateDiacritics = __bind(this.updateDiacritics, this); this.updateViewer = __bind(this.updateViewer, this); this.getDiacritics = __bind(this.getDiacritics, this); this.getPos = __bind(this.getPos, this); - this.putMarkatLocation = __bind(this.putMarkatLocation, this); - this.updateEditorForDiacritics = __bind(this.updateEditorForDiacritics, this); + this.putMarkAtLocation = __bind(this.putMarkAtLocation, this); + this.updateEditorForDiacritics = + __bind(this.updateEditorForDiacritics, this); this.options = options; this.diacriticmarks = this.getDiacritics(); - _ref = Diacritics.__super__.constructor.apply(this, arguments); - return _ref; - } - + _ref = Diacritics.__super__.constructor.apply(this, arguments); + return _ref; + } + //example variables to be used to receive input in the annotator view - Diacritics.prototype.field = null; - Diacritics.prototype.input = null; + Diacritics.prototype.field = null; + Diacritics.prototype.input = null; - //this function will initialize the plug in - Diacritics.prototype.pluginInit = function() { - console.log("Diacritics-pluginInit"); - + /** + * Initalizes the Plug-in for diacritic marks. It adds in the field for the mark + * and sets up listeners from the Annotator.js file to make changes as needed + */ + Diacritics.prototype.pluginInit = function() { //Check that annotator is working - if (!Annotator.supported()) { - return; - } - var di = this.diacriticmarks; - + if (!Annotator.supported()) { + return; + } + var di = this.diacriticmarks; + //-- Editor var self = this; if(di != 'undefined'){ $.each(di,function(item){ self.field = self.annotator.editor.addField({ - type: 'checkbox', //options (textarea,input,select,checkbox) - label: Annotator._t(item), - submit: self.pluginSubmit, - }); + //options (textarea,input,select,checkbox) + type: 'checkbox', + label: Annotator._t(item), + submit: self.pluginSubmit, + }); + }); + + //-- Viewer + this.annotator.viewer.addField({ + load: this.updateViewer, }); - - //-- Viewer - var newview = this.annotator.viewer.addField({ - load: this.updateViewer, - }); this.annotator.subscribe('annotationsLoaded', this.updateDiacritics); this.annotator.subscribe('annotationUploaded', this.updateDiacritics); - this.annotator.subscribe('annotationDeleted', this.updateDiacritics); + this.annotator.subscribe('annotationDeleted', this.updateDiacritics); this.annotator.subscribe('annotationUpdated', this.updateDiacritics); this.annotator.subscribe('annotationEditorShown', this.updateEditorForDiacritics, this.field); - var self = this; - $(window).resize(function() { - self.updateDiacritics(); - }); + $(window).resize(this.updateDiacritics.bind(this)); } - return this.input = $(this.field).find(':input'); - }; + return this.input = $(this.field).find(':input'); + }; - //The following function is run when a person hits submit. + /** + * Adds or removes tag from checked/unchecked boxes of diacritics available + * @param field {Object} - element which holds editor + * @param annotation {Object} - object that contains annotation information from database + */ Diacritics.prototype.pluginSubmit = function(field, annotation) { var checkedItems = $(this.field).find(':input'); var self = this; @@ -100,105 +121,150 @@ Annotator.Plugin.Diacritics = (function(_super) { var index = $.inArray(checkedItems[item].placeholder, annotation.tags); if(index != -1){ annotation.tags.splice(index, 1); - if (typeof $($('.annotator-wrapper')[0]).find('div.'+annotation.id)[0] != 'undefined'){ - $($('.annotator-wrapper')[0]).find('div.'+annotation.id)[0].remove(); - } else { - $($('.annotator-wrapper')[0]).find('div.undefined')[0].remove(); + var annotatorWrapper = $('.annotator-wrapper').first(); + var element = annotatorWrapper.find('div.' + annotation.id); + + if(!element.length){ + element = annotatorWrapper.find('div.undefined'); } + + element.remove(); } - if(checkedItems[item].checked == true){ + if(checkedItems[item].checked === true){ annotation.tags.unshift(checkedItems[item].placeholder); - self.putMarkatLocation(annotation, checkedItems[item].placeholder); + self.putMarkAtLocation(annotation, checkedItems[item].placeholder); } } else { - if(checkedItems[item].checked == true){ - annotation['tags'] = [checkedItems[item].placeholder]; - self.putMarkatLocation(annotation, checkedItems[item].placeholder); + if(checkedItems[item].checked === true){ + annotation.tags = [checkedItems[item].placeholder]; + self.putMarkAtLocation(annotation, checkedItems[item].placeholder); } } }); - - } + + }; - Diacritics.prototype.putMarkatLocation = function (annotation, mark){ + /** + * Draws the mark above a specific annotation + * @param annotation {Object} - location where mark should go + * @param mark {string}- type of mark that should go above annotation + */ + Diacritics.prototype.putMarkAtLocation = function (annotation, mark){ var loc = this.getPos(annotation.highlights[0]); var alignment = this.diacriticmarks[mark][1]; var imgurl = this.diacriticmarks[mark][0]; - var newdiv = document.createElement('div'); - var className = 'mark ' + annotation.id; - newdiv.setAttribute('class',className); - if(alignment == 'top'){ - $(newdiv).css('top',""+(loc.y-5)+"px"); - } else if(alignment == 'bottom'){ - $(newdiv).css('top',""+(loc.y+loc.height-5)+"px"); - } else{ - $(newdiv).css('top',""+loc.y+"px"); + var top; + switch(alignment){ + case 'top': + top = (loc.y-5); + break; + case 'bottom': + top = (loc.y + loc.height-5); + break; + default: + top = loc.y; } - $(newdiv).css('left',""+(loc.x+(loc.width/2.0)-5)+"px"); - $(newdiv).css('background-image', 'url('+imgurl+')'); - $('.annotator-wrapper')[0].appendChild(newdiv); - } - + $('
').addClass('mark ' + annotation.id).css({ + 'top': top, + 'left': loc.x + (0.5 * loc.width) - 5, + 'background-image': 'url(' + imgurl +')', + }).appendTo('.annotator-wrapper'); + }; + + /** + * Gets the Diacritics from the instantiation in studio + * @returns An object with the diacritics instantiated + */ Diacritics.prototype.getDiacritics = function(){ + var diacritics = {}; + var diacriticsList; if(typeof this.options.diacritics != 'undefined'){ - var self = this; - var final = new Object(), prelim = this.options.diacritics.split(","); - prelim.forEach(function(item){ + diacriticsList = this.options.diacritics.split(","); + $.each(diacriticsList, function(key, item){ var temp = item.split(";"); - if (temp.length <3) {return undefined;} - final[temp[0]] = [temp[1],temp[2]]; + if (temp.length > 2) { + diacritics[temp[0]] = [temp[1], temp[2]]; + } }); - return final; } - console.log("Was undefined"); - return undefined; - } + return diacritics; + }; + /** + * Gets the position of a specific element given the wrapper + * @param el {Object} - element you are trying to get the position of + */ Diacritics.prototype.getPos = function(el) { - var off = $(el).offset(); - return {x: off.left-$($('.annotator-wrapper')[0]).offset().left, y: off.top-$($('.annotator-wrapper')[0]).offset().top, width:$(el).width(), height:$(el).height()}; - } + var element = $(el), + elementOffset = element.offset(), + annotatorOffset = $('.annotator-wrapper').offset(); + + return { + x: elementOffset.left - annotatorOffset.left, + y: elementOffset.top - annotatorOffset.top, + width: element.width(), + height: element.height() + }; + }; + /** + * Redraws the marks above annotations by cycling through tags + */ Diacritics.prototype.updateDiacritics = function(){ $('.mark').remove(); - var annotations = this.annotator.plugins['Store'].annotations; + var annotations = this.annotator.plugins.Store.annotations; var self = this; - annotations.forEach(function(ann){ - $.each(self.diacriticmarks, function(item){ - if($.inArray(item, ann.tags) != -1){ - self.putMarkatLocation(ann, item); + $.each(annotations, function(key, annotation){ + $.each(self.diacriticmarks, function(tag){ + if($.inArray(tag, annotation.tags) != -1){ + self.putMarkAtLocation(annotation, tag); } }); }); - } + }; - Diacritics.prototype.updateViewer = function(field,annotation){ + /** + * Removes unnecessary field that Annotator automatically adds to popup + * @param {Object} field - the html element that represents the popup + * @param {Object} annotation - the annotation element that holds metadata + */ + Diacritics.prototype.updateViewer = function(field, annotation){ $(field).remove(); - } - - Diacritics.prototype.updateEditorForDiacritics = function(field, annotation){ + }; + + /** + * Function for adding Diacritic choices to the annotator popup + * @param {Object} field - the html element that represents the popup + * @param {Object} annotation - the annotation element that holds metadata + */ + Diacritics.prototype.updateEditorForDiacritics = + function(field, annotation){ + + // if no tags are present, no need to go through this if (typeof annotation.tags == 'undefined'){ return; } - var self = this; var inputItems = $(this.field).find(':input'); - var dictOfItems = {} - $.each(inputItems, function(item){ - inputItems[item].checked = false; - dictOfItems[inputItems[item].placeholder] = inputItems[item]; + var dictOfItems = {}; + var self = this; + + // add each diacritic mark to a dictionary and default to off + $.each(inputItems, function(key,item){ + item.checked = false; + dictOfItems[item.placeholder] = item; }); - annotation.tags.forEach(function(tag){ - if(typeof self.diacriticmarks[tag] != 'undefined'){ + + // match tags to diacritics and check off the ones that are true + $.each(annotation.tags, function(key,tag){ + if(self.diacriticmarks[tag]){ dictOfItems[tag].checked = true; } }); - } - - - + }; + return Diacritics; -})(Annotator.Plugin); \ No newline at end of file +})(Annotator.Plugin); diff --git a/lms/envs/common.py b/lms/envs/common.py index 815d0756074e..c7b7c69ee1f7 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -871,8 +871,8 @@ 'css/vendor/jquery.qtip.min.css', 'css/vendor/responsive-carousel/responsive-carousel.css', 'css/vendor/responsive-carousel/responsive-carousel.slide.css', - 'css/vendor/ova/edx-annotator.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', diff --git a/lms/templates/textannotation.html b/lms/templates/textannotation.html index 5d97ac11c86f..43f122e05087 100644 --- a/lms/templates/textannotation.html +++ b/lms/templates/textannotation.html @@ -148,6 +148,9 @@ highlightTags:{ tag: "${tag}", }, + diacriticMarks:{ + diacritics: "${diacritic_marks}" + } }, optionsVideoJS: {techOrder: ["html5","flash","youtube"]}, optionsRS: {},