diff --git a/AUTHORS b/AUTHORS index 60fdb8d4c4..9249c6353b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -147,3 +147,4 @@ David Bodor Sébastien Hinderer Kristin Stephens Ben Patterson +Luis Duarte diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c9d2bd1d8f..75132000c1 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -754,3 +754,5 @@ LMS: Option to email students when enroll/un-enroll them. Blades: Added WAI-ARIA markup to the video player controls. These are now fully accessible by screen readers. + +Common: Added advanced_module for annotating images to go with the ones for text and videos. diff --git a/common/lib/xmodule/xmodule/annotator_mixin.py b/common/lib/xmodule/xmodule/annotator_mixin.py index 9c4875e462..aa597702db 100644 --- a/common/lib/xmodule/xmodule/annotator_mixin.py +++ b/common/lib/xmodule/xmodule/annotator_mixin.py @@ -50,6 +50,6 @@ class MLStripper(HTMLParser): def html_to_text(html): "strips the html tags off of the text to return plaintext" - htmlStripper = MLStripper() - htmlStripper.feed(html) - return htmlStripper.get_data() + htmlstripper = MLStripper() + htmlstripper.feed(html) + return htmlstripper.get_data() diff --git a/common/lib/xmodule/xmodule/annotator_token.py b/common/lib/xmodule/xmodule/annotator_token.py index 501917cc3d..80ad30cc9b 100644 --- a/common/lib/xmodule/xmodule/annotator_token.py +++ b/common/lib/xmodule/xmodule/annotator_token.py @@ -23,8 +23,8 @@ def retrieve_token(userid, secret): dtnow = datetime.datetime.now() dtutcnow = datetime.datetime.utcnow() delta = dtnow - dtutcnow - newhour, newmin = divmod((delta.days * 24 * 60 * 60 + delta.seconds + 30) // 60, 60) # pylint: disable=E1103 - newtime = "%s%+02d:%02d" % (dtnow.isoformat(), newhour, newmin) # pylint: disable=E1103 + newhour, newmin = divmod((delta.days * 24 * 60 * 60 + delta.seconds + 30) // 60, 60) + newtime = "%s%+02d:%02d" % (dtnow.isoformat(), newhour, newmin) # uses the issued time (UTC plus timezone), the consumer key and the user's email to maintain a # federated system in the annotation backend server custom_data = {"issuedAt": newtime, "consumerKey": secret, "userId": userid, "ttl": 86400} diff --git a/common/lib/xmodule/xmodule/imageannotation_module.py b/common/lib/xmodule/xmodule/imageannotation_module.py index 31f86a0f82..9d5ab94083 100644 --- a/common/lib/xmodule/xmodule/imageannotation_module.py +++ b/common/lib/xmodule/xmodule/imageannotation_module.py @@ -1,4 +1,3 @@ -# pylint: disable=W0223 """ Module for Image annotations using annotator. """ @@ -48,8 +47,18 @@ 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") + 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 ImageAnnotationModule(AnnotatableFields, XModule): @@ -96,7 +105,7 @@ class ImageAnnotationModule(AnnotatableFields, XModule): return self.system.render_template('imageannotation.html', context) -class ImageAnnotationDescriptor(AnnotatableFields, RawDescriptor): +class ImageAnnotationDescriptor(AnnotatableFields, RawDescriptor): # pylint: disable=abstract-method ''' Image annotation descriptor ''' module_class = ImageAnnotationModule mako_template = "widgets/raw-edit.html" diff --git a/common/lib/xmodule/xmodule/tests/test_annotator_mixin.py b/common/lib/xmodule/xmodule/tests/test_annotator_mixin.py index a33c05c32d..38a55ecd8f 100644 --- a/common/lib/xmodule/xmodule/tests/test_annotator_mixin.py +++ b/common/lib/xmodule/xmodule/tests/test_annotator_mixin.py @@ -23,17 +23,18 @@ class HelperFunctionTest(unittest.TestCase): def test_get_instructions(self): """ - Function takes in an input of a specific xml string with surrounding instructions tags and returns a valid html string. + Function takes in an input of a specific xml string with surrounding instructions + tags and returns a valid html string. """ xmltree = etree.fromstring(self.sample_xml) expected_xml = u"

Helper Test Instructions.

" - actual_xml = get_instructions(xmltree) # pylint: disable=W0212 + actual_xml = get_instructions(xmltree) self.assertIsNotNone(actual_xml) self.assertEqual(expected_xml.strip(), actual_xml.strip()) xmltree = etree.fromstring('foo') - actual = get_instructions(xmltree) # pylint: disable=W0212 + actual = get_instructions(xmltree) self.assertIsNone(actual) def test_get_extension(self): @@ -42,8 +43,8 @@ class HelperFunctionTest(unittest.TestCase): """ expectedyoutube = 'video/youtube' expectednotyoutube = 'video/mp4' - result1 = get_extension(self.sample_sourceurl) # pylint: disable=W0212 - result2 = get_extension(self.sample_youtubeurl) # pylint: disable=W0212 + result1 = get_extension(self.sample_sourceurl) + result2 = get_extension(self.sample_youtubeurl) self.assertEqual(expectedyoutube, result2) self.assertEqual(expectednotyoutube, result1) diff --git a/common/lib/xmodule/xmodule/tests/test_annotator_token.py b/common/lib/xmodule/xmodule/tests/test_annotator_token.py index 49f376436b..dea01496f8 100644 --- a/common/lib/xmodule/xmodule/tests/test_annotator_token.py +++ b/common/lib/xmodule/xmodule/tests/test_annotator_token.py @@ -12,9 +12,12 @@ class TokenRetriever(unittest.TestCase): """ def test_token(self): """ - Test for the token generator. Give an a random username and secret token, it should create the properly encoded string of text. + Test for the token generator. Give an a random username and secret token, + it should create the properly encoded string of text. """ expected = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3N1ZWRBdCI6ICIyMDE0LTAyLTI3VDE3OjAwOjQyLjQwNjQ0MSswOjAwIiwgImNvbnN1bWVyS2V5IjogImZha2Vfc2VjcmV0IiwgInVzZXJJZCI6ICJ1c2VybmFtZSIsICJ0dGwiOiA4NjQwMH0.Dx1PoF-7mqBOOSGDMZ9R_s3oaaLRPnn6CJgGGF2A5CQ" response = retrieve_token("username", "fake_secret") + + # because the middle hashes are dependent on time, conly the header and footer are checked for secret key self.assertEqual(expected.split('.')[0], response.split('.')[0]) self.assertNotEqual(expected.split('.')[2], response.split('.')[2]) diff --git a/common/lib/xmodule/xmodule/tests/test_imageannotation.py b/common/lib/xmodule/xmodule/tests/test_imageannotation.py index c3cb9aaef5..c19ffc25d0 100644 --- a/common/lib/xmodule/xmodule/tests/test_imageannotation.py +++ b/common/lib/xmodule/xmodule/tests/test_imageannotation.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -"Test for Image Annotation Xmodule functional logic." +"""Test for Image Annotation Xmodule functional logic.""" import unittest from mock import Mock @@ -61,12 +61,12 @@ class ImageAnnotationModuleTestCase(unittest.TestCase): xmltree = etree.fromstring(self.sample_xml) expected_xml = u"

Image Test Instructions.

" - actual_xml = self.mod._extract_instructions(xmltree) # pylint: disable=W0212 + actual_xml = self.mod._extract_instructions(xmltree) # pylint: disable=protected-access self.assertIsNotNone(actual_xml) self.assertEqual(expected_xml.strip(), actual_xml.strip()) xmltree = etree.fromstring('foo') - actual = self.mod._extract_instructions(xmltree) # pylint: disable=W0212 + actual = self.mod._extract_instructions(xmltree) # pylint: disable=protected-access self.assertIsNone(actual) def test_get_html(self): diff --git a/common/lib/xmodule/xmodule/tests/test_videoannotation.py b/common/lib/xmodule/xmodule/tests/test_videoannotation.py index 533ea80203..410d39d4b1 100644 --- a/common/lib/xmodule/xmodule/tests/test_videoannotation.py +++ b/common/lib/xmodule/xmodule/tests/test_videoannotation.py @@ -66,6 +66,6 @@ class VideoAnnotationModuleTestCase(unittest.TestCase): """ Tests to make sure variables passed in truly exist within the html once it is all rendered. """ - context = self.mod.get_html() # pylint: disable=W0212 + context = self.mod.get_html() for key in ['display_name', 'instructions_html', 'sourceUrl', 'typeSource', 'poster', 'annotation_storage']: self.assertIn(key, context) diff --git a/common/lib/xmodule/xmodule/videoannotation_module.py b/common/lib/xmodule/xmodule/videoannotation_module.py index 1431b03b25..f5bd7d3e93 100644 --- a/common/lib/xmodule/xmodule/videoannotation_module.py +++ b/common/lib/xmodule/xmodule/videoannotation_module.py @@ -68,9 +68,9 @@ class VideoAnnotationModule(AnnotatableFields, XModule): """ Removes from the xmltree and returns them as a string, otherwise None. """ return get_instructions(xmltree) - def _get_extension(self, srcurl): + def _get_extension(self, src_url): ''' get the extension of a given url ''' - return get_extension(srcurl) + return get_extension(src_url) def get_html(self): """ Renders parameters to template. """ diff --git a/common/static/css/vendor/ova/richText-annotator.css b/common/static/css/vendor/ova/richText-annotator.css index 4cadb8e055..bf384fa18d 100644 --- a/common/static/css/vendor/ova/richText-annotator.css +++ b/common/static/css/vendor/ova/richText-annotator.css @@ -16,10 +16,6 @@ font-style: italic; } -.annotator-wrapper .mce-container { - z-index: 3000000000!important; /*To fix full-screen problems*/ -} - .mce-container-body { min-width: 400px; } @@ -29,6 +25,10 @@ min-width: 400px; } +.mce-floatpanel { + z-index: 700000000!important; +} + div.mce-tinymce.mce-container.mce-panel { min-width:400px; } diff --git a/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js b/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js index 0fdd10b70a..d8c2f595c0 100644 --- a/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js +++ b/common/static/js/vendor/ova/OpenSeaDragonAnnotation.js @@ -18,48 +18,48 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ (function($) { - $.Viewer.prototype.annotation = function(options) { - //-- wait for plugins --// - var wrapper = jQuery('.annotator-wrapper').parent()[0], - annotator = jQuery.data(wrapper, 'annotator'), - self = this, - isOpenViewer = false; - - this.addHandler("open", function() { - isOpenViewer = true; - if (typeof self.annotationInstance!='undefined') - self.annotationInstance.refreshDisplay(); - }); - - - annotator - //-- Finished the Annotator DOM - .subscribe("annotationsLoaded", function (annotations){ - if (!self.annotationInstance) { - self.annotationInstance = new $._annotation({ - viewer: self, - annotator: annotator, - }); - annotator.osda = self.annotationInstance; - //Wait until viewer is opened - function refreshDisplay(){ - if(!isOpenViewer){ - setTimeout(refreshDisplay,200); - }else{ - self.annotationInstance.refreshDisplay(); - } - } - refreshDisplay(); - } else { - self.annotationInstance.refreshDisplay(); - } - }); - }; - // INIT annotation - $._annotation = function(options) { - //options - options = options || {}; - if (!options.viewer) { + $.Viewer.prototype.annotation = function(options) { + //-- wait for plugins --// + var wrapper = jQuery('.annotator-wrapper').parent()[0], + annotator = jQuery.data(wrapper, 'annotator'), + self = this, + isOpenViewer = false; + + this.addHandler("open", function() { + isOpenViewer = true; + if (typeof self.annotationInstance!='undefined') + self.annotationInstance.refreshDisplay(); + }); + + + annotator + //-- Finished the Annotator DOM + .subscribe("annotationsLoaded", function (annotations){ + if (!self.annotationInstance) { + self.annotationInstance = new $._annotation({ + viewer: self, + annotator: annotator, + }); + annotator.osda = self.annotationInstance; + //Wait until viewer is opened + function refreshDisplay(){ + if(!isOpenViewer){ + setTimeout(refreshDisplay,200); + }else{ + self.annotationInstance.refreshDisplay(); + } + } + refreshDisplay(); + } else { + self.annotationInstance.refreshDisplay(); + } + }); + }; + // INIT annotation + $._annotation = function(options) { + //options + options = options || {}; + if (!options.viewer) { throw new Error("A viewer must be specified."); } @@ -69,457 +69,458 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. this.options = options; this.isAnnotating = false; //If the user is annotating this.isDrawing = false; //if the user is drawing something + this.rectPosition = undefined; - //Init - this.init(); - }; - - //-- Methods - $._annotation.prototype = { - init: function(){ - var viewer = this.viewer; - - //create Buttons - this._createNewButton(); - - /* canvas Events */ - //- Bind canvas functions - var onCanvasMouseDown = this.__bind(this._onCanvasMouseDown,this), - onCanvasMouseMove = this.__bind(this._onCanvasMouseMove,this), - onDocumentMouseUp = this.__bind(this._onDocumentMouseUp,this); - - //- Add canvas events - $.addEvent(viewer.canvas, "mousedown", onCanvasMouseDown, true); - $.addEvent(viewer.canvas, "mousemove", onCanvasMouseMove, true); - $.addEvent(document, "mouseup", onDocumentMouseUp, true); - - //Viewer events - var self = this; - }, - newAnnotation:function(){ - var annotator = this.annotator; - - //This variable is to say the editor that we want create an image annotation - annotator.editor.OpenSeaDragon = this.viewer.id; - - annotator.adder.show(); - - this._setOverShape(annotator.adder); - - //Open a new annotator dialog - annotator.onAdderClick(); - }, - editAnnotation: function(annotation,editor){ - //This will be usefull when we are going to edit an annotation. - if (this._isOpenSeaDragon(annotation)){ - //this.hideDisplay(); - var editor = editor || this.annotator.editor; - - //set the editor over the range slider - this._setOverShape(editor.element); - editor.checkOrientation(); - - //This variable is to say the editor that we want create an image annotation - editor.OpenSeaDragon = this.viewer.id; - } - }, - refreshDisplay: function(){ - var allannotations = this.annotator.plugins['Store'].annotations; - var annotator = this.annotator; - - //Sort by date the Array - this._sortByDate(allannotations); - - //remove all the overlays - this.viewer.drawer.clearOverlays(); - - for (var item in allannotations) { - var an = allannotations[item]; - - //check if the annotation is an OpenSeaDragon annotation - if (this._isOpenSeaDragon(an)) - this.drawRect(an); - annotator.publish('colorizeHighlight', [an]); - }; - }, - modeAnnotation:function(e){ - this._reset(); - var viewer = this.viewer; - if (!this.isAnnotating){ - jQuery('.openseadragon1').css('cursor', 'crosshair'); - jQuery('.openseadragon1').css('border', '2px solid rgb(51,204,102)'); - e.eventSource.imgGroup.src = this.resolveUrl( viewer.prefixUrl,"newan_hover.png"); - e.eventSource.imgRest.src = this.resolveUrl( viewer.prefixUrl,"newan_hover.png"); - e.eventSource.imgHover.src = this.resolveUrl( viewer.prefixUrl,"newan_grouphover.png"); - }else{ - jQuery('.openseadragon1').css('cursor', 'all-scroll'); - jQuery('.openseadragon1').css('border', 'inherit'); - e.eventSource.imgGroup.src = this.resolveUrl( viewer.prefixUrl,"newan_grouphover.png"); - e.eventSource.imgRest.src = this.resolveUrl( viewer.prefixUrl,"newan_rest.png"); - e.eventSource.imgHover.src = this.resolveUrl( viewer.prefixUrl,"newan_hover.png"); - } - this.isAnnotating = !this.isAnnotating?true:false; - }, - drawRect:function(an){ - if (typeof an.rangePosition!='undefined'){ - var span = document.createElement('span'), - rectPosition = an.rangePosition; - //Span - span.className = "annotator-hl"; - span.style.border = '1px solid rgba(0,0,0,0.5)'; - var onAnnotationMouseMove = this.__bind(this._onAnnotationMouseMove,this), - onAnnotationClick = this.__bind(this._onAnnotationClick,this); - $.addEvent(span, "mousemove", onAnnotationMouseMove, true); - $.addEvent(span, "click", onAnnotationClick, true); - - //Set the object in the div - jQuery.data(span, 'annotation', an); - //Add the highlights to the annotation - an.highlights = jQuery(span); - - var olRect = new OpenSeadragon.Rect(rectPosition.left, rectPosition.top, rectPosition.width, rectPosition.height); - return this.viewer.drawer.addOverlay({ - element: span, - location: olRect, - placement: OpenSeadragon.OverlayPlacement.TOP_LEFT - }); - } - return false; - }, - //Change object(this.rectPosition)the rectangle Position using div element(this.rect) - setRectPosition:function(){ - var left = parseInt(this.rect.style.left), - top = parseInt(this.rect.style.top), - width = parseInt(this.rect.style.left)+parseInt(this.rect.style.width), - height = parseInt(this.rect.style.top)+parseInt(this.rect.style.height), - startPoint = new $.Point(left,top), - endPoint = new $.Point(width,height); - this.rectPosition = {left:this._physicalToLogicalXY(startPoint).x, - top:this._physicalToLogicalXY(startPoint).y, - width:this._physicalToLogicalXY(endPoint).x-this._physicalToLogicalXY(startPoint).x, - height:this._physicalToLogicalXY(endPoint).y-this._physicalToLogicalXY(startPoint).y - }; - }, - /* Handlers */ - _onCanvasMouseDown: function(event,seft) { - if (this.isAnnotating){ - var viewer = this.viewer; - event.preventDefault(); - - //reset the display - this._reset(); - - //set mode drawing - this.isDrawing = true; - - //Create rect element - var mouse = $.getMousePosition( event ), - elementPosition = $.getElementPosition(viewer.canvas), - position = mouse.minus( elementPosition ); - viewer.innerTracker.setTracking(false); - this.rect = document.createElement('div'); - this.rect.style.background = 'rgba(0,0,0,0.25)'; - this.rect.style.border = '1px solid rgba(0,0,0,0.5)'; - this.rect.style.position = 'absolute'; - this.rect.className = 'DrawingRect'; - //set the initial position - this.rect.style.top = position.y+"px"; - this.rect.style.left = position.x+"px"; - this.rect.style.width = "1px"; - this.rect.style.height = "1px"; - - //save the start Position - this.startPosition = position; - //save rectPosition as initial rectangle parameter to Draw in the canvas - this.setRectPosition(); - - //append Child to the canvas - viewer.canvas.appendChild(this.rect); - } - }, - _onCanvasMouseMove: function(event) { - if (this.isAnnotating && this.isDrawing){ - var viewer = this.viewer; - - //Calculate the new end position - var mouse = $.getMousePosition( event ), - elementPosition = $.getElementPosition(viewer.canvas), - endPosition = mouse.minus( elementPosition ); - //retrieve start position - var startPosition = this.startPosition; - - var newWidth= endPosition.x-startPosition.x, - newHeight =endPosition.y-startPosition.y; - - //Set new position - this.rect.style.width = (newWidth<0) ? (-1*newWidth) +'px' : newWidth +'px'; - this.rect.style.left = (newWidth<0) ? (startPosition.x + newWidth) +'px' : startPosition.x +'px'; - this.rect.style.height = (newHeight<0) ? (-1*newHeight) +'px' : newHeight +'px'; - this.rect.style.top = (newHeight<0) ? (startPosition.y + newHeight) +'px' : startPosition.y +'px'; - - //Modify the rectPosition with the new this.rect values - this.setRectPosition(); - - //Show adder and hide editor - this.annotator.editor.element[0].style.display = 'none'; - this._setOverShape(this.annotator.adder); - } - }, - _onDocumentMouseUp: function() { - if (this.isAnnotating && this.isDrawing){ - var viewer = this.viewer; - - viewer.innerTracker.setTracking(true); - this.isDrawing = false; - - //Set the new position for the rectangle - this.setRectPosition(); - - //Open Annotator editor - this.newAnnotation(); - - //Hide adder and show editor - this.annotator.editor.element[0].style.display = 'block'; - this._setOverShape(this.annotator.editor.element); - this.annotator.editor.checkOrientation(); - } - }, - _onAnnotationMouseMove: function(event){ - var annotator = this.annotator; - var elem = jQuery(event.target).parents('.annotator-hl').andSelf(); - //if there is a opened annotation then show the new annotation mouse over - if (typeof annotator!='undefined' && elem.hasClass("annotator-hl") && !this.isDrawing){ - //hide the last open viewer - annotator.viewer.hide(); - //get the annotation over the mouse - var annotations = jQuery(event.target.parentNode).find('.annotator-hl').map(function() { - var self = jQuery(this), - offset = self.offset(), - l = offset.left, - t = offset.top, - h = self.height(), - w = self.width(), - x = $.getMousePosition(event).x, - y = $.getMousePosition(event).y; + //Init + this.init(); + }; + + //-- Methods + $._annotation.prototype = { + init: function(){ + var viewer = this.viewer; + + //create Buttons + this._createNewButton(); + + /* canvas Events */ + //- Bind canvas functions + var onCanvasMouseDown = this.__bind(this._onCanvasMouseDown,this); + var onCanvasMouseMove = this.__bind(this._onCanvasMouseMove,this); + var onDocumentMouseUp = this.__bind(this._onDocumentMouseUp,this); + + //- Add canvas events + $.addEvent(viewer.canvas, "mousedown", onCanvasMouseDown, true); + $.addEvent(viewer.canvas, "mousemove", onCanvasMouseMove, true); + $.addEvent(document, "mouseup", onDocumentMouseUp, true); + + //Viewer events + var self = this; + }, + newAnnotation:function(){ + var annotator = this.annotator; + + //This variable is to say the editor that we want create an image annotation + annotator.editor.OpenSeaDragon = this.viewer.id; + + annotator.adder.show(); + + this._setOverShape(annotator.adder); + + //Open a new annotator dialog + annotator.onAdderClick(); + }, + editAnnotation: function(annotation,editor){ + //This will be usefull when we are going to edit an annotation. + if (this._isOpenSeaDragon(annotation)){ + //this.hideDisplay(); + var editor = editor || this.annotator.editor; + + //set the editor over the range slider + this._setOverShape(editor.element); + editor.checkOrientation(); + + //This variable is to say the editor that we want create an image annotation + editor.OpenSeaDragon = this.viewer.id; + } + }, + refreshDisplay: function(){ + var allannotations = this.annotator.plugins['Store'].annotations; + var annotator = this.annotator; + + //Sort by date the Array + this._sortByDate(allannotations); + + //remove all the overlays + this.viewer.drawer.clearOverlays(); + + for (var item in allannotations) { + var an = allannotations[item]; + + //check if the annotation is an OpenSeaDragon annotation + if (this._isOpenSeaDragon(an)) + this.drawRect(an); + annotator.publish('colorizeHighlight', [an]); + }; + }, + modeAnnotation:function(e){ + this._reset(); + var viewer = this.viewer; + if (!this.isAnnotating){ + jQuery('.openseadragon1').css('cursor', 'crosshair'); + jQuery('.openseadragon1').css('border', '2px solid rgb(51,204,102)'); + e.eventSource.imgGroup.src = this.resolveUrl( viewer.prefixUrl,"newan_hover.png"); + e.eventSource.imgRest.src = this.resolveUrl( viewer.prefixUrl,"newan_hover.png"); + e.eventSource.imgHover.src = this.resolveUrl( viewer.prefixUrl,"newan_grouphover.png"); + }else{ + jQuery('.openseadragon1').css('cursor', 'all-scroll'); + jQuery('.openseadragon1').css('border', 'inherit'); + e.eventSource.imgGroup.src = this.resolveUrl( viewer.prefixUrl,"newan_grouphover.png"); + e.eventSource.imgRest.src = this.resolveUrl( viewer.prefixUrl,"newan_rest.png"); + e.eventSource.imgHover.src = this.resolveUrl( viewer.prefixUrl,"newan_hover.png"); + } + this.isAnnotating = !this.isAnnotating?true:false; + }, + drawRect:function(an){ + if (typeof an.rangePosition!='undefined'){ + var span = document.createElement('span'); + var rectPosition = an.rangePosition; + //Span + span.className = "annotator-hl"; + span.style.border = '1px solid rgba(0,0,0,0.5)'; + var onAnnotationMouseMove = this.__bind(this._onAnnotationMouseMove,this); + var onAnnotationClick = this.__bind(this._onAnnotationClick,this); + $.addEvent(span, "mousemove", onAnnotationMouseMove, true); + $.addEvent(span, "click", onAnnotationClick, true); + + //Set the object in the div + jQuery.data(span, 'annotation', an); + //Add the highlights to the annotation + an.highlights = jQuery(span); + + var olRect = new OpenSeadragon.Rect(rectPosition.left, rectPosition.top, rectPosition.width, rectPosition.height); + return this.viewer.drawer.addOverlay({ + element: span, + location: olRect, + placement: OpenSeadragon.OverlayPlacement.TOP_LEFT + }); + } + return false; + }, + //Change object(this.rectPosition)the rectangle Position using div element(this.rect) + setRectPosition:function(){ + var left = parseInt(this.rect.style.left); + var top = parseInt(this.rect.style.top); + var width = parseInt(this.rect.style.left)+parseInt(this.rect.style.width); + var height = parseInt(this.rect.style.top)+parseInt(this.rect.style.height); + var startPoint = new $.Point(left,top); + var endPoint = new $.Point(width,height); + this.rectPosition = {left:this._physicalToLogicalXY(startPoint).x, + top:this._physicalToLogicalXY(startPoint).y, + width:this._physicalToLogicalXY(endPoint).x-this._physicalToLogicalXY(startPoint).x, + height:this._physicalToLogicalXY(endPoint).y-this._physicalToLogicalXY(startPoint).y + }; + }, + /* Handlers */ + _onCanvasMouseDown: function(event,seft) { + if (this.isAnnotating){ + var viewer = this.viewer; + event.preventDefault(); + + //reset the display + this._reset(); + + //set mode drawing + this.isDrawing = true; + + //Create rect element + var mouse = $.getMousePosition( event ); + var elementPosition = $.getElementPosition(viewer.canvas); + var position = mouse.minus( elementPosition ); + viewer.innerTracker.setTracking(false); + this.rect = document.createElement('div'); + this.rect.style.background = 'rgba(0,0,0,0.25)'; + this.rect.style.border = '1px solid rgba(0,0,0,0.5)'; + this.rect.style.position = 'absolute'; + this.rect.className = 'DrawingRect'; + //set the initial position + this.rect.style.top = position.y+"px"; + this.rect.style.left = position.x+"px"; + this.rect.style.width = "1px"; + this.rect.style.height = "1px"; + + //save the start Position + this.startPosition = position; + //save rectPosition as initial rectangle parameter to Draw in the canvas + this.setRectPosition(); + + //append Child to the canvas + viewer.canvas.appendChild(this.rect); + } + }, + _onCanvasMouseMove: function(event) { + if (this.isAnnotating && this.isDrawing){ + var viewer = this.viewer; + + //Calculate the new end position + var mouse = $.getMousePosition( event ); + var elementPosition = $.getElementPosition(viewer.canvas); + var endPosition = mouse.minus( elementPosition ); + //retrieve start position + var startPosition = this.startPosition; + + var newWidth= endPosition.x-startPosition.x; + var newHeight =endPosition.y-startPosition.y; + + //Set new position + this.rect.style.width = (newWidth<0) ? (-1*newWidth) +'px' : newWidth +'px'; + this.rect.style.left = (newWidth<0) ? (startPosition.x + newWidth) +'px' : startPosition.x +'px'; + this.rect.style.height = (newHeight<0) ? (-1*newHeight) +'px' : newHeight +'px'; + this.rect.style.top = (newHeight<0) ? (startPosition.y + newHeight) +'px' : startPosition.y +'px'; + + //Modify the rectPosition with the new this.rect values + this.setRectPosition(); + + //Show adder and hide editor + this.annotator.editor.element[0].style.display = 'none'; + this._setOverShape(this.annotator.adder); + } + }, + _onDocumentMouseUp: function() { + if (this.isAnnotating && this.isDrawing){ + var viewer = this.viewer; + + viewer.innerTracker.setTracking(true); + this.isDrawing = false; + + //Set the new position for the rectangle + this.setRectPosition(); + + //Open Annotator editor + this.newAnnotation(); + + //Hide adder and show editor + this.annotator.editor.element[0].style.display = 'block'; + this._setOverShape(this.annotator.editor.element); + this.annotator.editor.checkOrientation(); + } + }, + _onAnnotationMouseMove: function(event){ + var annotator = this.annotator; + var elem = jQuery(event.target).parents('.annotator-hl').andSelf(); + //if there is a opened annotation then show the new annotation mouse over + if (typeof annotator!='undefined' && elem.hasClass("annotator-hl") && !this.isDrawing){ + //hide the last open viewer + annotator.viewer.hide(); + //get the annotation over the mouse + var annotations = jQuery(event.target.parentNode).find('.annotator-hl').map(function() { + var self = jQuery(this); + var offset = self.offset(); + var l = offset.left; + var t = offset.top; + var h = self.height(); + var w = self.width(); + var x = $.getMousePosition(event).x; + var y = $.getMousePosition(event).y; - var maxx = l + w, - maxy = t + h; - this.style.background = (y <= maxy && y >= t) && (x <= maxx && x >= l)? - 'rgba(12, 150, 0, 0.3)':'rgba(255, 255, 10, 0.3)'; - return (y <= maxy && y >= t) && (x <= maxx && x >= l)? jQuery(this).data("annotation") : null; - }); - //show the annotation in the viewer - var mousePosition = { - top:$.getMousePosition(event).y, - left:$.getMousePosition(event).x, - }; - if (annotations.length>0) annotator.showViewer(jQuery.makeArray(annotations), mousePosition); - } - }, - _onAnnotationClick: function(event){ - var an = jQuery.data(event.target, 'annotation'), - bounds = typeof an.bounds!='undefined'?an.bounds:{}, - currentBounds = this.viewer.drawer.viewport.getBounds(); - if (typeof bounds.x!='undefined') currentBounds.x = bounds.x; - if (typeof bounds.y!='undefined') currentBounds.y = bounds.y; - if (typeof bounds.width!='undefined') currentBounds.width = bounds.width; - if (typeof bounds.height!='undefined') currentBounds.height = bounds.height; - //change the zoom to the saved - this.viewer.drawer.viewport.fitBounds(currentBounds); - }, - _onAnnotationMouseOut: function(event){ - var annotator = this.annotator; - var elem = jQuery(event.target).parents('.annotator-hl').andSelf(); - //if there is a opened annotation then show the new annotation mouse over - if (typeof annotator!='undefined' && elem.hasClass("annotator-hl") && !this.isDrawing){ - /*jQuery(event.target.parentNode).find('.annotator-hl').map(function() { - return this.style.background = 'rgba(255, 255, 10, 0.3)'; - });*/ - } - }, - /* Utilities */ - _sortByDate: function (annotations,type){ - var type = type || 'asc'; //asc => The value [0] will be the most recent date - annotations.sort(function(a,b){ - a = new Date(typeof a.updated!='undefined'?createDateFromISO8601(a.updated):''); - b = new Date(typeof b.updated!='undefined'?createDateFromISO8601(b.updated):''); - if (type == 'asc') - return ba?1:0; - else - return ab?1:0; - }); - }, - _createNewButton:function(){ - var viewer = this.viewer, - onFocusHandler = $.delegate( this, onFocus ), - onBlurHandler = $.delegate( this, onBlur ), - onModeAnnotationHandler = $.delegate( this, this.modeAnnotation ); - /* Buttons */ - var viewer = this.viewer; - var self = this; - viewer.modeAnnotation = new $.Button({ - element: viewer.modeAnnotation ? $.getElement( viewer.modeAnnotation ) : null, - clickTimeThreshold: viewer.clickTimeThreshold, - clickDistThreshold: viewer.clickDistThreshold, - tooltip: "New Annotation", - srcRest: self.resolveUrl( viewer.prefixUrl,"newan_rest.png"), - srcGroup: self.resolveUrl( viewer.prefixUrl,"newan_grouphover.png"), - srcHover: self.resolveUrl( viewer.prefixUrl,"newan_hover.png"), - srcDown: self.resolveUrl( viewer.prefixUrl,"newan_pressed.png"), - onRelease: onModeAnnotationHandler, - onFocus: onFocusHandler, - onBlur: onBlurHandler - }); - - //- Wrapper Annotation Menu - viewer.wrapperAnnotation = new $.ButtonGroup({ - buttons: [ - viewer.modeAnnotation, - ], - 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} - ); - } - }, - _reset: function(){ - //Find and remove DrawingRect. This is the previous rectangle - this._removeElemsByClass('DrawingRect',this.viewer.canvas); - //Show adder and hide editor - this.annotator.editor.element[0].style.display = 'none'; - }, - __bind: function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - // Remove all the elements with a given name inside "inElement" - _removeElemsByClass: function(className,inElement){ - var className = className || '', - inElement = inElement || {}; - divs = inElement.getElementsByClassName(className); - for(var i = 0; i < divs.length; i++) { - divs[i].remove(); - } - }, - //Detect if the annotation is an image annotation - _isOpenSeaDragon: function (an){ - var annotator = this.annotator, - rp = an.rangePosition, - isOpenSeaDragon = (typeof annotator.osda != 'undefined'), - isContainer = (typeof an.target!='undefined' && an.target.container==this.viewer.id ), - isImage = (typeof an.media!='undefined' && an.media=='image'), - isRP = (typeof rp!='undefined'), - isSource = false; - //Save source url - var source = this.viewer.source, - tilesUrl = typeof source.tilesUrl!='undefined'?source.tilesUrl:''; - functionUrl = typeof source.getTileUrl!='undefined'?source.getTileUrl:'', - compareUrl = tilesUrl!=''?tilesUrl:(''+functionUrl).replace(/\s+/g, ' '); - if(isContainer) isSource = (an.target.src == compareUrl); - return (isOpenSeaDragon && isContainer && isImage && isRP && isSource); - }, - /* Annotator Utilities */ - _setOverShape: function(elem){ - //Calculate Point absolute positions - var rectPosition = this.rectPosition || {}, - startPoint = this._logicalToPhysicalXY(new $.Point(rectPosition.left,rectPosition.top)), - endPoint = this._logicalToPhysicalXY(new $.Point(rectPosition.left+rectPosition.width,rectPosition.top+rectPosition.height)); - - //Calculate Point absolute positions - var wrapper = jQuery('.annotator-wrapper')[0], - positionAnnotator = $.getElementPosition(wrapper), - positionCanvas = $.getElementPosition(this.viewer.canvas), - positionAdder = {}; - - //Fix with positionCanvas - startPoint = startPoint.plus(positionCanvas); - endPoint = endPoint.plus(positionCanvas); - - elem[0].style.display = 'block'; //Show the adder - - positionAdder.left = (startPoint.x - positionAnnotator.x) + (endPoint.x - startPoint.x) / 2; - positionAdder.top = (startPoint.y - positionAnnotator.y) + (endPoint.y - startPoint.y) / 2; //It is not necessary fix with - positionAnnotator.y - elem.css(positionAdder); - }, - resolveUrl: function( prefix, url ) { - return prefix ? prefix + url : url; - }, - /* Canvas Utilities */ - // return a point with the values in percentage related to the Image - // point is an object $.Point with the value of the canvas relative coordenates - _physicalToLogicalXY: function(point){ - var point = typeof point!='undefined'?point:{}, - boundX = this.viewer.viewport.getBounds(true).x, - boundY = this.viewer.viewport.getBounds(true).y, - boundWidth = this.viewer.viewport.getBounds(true).width, - boundHeight = this.viewer.viewport.getBounds(true).height, - containerSizeX = this.viewer.viewport.getContainerSize().x, - containerSizeY = this.viewer.viewport.getContainerSize().y, - x = typeof point.x!='undefined'?point.x:0, - y = typeof point.y!='undefined'?point.y:0; - x = boundX + ((x / containerSizeX) * boundWidth); - y = boundY + ((y / containerSizeY) * boundHeight); - return new $.Point(x,y); - }, - // return a point with the values in pixels related to the canvas element - // point is an object $.Point with the value of the Image relative percentage - _logicalToPhysicalXY: function(point){ - var point = typeof point!='undefined'?point:{}, - boundX = this.viewer.viewport.getBounds(true).x, - boundY = this.viewer.viewport.getBounds(true).y, - boundWidth = this.viewer.viewport.getBounds(true).width, - boundHeight = this.viewer.viewport.getBounds(true).height, - containerSizeX = this.viewer.viewport.getContainerSize().x, - containerSizeY = this.viewer.viewport.getContainerSize().y, - x = typeof point.x!='undefined'?point.x:0, - y = typeof point.y!='undefined'?point.y:0; - x = (x - boundX) * containerSizeX / boundWidth; - y = (y - boundY) * containerSizeY / boundHeight; - return new $.Point(x,y); - }, - } - - /* General functions */ - //initiates an animation to hide the controls - function beginControlsAutoHide( viewer ) { - if ( !viewer.autoHideControls ) { - return; - } - viewer.controlsShouldFade = true; - viewer.controlsFadeBeginTime = - $.now() + - viewer.controlsFadeDelay; + var maxx = l + w; + var maxy = t + h; + this.style.background = (y <= maxy && y >= t) && (x <= maxx && x >= l)? + 'rgba(12, 150, 0, 0.3)':'rgba(255, 255, 10, 0.3)'; + return (y <= maxy && y >= t) && (x <= maxx && x >= l)? jQuery(this).data("annotation") : null; + }); + //show the annotation in the viewer + var mousePosition = { + top:$.getMousePosition(event).y, + left:$.getMousePosition(event).x, + }; + if (annotations.length>0) annotator.showViewer(jQuery.makeArray(annotations), mousePosition); + } + }, + _onAnnotationClick: function(event){ + var an = jQuery.data(event.target, 'annotation'); + var bounds = typeof an.bounds!='undefined'?an.bounds:{}; + var currentBounds = this.viewer.drawer.viewport.getBounds(); + if (typeof bounds.x!='undefined') currentBounds.x = bounds.x; + if (typeof bounds.y!='undefined') currentBounds.y = bounds.y; + if (typeof bounds.width!='undefined') currentBounds.width = bounds.width; + if (typeof bounds.height!='undefined') currentBounds.height = bounds.height; + //change the zoom to the saved + this.viewer.drawer.viewport.fitBounds(currentBounds); + }, + _onAnnotationMouseOut: function(event){ + var annotator = this.annotator; + var elem = jQuery(event.target).parents('.annotator-hl').andSelf(); + //if there is a opened annotation then show the new annotation mouse over + if (typeof annotator!='undefined' && elem.hasClass("annotator-hl") && !this.isDrawing){ + /*jQuery(event.target.parentNode).find('.annotator-hl').map(function() { + return this.style.background = 'rgba(255, 255, 10, 0.3)'; + });*/ + } + }, + /* Utilities */ + _sortByDate: function (annotations,type){ + var type = type || 'asc'; //asc => The value [0] will be the most recent date + annotations.sort(function(a,b){ + a = new Date(typeof a.updated!='undefined'?createDateFromISO8601(a.updated):''); + b = new Date(typeof b.updated!='undefined'?createDateFromISO8601(b.updated):''); + if (type == 'asc') + return ba?1:0; + else + return ab?1:0; + }); + }, + _createNewButton:function(){ + var viewer = this.viewer; + var onFocusHandler = $.delegate( this, onFocus ); + var onBlurHandler = $.delegate( this, onBlur ); + var onModeAnnotationHandler = $.delegate( this, this.modeAnnotation ); + /* Buttons */ + var viewer = this.viewer; + var self = this; + viewer.modeAnnotation = new $.Button({ + element: viewer.modeAnnotation ? $.getElement( viewer.modeAnnotation ) : null, + clickTimeThreshold: viewer.clickTimeThreshold, + clickDistThreshold: viewer.clickDistThreshold, + tooltip: "New Annotation", + srcRest: self.resolveUrl( viewer.prefixUrl,"newan_rest.png"), + srcGroup: self.resolveUrl( viewer.prefixUrl,"newan_grouphover.png"), + srcHover: self.resolveUrl( viewer.prefixUrl,"newan_hover.png"), + srcDown: self.resolveUrl( viewer.prefixUrl,"newan_pressed.png"), + onRelease: onModeAnnotationHandler, + onFocus: onFocusHandler, + onBlur: onBlurHandler + }); + + //- Wrapper Annotation Menu + viewer.wrapperAnnotation = new $.ButtonGroup({ + buttons: [ + viewer.modeAnnotation, + ], + 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} + ); + } + }, + _reset: function(){ + //Find and remove DrawingRect. This is the previous rectangle + this._removeElemsByClass('DrawingRect',this.viewer.canvas); + //Show adder and hide editor + this.annotator.editor.element[0].style.display = 'none'; + }, + __bind: function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + // Remove all the elements with a given name inside "inElement" + _removeElemsByClass: function(className,inElement){ + var className = className || ''; + var inElement = inElement || {}; + divs = inElement.getElementsByClassName(className); + for(var i = 0; i < divs.length; i++) { + divs[i].remove(); + } + }, + //Detect if the annotation is an image annotation + _isOpenSeaDragon: function (an){ + var annotator = this.annotator; + var rp = an.rangePosition; + var isOpenSeaDragon = (typeof annotator.osda != 'undefined'); + var isContainer = (typeof an.target!='undefined' && an.target.container==this.viewer.id ); + var isImage = (typeof an.media!='undefined' && an.media=='image'); + var isRP = (typeof rp!='undefined'); + var isSource = false; + //Save source url + var source = this.viewer.source; + var tilesUrl = typeof source.tilesUrl!='undefined'?source.tilesUrl:''; + var functionUrl = typeof source.getTileUrl!='undefined'?source.getTileUrl:''; + var compareUrl = tilesUrl!=''?tilesUrl:(''+functionUrl).replace(/\s+/g, ' '); + if(isContainer) isSource = (an.target.src == compareUrl); + return (isOpenSeaDragon && isContainer && isImage && isRP && isSource); + }, + /* Annotator Utilities */ + _setOverShape: function(elem){ + //Calculate Point absolute positions + var rectPosition = this.rectPosition || {}; + var startPoint = this._logicalToPhysicalXY(new $.Point(rectPosition.left,rectPosition.top)); + var endPoint = this._logicalToPhysicalXY(new $.Point(rectPosition.left+rectPosition.width,rectPosition.top+rectPosition.height)); + + //Calculate Point absolute positions + var wrapper = jQuery('.annotator-wrapper')[0]; + var positionAnnotator = $.getElementPosition(wrapper); + var positionCanvas = $.getElementPosition(this.viewer.canvas); + var positionAdder = {}; + + //Fix with positionCanvas + startPoint = startPoint.plus(positionCanvas); + endPoint = endPoint.plus(positionCanvas); + + elem[0].style.display = 'block'; //Show the adder + + positionAdder.left = (startPoint.x - positionAnnotator.x) + (endPoint.x - startPoint.x) / 2; + positionAdder.top = (startPoint.y - positionAnnotator.y) + (endPoint.y - startPoint.y) / 2; //It is not necessary fix with - positionAnnotator.y + elem.css(positionAdder); + }, + resolveUrl: function( prefix, url ) { + return prefix ? prefix + url : url; + }, + /* Canvas Utilities */ + // return a point with the values in percentage related to the Image + // point is an object $.Point with the value of the canvas relative coordenates + _physicalToLogicalXY: function(point){ + var point = typeof point!='undefined'?point:{}; + var boundX = this.viewer.viewport.getBounds(true).x; + var boundY = this.viewer.viewport.getBounds(true).y; + var boundWidth = this.viewer.viewport.getBounds(true).width; + var boundHeight = this.viewer.viewport.getBounds(true).height; + var containerSizeX = this.viewer.viewport.getContainerSize().x; + var containerSizeY = this.viewer.viewport.getContainerSize().y; + var x = typeof point.x!='undefined'?point.x:0; + var y = typeof point.y!='undefined'?point.y:0; + x = boundX + ((x / containerSizeX) * boundWidth); + y = boundY + ((y / containerSizeY) * boundHeight); + return new $.Point(x,y); + }, + // return a point with the values in pixels related to the canvas element + // point is an object $.Point with the value of the Image relative percentage + _logicalToPhysicalXY: function(point){ + var point = typeof point!='undefined'?point:{}; + var boundX = this.viewer.viewport.getBounds(true).x; + var boundY = this.viewer.viewport.getBounds(true).y; + var boundWidth = this.viewer.viewport.getBounds(true).width; + var boundHeight = this.viewer.viewport.getBounds(true).height; + var containerSizeX = this.viewer.viewport.getContainerSize().x; + var containerSizeY = this.viewer.viewport.getContainerSize().y; + var x = typeof point.x!='undefined'?point.x:0; + var y = typeof point.y!='undefined'?point.y:0; + x = (x - boundX) * containerSizeX / boundWidth; + y = (y - boundY) * containerSizeY / boundHeight; + return new $.Point(x,y); + }, + } + + /* General functions */ + //initiates an animation to hide the controls + function beginControlsAutoHide( viewer ) { + if ( !viewer.autoHideControls ) { + return; + } + viewer.controlsShouldFade = true; + viewer.controlsFadeBeginTime = + $.now() + + viewer.controlsFadeDelay; - window.setTimeout( function(){ - scheduleControlsFade( viewer ); - }, viewer.controlsFadeDelay ); - } - //stop the fade animation on the controls and show them - function abortControlsAutoHide( viewer ) { - var i; - viewer.controlsShouldFade = false; - for ( i = viewer.controls.length - 1; i >= 0; i-- ) { - viewer.controls[ i ].setOpacity( 1.0 ); - } - } - function onFocus(){ - abortControlsAutoHide( this.viewer ); - } + window.setTimeout( function(){ + scheduleControlsFade( viewer ); + }, viewer.controlsFadeDelay ); + } + //stop the fade animation on the controls and show them + function abortControlsAutoHide( viewer ) { + var i; + viewer.controlsShouldFade = false; + for ( i = viewer.controls.length - 1; i >= 0; i-- ) { + viewer.controls[ i ].setOpacity( 1.0 ); + } + } + function onFocus(){ + abortControlsAutoHide( this.viewer ); + } - function onBlur(){ - beginControlsAutoHide( this.viewer ); - } - - + function onBlur(){ + beginControlsAutoHide( this.viewer ); + } + + })(OpenSeadragon); @@ -527,181 +528,198 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //----------------Plugin for Annotator to setup OpenSeaDragon----------------// Annotator.Plugin.OpenSeaDragon = (function(_super) { - __extends(OpenSeaDragon, _super); + __extends(OpenSeaDragon, _super); - //constructor - function OpenSeaDragon() { - this.pluginSubmit = __bind(this.pluginSubmit, this); - _ref = OpenSeaDragon.__super__.constructor.apply(this, arguments); - this.__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; } - return _ref; - } + //constructor + function OpenSeaDragon() { + this.pluginSubmit = __bind(this.pluginSubmit, this); + _ref = OpenSeaDragon.__super__.constructor.apply(this, arguments); + this.__indexOf = [].indexOf; + if(!this.__indexOf){ + this.__indexOf = function(item) { + for (var i = 0, l = this.length; i < l; i++) { + if (i in this && this[i] === item) + return i; + } + return -1; + } - OpenSeaDragon.prototype.field = null; - OpenSeaDragon.prototype.input = null; + } + return _ref; + } - OpenSeaDragon.prototype.pluginInit = function() { - //Check that annotator is working - if (!Annotator.supported()) { - return; - } - - //-- Editor - this.field = this.annotator.editor.addField({ - id: 'osd-input-rangePosition-annotations', - type: 'input', //options (textarea,input,select,checkbox) - submit: this.pluginSubmit, - EditOpenSeaDragonAn: this.EditOpenSeaDragonAn - }); - - //Modify the element created with annotator to be an invisible span - var select = '
  • ', - newfield = Annotator.$(select); - Annotator.$(this.field).replaceWith(newfield); - this.field=newfield[0]; + OpenSeaDragon.prototype.field = null; + OpenSeaDragon.prototype.input = null; - //-- Listener for OpenSeaDragon Plugin - this.initListeners(); - - return this.input = $(this.field).find(':input'); - } - - - - // New JSON for the database - OpenSeaDragon.prototype.pluginSubmit = function(field, annotation) { - //Select the new JSON for the Object to save - if (this.EditOpenSeaDragonAn()){ - var annotator = this.annotator, - osda = annotator.osda, - position = osda.rectPosition, - isNew = typeof annotation.media=='undefined'; - if (typeof annotation.media == 'undefined') annotation.media = "image"; // - media - annotation.target = annotation.target || {}; // - target - annotation.target.container = osda.viewer.id || ""; // - target.container - //Save source url - var source = osda.viewer.source, - tilesUrl = typeof source.tilesUrl!='undefined'?source.tilesUrl:'', - functionUrl = typeof source.getTileUrl!='undefined'?source.getTileUrl:''; - annotation.target.src = tilesUrl!=''?tilesUrl:(''+functionUrl).replace(/\s+/g, ' '); // - target.src (media source) - annotation.target.ext = source.fileFormat || ""; // - target.ext (extension) - annotation.bounds = osda.viewer.drawer.viewport.getBounds() || {}; // - bounds - if(isNew) annotation.rangePosition = position || {}; // - rangePosition - annotation.updated = new Date().toISOString(); // - updated - if (typeof annotation.created == 'undefined') - annotation.created = annotation.updated; // - created - }else{ - if (typeof annotation.media == 'undefined') - annotation.media = "text"; // - media - annotation.updated = new Date().toISOString(); // - updated - if (typeof annotation.created == 'undefined') - annotation.created = annotation.updated; // - created - } - return annotation.media; - }; - - - - //------ Methods ------// - //Detect if we are creating or editing an OpenSeaDragon annotation - OpenSeaDragon.prototype.EditOpenSeaDragonAn = function (){ - var wrapper = $('.annotator-wrapper').parent()[0], - annotator = window.annotator = $.data(wrapper, 'annotator'), - isOpenSeaDragon = (typeof annotator.osda != 'undefined'), - OpenSeaDragon = annotator.editor.OpenSeaDragon; - return (isOpenSeaDragon && typeof OpenSeaDragon!='undefined' && OpenSeaDragon!==-1); - }; - - //Detect if the annotation is an OpenSeaDragon annotation - OpenSeaDragon.prototype.isOpenSeaDragon = function (an){ - var wrapper = $('.annotator-wrapper').parent()[0], - annotator = window.annotator = $.data(wrapper, 'annotator'), - rp = an.rangePosition, - isOpenSeaDragon = (typeof annotator.osda != 'undefined'), - isContainer = (typeof an.target!='undefined' && an.target.container==annotator.osda.viewer.id ), - isImage = (typeof an.media!='undefined' && an.media=='image'), - isRP = (typeof rp!='undefined'), - isSource = false; - //Save source url - var source = annotator.osda.viewer.source, - tilesUrl = typeof source.tilesUrl!='undefined'?source.tilesUrl:''; - functionUrl = typeof source.getTileUrl!='undefined'?source.getTileUrl:'', - compareUrl = tilesUrl!=''?tilesUrl:(''+functionUrl).replace(/\s+/g, ' '); - if(isContainer) isSource = (an.target.src == compareUrl); - return (isOpenSeaDragon && isContainer && isImage && isRP && isSource); - }; - - //Delete OpenSeaDragon Annotation - OpenSeaDragon.prototype._deleteAnnotation = function(an){ - //Remove the annotation of the plugin Store - var annotations = this.annotator.plugins['Store'].annotations; - if (annotations.indexOf(an)>-1) - annotations.splice(annotations.indexOf(an), 1); - //Refresh the annotations in the display - this.annotator.osda.refreshDisplay(); - }; - - - //--Listeners - OpenSeaDragon.prototype.initListeners = function (){ - var wrapper = $('.annotator-wrapper').parent()[0], - annotator = $.data(wrapper, 'annotator'); - var EditOpenSeaDragonAn = this.EditOpenSeaDragonAn, - isOpenSeaDragon = this.isOpenSeaDragon, - self = this; - - //local functions - //-- Editor - function annotationEditorHidden(editor) { - if (EditOpenSeaDragonAn()){ - annotator.osda._reset(); - annotator.osda.refreshDisplay(); //Reload the display of annotations - } - annotator.editor.OpenSeaDragon=-1; - annotator.unsubscribe("annotationEditorHidden", annotationEditorHidden); - }; - function annotationEditorShown(editor,annotation) { - annotator.osda.editAnnotation(annotation,editor); - annotator.subscribe("annotationEditorHidden", annotationEditorHidden); - }; - //-- Annotations - function annotationDeleted(annotation) { - if (isOpenSeaDragon(annotation)) - self._deleteAnnotation(annotation); - }; - //-- Viewer - function hideViewer(){ - jQuery(annotator.osda.viewer.canvas.parentNode).find('.annotator-hl').map(function() { - return this.style.background = 'rgba(255, 255, 10, 0.3)'; - }); - annotator.viewer.unsubscribe("hide", hideViewer); - }; - function annotationViewerShown(viewer,annotations) { - var wrapper = jQuery('.annotator-wrapper').offset(); + OpenSeaDragon.prototype.pluginInit = function() { + //Check that annotator is working + if (!Annotator.supported()) { + return; + } + + //-- Editor + this.field = this.annotator.editor.addField({ + id: 'osd-input-rangePosition-annotations', + type: 'input', //options (textarea,input,select,checkbox) + submit: this.pluginSubmit, + EditOpenSeaDragonAn: this.EditOpenSeaDragonAn + }); + + //Modify the element created with annotator to be an invisible span + var select = '
  • '; + var newfield = Annotator.$(select); + Annotator.$(this.field).replaceWith(newfield); + this.field=newfield[0]; - //Fix with positionCanvas - var startPoint = {x: parseFloat(viewer.element[0].style.left), - y: parseFloat(viewer.element[0].style.top)}; - - var separation = viewer.element.hasClass(viewer.classes.invert.y)?5:-5, - newpos = { - top: (startPoint.y - wrapper.top)+separation, - left: (startPoint.x - wrapper.left) - }; - viewer.element.css(newpos); - - //Remove the time to wait until disapear, to be more faster that annotator by default - viewer.element.find('.annotator-controls').removeClass(viewer.classes.showControls); - - annotator.viewer.subscribe("hide", hideViewer); - }; - //subscribe to Annotator - annotator.subscribe("annotationEditorShown", annotationEditorShown) - .subscribe("annotationDeleted", annotationDeleted) - .subscribe("annotationViewerShown", annotationViewerShown); - } + //-- Listener for OpenSeaDragon Plugin + this.initListeners(); + + return this.input = $(this.field).find(':input'); + } + + + + // New JSON for the database + OpenSeaDragon.prototype.pluginSubmit = function(field, annotation) { + //Select the new JSON for the Object to save + if (this.EditOpenSeaDragonAn()){ + var annotator = this.annotator; + var osda = annotator.osda; + var position = osda.rectPosition; + var isNew = typeof annotation.media=='undefined'; + if (typeof annotation.media == 'undefined') annotation.media = "image"; // - media + annotation.target = annotation.target || {}; // - target + annotation.target.container = osda.viewer.id || ""; // - target.container + //Save source url + var source = osda.viewer.source; + var tilesUrl = typeof source.tilesUrl!='undefined'?source.tilesUrl:''; + var functionUrl = typeof source.getTileUrl!='undefined'?source.getTileUrl:''; + annotation.target.src = tilesUrl!=''?tilesUrl:(''+functionUrl).replace(/\s+/g, ' '); // - target.src (media source) + annotation.target.ext = source.fileFormat || ""; // - target.ext (extension) + annotation.bounds = osda.viewer.drawer.viewport.getBounds() || {}; // - bounds - return OpenSeaDragon; + var finalimagelink = source["@id"].replace("/info.json", ""); + var highlightX = Math.round(position.left * source["width"]); + var highlightY = Math.round(position.top * source["width"]); + var highlightWidth = Math.round(position.width * source["width"]); + var highlightHeight = Math.round(position.height * source["width"]); + annotation.target.thumb = finalimagelink + "/" + highlightX + "," + highlightY + "," + highlightWidth + "," + highlightHeight + "/full/0/native." + source["formats"][0]; + if(isNew) annotation.rangePosition = position || {}; // - rangePosition + annotation.updated = new Date().toISOString(); // - updated + if (typeof annotation.created == 'undefined') + annotation.created = annotation.updated; // - created + }else{ + if (typeof annotation.media == 'undefined') + annotation.media = "text"; // - media + annotation.updated = new Date().toISOString(); // - updated + if (typeof annotation.created == 'undefined') + annotation.created = annotation.updated; // - created + } + return annotation.media; + }; + + + + //------ Methods ------// + //Detect if we are creating or editing an OpenSeaDragon annotation + OpenSeaDragon.prototype.EditOpenSeaDragonAn = function (){ + var wrapper = $('.annotator-wrapper').parent()[0], + annotator = window.annotator = $.data(wrapper, 'annotator'), + isOpenSeaDragon = (typeof annotator.osda != 'undefined'), + OpenSeaDragon = annotator.editor.OpenSeaDragon; + return (isOpenSeaDragon && typeof OpenSeaDragon!='undefined' && OpenSeaDragon!==-1); + }; + + //Detect if the annotation is an OpenSeaDragon annotation + OpenSeaDragon.prototype.isOpenSeaDragon = function (an){ + var wrapper = $('.annotator-wrapper').parent()[0]; + var annotator = window.annotator = $.data(wrapper, 'annotator'); + var rp = an.rangePosition; + var isOpenSeaDragon = (typeof annotator.osda != 'undefined'); + var isContainer = (typeof an.target!='undefined' && an.target.container==annotator.osda.viewer.id ); + var isImage = (typeof an.media!='undefined' && an.media=='image'); + var isRP = (typeof rp!='undefined'); + var isSource = false; + //Save source url + var source = annotator.osda.viewer.source; + var tilesUrl = typeof source.tilesUrl!='undefined'?source.tilesUrl:''; + var functionUrl = typeof source.getTileUrl!='undefined'?source.getTileUrl:''; + var compareUrl = tilesUrl!=''?tilesUrl:(''+functionUrl).replace(/\s+/g, ' '); + if(isContainer) isSource = (an.target.src == compareUrl); + return (isOpenSeaDragon && isContainer && isImage && isRP && isSource); + }; + + //Delete OpenSeaDragon Annotation + OpenSeaDragon.prototype._deleteAnnotation = function(an){ + //Remove the annotation of the plugin Store + var annotations = this.annotator.plugins['Store'].annotations; + if (annotations.indexOf(an)>-1) + annotations.splice(annotations.indexOf(an), 1); + //Refresh the annotations in the display + this.annotator.osda.refreshDisplay(); + }; + + + //--Listeners + OpenSeaDragon.prototype.initListeners = function (){ + var wrapper = $('.annotator-wrapper').parent()[0]; + var annotator = $.data(wrapper, 'annotator'); + var EditOpenSeaDragonAn = this.EditOpenSeaDragonAn; + var isOpenSeaDragon = this.isOpenSeaDragon; + var self = this; + + //local functions + //-- Editor + function annotationEditorHidden(editor) { + if (EditOpenSeaDragonAn()){ + annotator.osda._reset(); + annotator.osda.refreshDisplay(); //Reload the display of annotations + } + annotator.editor.OpenSeaDragon=-1; + annotator.unsubscribe("annotationEditorHidden", annotationEditorHidden); + }; + function annotationEditorShown(editor,annotation) { + annotator.osda.editAnnotation(annotation,editor); + annotator.subscribe("annotationEditorHidden", annotationEditorHidden); + }; + //-- Annotations + function annotationDeleted(annotation) { + if (isOpenSeaDragon(annotation)) + self._deleteAnnotation(annotation); + }; + //-- Viewer + function hideViewer(){ + jQuery(annotator.osda.viewer.canvas.parentNode).find('.annotator-hl').map(function() { + return this.style.background = 'rgba(255, 255, 10, 0.3)'; + }); + annotator.viewer.unsubscribe("hide", hideViewer); + }; + function annotationViewerShown(viewer,annotations) { + var wrapper = jQuery('.annotator-wrapper').offset(); + + //Fix with positionCanvas + var startPoint = {x: parseFloat(viewer.element[0].style.left), + y: parseFloat(viewer.element[0].style.top)}; + + var separation = viewer.element.hasClass(viewer.classes.invert.y)?5:-5, + newpos = { + top: (startPoint.y - wrapper.top)+separation, + left: (startPoint.x - wrapper.left) + }; + viewer.element.css(newpos); + + //Remove the time to wait until disapear, to be more faster that annotator by default + viewer.element.find('.annotator-controls').removeClass(viewer.classes.showControls); + + annotator.viewer.subscribe("hide", hideViewer); + }; + //subscribe to Annotator + annotator.subscribe("annotationEditorShown", annotationEditorShown) + .subscribe("annotationDeleted", annotationDeleted) + .subscribe("annotationViewerShown", annotationViewerShown); + } + + return OpenSeaDragon; })(Annotator.Plugin); @@ -713,101 +731,101 @@ Annotator.Plugin.OpenSeaDragon = (function(_super) { OpenSeadragonAnnotation = ("OpenSeadragonAnnotation" in window) ? OpenSeadragonAnnotation : {}; OpenSeadragonAnnotation = function (element, options) { - //local variables - var $ = jQuery, - options = options || {}; - options.optionsOpenSeadragon = options.optionsOpenSeadragon || {}; - options.optionsOSDA = options.optionsOSDA || {}; - options.optionsAnnotator = options.optionsAnnotator || {}; - - //if there isn't store optinos it will create a uri and limit variables for the Back-end of Annotations - if (typeof options.optionsAnnotator.store=='undefined') - options.optionsAnnotator.store = {}; - var store = options.optionsAnnotator.store; - if (typeof store.annotationData=='undefined') - store.annotationData = {}; - if (typeof store.annotationData.uri=='undefined'){ - var uri = location.protocol + '//' + location.host + location.pathname; - store.annotationData.store = {uri:uri}; - } - if (typeof store.loadFromSearch=='undefined') - store.loadFromSearch={}; - if (typeof store.loadFromSearch.uri=='undefined') - store.loadFromSearch.uri = uri; - if (typeof store.loadFromSearch.limit=='undefined') - store.loadFromSearch.limit = 10000; - - //global variables - this.currentUser = null; + //local variables + var $ = jQuery; + var options = options || {}; + options.optionsOpenSeadragon = options.optionsOpenSeadragon || {}; + options.optionsOSDA = options.optionsOSDA || {}; + options.optionsAnnotator = options.optionsAnnotator || {}; + + //if there isn't store optinos it will create a uri and limit variables for the Back-end of Annotations + if (typeof options.optionsAnnotator.store=='undefined') + options.optionsAnnotator.store = {}; + var store = options.optionsAnnotator.store; + if (typeof store.annotationData=='undefined') + store.annotationData = {}; + if (typeof store.annotationData.uri=='undefined'){ + var uri = location.protocol + '//' + location.host + location.pathname; + store.annotationData.store = {uri:uri}; + } + if (typeof store.loadFromSearch=='undefined') + store.loadFromSearch={}; + if (typeof store.loadFromSearch.uri=='undefined') + store.loadFromSearch.uri = uri; + if (typeof store.loadFromSearch.limit=='undefined') + store.loadFromSearch.limit = 10000; + + //global variables + this.currentUser = null; - //-- Init all the classes --/ - //Annotator - this.annotator = $(element).annotator(options.optionsAnnotator.annotator).data('annotator'); - - //-- Activate all the Annotator plugins --// - if (typeof options.optionsAnnotator.auth!='undefined') - this.annotator.addPlugin('Auth', options.optionsAnnotator.auth); - - if (typeof options.optionsAnnotator.permissions!='undefined') - this.annotator.addPlugin("Permissions", options.optionsAnnotator.permissions); - - if (typeof options.optionsAnnotator.store!='undefined') - this.annotator.addPlugin("Store", options.optionsAnnotator.store); - + //-- Init all the classes --/ + //Annotator + this.annotator = $(element).annotator(options.optionsAnnotator.annotator).data('annotator'); + + //-- Activate all the Annotator plugins --// + if (typeof options.optionsAnnotator.auth!='undefined') + this.annotator.addPlugin('Auth', options.optionsAnnotator.auth); + + if (typeof options.optionsAnnotator.permissions!='undefined') + this.annotator.addPlugin("Permissions", options.optionsAnnotator.permissions); + + if (typeof options.optionsAnnotator.store!='undefined') + this.annotator.addPlugin("Store", options.optionsAnnotator.store); + if (typeof Annotator.Plugin["Geolocation"] === 'function') - this.annotator.addPlugin("Geolocation",options.optionsAnnotator.geolocation); - - if (typeof Annotator.Plugin["Share"] === 'function') - this.annotator.addPlugin("Share",options.optionsAnnotator.share); - - if (typeof Annotator.Plugin["RichText"] === 'function') - this.annotator.addPlugin("RichText",options.optionsAnnotator.richText); - - if (typeof Annotator.Plugin["Reply"] === 'function') - this.annotator.addPlugin("Reply"); - - if (typeof Annotator.Plugin["OpenSeaDragon"] === 'function') - this.annotator.addPlugin("OpenSeaDragon"); + this.annotator.addPlugin("Geolocation",options.optionsAnnotator.geolocation); + + if (typeof Annotator.Plugin["Share"] === 'function') + this.annotator.addPlugin("Share",options.optionsAnnotator.share); + + if (typeof Annotator.Plugin["RichText"] === 'function') + this.annotator.addPlugin("RichText",options.optionsAnnotator.richText); + + if (typeof Annotator.Plugin["Reply"] === 'function') + this.annotator.addPlugin("Reply"); + + if (typeof Annotator.Plugin["OpenSeaDragon"] === 'function') + this.annotator.addPlugin("OpenSeaDragon"); if (typeof Annotator.Plugin["Flagging"] === 'function') - this.annotator.addPlugin("Flagging"); + this.annotator.addPlugin("Flagging"); - if (typeof Annotator.Plugin["HighlightTags"] === 'function') - this.annotator.addPlugin("HighlightTags", options.optionsAnnotator.highlightTags); + if (typeof Annotator.Plugin["HighlightTags"] === 'function') + this.annotator.addPlugin("HighlightTags", options.optionsAnnotator.highlightTags); - //- OpenSeaDragon - this.viewer = OpenSeadragon(options.optionsOpenSeadragon); - //- OpenSeaDragon Plugins + //- OpenSeaDragon + this.viewer = OpenSeadragon(options.optionsOpenSeadragon); + //- OpenSeaDragon Plugins this.viewer.annotation(options.optionsOSDA); //Set annotator.editor.OpenSeaDragon by default this.annotator.editor.OpenSeaDragon=-1; function reloadEditor(){ - tinymce.EditorManager.execCommand('mceRemoveEditor',true, "annotator-field-0"); - tinymce.EditorManager.execCommand('mceAddEditor',true, "annotator-field-0"); + tinymce.EditorManager.execCommand('mceRemoveEditor',true, "annotator-field-0"); + tinymce.EditorManager.execCommand('mceAddEditor',true, "annotator-field-0"); } var self = this; document.addEventListener("fullscreenchange", function () { - reloadEditor(); - }, false); + reloadEditor(); + }, false); - document.addEventListener("mozfullscreenchange", function () { - reloadEditor(); - }, false); + document.addEventListener("mozfullscreenchange", function () { + reloadEditor(); + }, false); - document.addEventListener("webkitfullscreenchange", function () { - reloadEditor(); - }, false); + document.addEventListener("webkitfullscreenchange", function () { + reloadEditor(); + }, false); - document.addEventListener("msfullscreenchange", function () { - reloadEditor(); + document.addEventListener("msfullscreenchange", function () { + reloadEditor(); }, false); this.options = options; - return this; + return this; } diff --git a/common/static/js/vendor/ova/catch/css/main.css b/common/static/js/vendor/ova/catch/css/main.css index 7907481585..b79bd80e0a 100644 --- a/common/static/js/vendor/ova/catch/css/main.css +++ b/common/static/js/vendor/ova/catch/css/main.css @@ -225,7 +225,14 @@ margin-top: 15px; } -#mainCatch .playMediaButton { +#mainCatch .zoomToImageBounds { + width: 20em; + text-align:center; + margin-top: 15px; + margin-bottom: 5px; +} + +#mainCatch .playMediaButton, #mainCatch .zoomToImageBounds { border-top: 2px solid #d3bd89; border-bottom: 2px solid #b3ad69; border-right: 2px solid #b3ad69; @@ -242,7 +249,7 @@ border-radius: 24px; color: #000000; } -#mainCatch .playMediaButton:hover { +#mainCatch .playMediaButton:hover, #mainCatch .zoomToImageBounds:hover { border-top: 2px solid #d3bd89; border-bottom: 2px solid #b3ad69; border-right: 2px solid #b3ad69; @@ -250,7 +257,7 @@ background: #f5c105; color: #080708; } -#mainCatch .playMediaButton:active { +#mainCatch .playMediaButton:active, #mainCatch .zoomToImageBounds:active { border-top: 2px solid #d3bd89; border-bottom: 2px solid #b3ad69; border-right: 2px solid #b3ad69; diff --git a/common/static/js/vendor/ova/catch/js/catch.js b/common/static/js/vendor/ova/catch/js/catch.js index 30e16ac362..442873659f 100644 --- a/common/static/js/vendor/ova/catch/js/catch.js +++ b/common/static/js/vendor/ova/catch/js/catch.js @@ -222,7 +222,11 @@ annotationDetail: ''+ '{{/if}}'+ '{{#if mediatypeforgrid.image}}'+ - ''+ + '
    '+ + ''+ + ''+ + ''+ + '
    '+ '{{/if}}'+ '
    '+ '{{{ text }}}'+ @@ -254,10 +258,6 @@ annotationDetail: '{{/if}}'+ '
    '+ - //'Privacy Settings'+ -// 'Groups Access'+ -// 'Reply'+ - //''+ '
    '+ '
    ', }; @@ -412,18 +412,19 @@ CatchAnnotation.prototype = { el.off(); //Bind functions - var openAnnotationItem = this.__bind(this._openAnnotationItem,this), - closeAnnotationItem = this.__bind(this._closeAnnotationItem,this), - onGeolocationClick = this.__bind(this._onGeolocationClick,this), - onPlaySelectionClick = this.__bind(this._onPlaySelectionClick,this), - onShareControlsClick = this.__bind(this._onShareControlsClick,this), - onSelectionButtonClick = this.__bind(this._onSelectionButtonClick,this), - onPublicPrivateButtonClick = this.__bind(this._onPublicPrivateButtonClick,this), - onQuoteMediaButton = this.__bind(this._onQuoteMediaButton,this), - onControlRepliesClick = this.__bind(this._onControlRepliesClick,this), - onMoreButtonClick = this.__bind(this._onMoreButtonClick,this), + var openAnnotationItem = this.__bind(this._openAnnotationItem, this), + closeAnnotationItem = this.__bind(this._closeAnnotationItem, this), + onGeolocationClick = this.__bind(this._onGeolocationClick, this), + onPlaySelectionClick = this.__bind(this._onPlaySelectionClick, this), + onShareControlsClick = this.__bind(this._onShareControlsClick, this), + onSelectionButtonClick = this.__bind(this._onSelectionButtonClick, this), + onPublicPrivateButtonClick = this.__bind(this._onPublicPrivateButtonClick, this), + onQuoteMediaButton = this.__bind(this._onQuoteMediaButton, this), + onControlRepliesClick = this.__bind(this._onControlRepliesClick, this), + onMoreButtonClick = this.__bind(this._onMoreButtonClick, this), onSearchButtonClick = this.__bind(this._onSearchButtonClick, this), - onDeleteReplyButtonClick = this.__bind(this._onDeleteReplyButtonClick,this); + onDeleteReplyButtonClick = this.__bind(this._onDeleteReplyButtonClick, this), + onZoomToImageBoundsButtonClick = this.__bind(this._onZoomToImageBoundsButtonClick, this); //Open Button el.on("click", ".annotationItem .annotationRow", openAnnotationItem); @@ -443,6 +444,12 @@ CatchAnnotation.prototype = { //PlaySelection button el.on("click",".annotationItem .annotationDetail .quote", onQuoteMediaButton); } + + //IMAGE + if (this.options.media=='image') { + //PlaySelection button + el.on("click",".annotationItem .annotationDetail .zoomToImageBounds", onZoomToImageBoundsButtonClick); + } //controlReplies el.on("click",".annotationItem .controlReplies", onControlRepliesClick); @@ -568,7 +575,7 @@ CatchAnnotation.prototype = { setTimeout(function(){ if (new_tot != tot){ self.refreshCatch(true); - self.checkTotAnnotations(); + self.checkTotAnnotations(); }else{ attempts++; ischanged(); @@ -587,7 +594,7 @@ CatchAnnotation.prototype = { self.refreshCatch(); if (typeof annotation.parent != 'undefined' && annotation.parent != '0'){ var replies = $("[annotationid="+annotation.parent+"]").find(".controlReplies .hideReplies"); - replies.show(); + replies.show(); replies.click(); replies.click(); } @@ -651,6 +658,10 @@ CatchAnnotation.prototype = { item.mediatypeforgrid = {}; item.mediatypeforgrid[item.media] = true; + if (item.mediatypeforgrid.image) { + item.thumbnailLink = item.target.thumb; + }; + //Flags if(!this.options.flags && typeof item.tags != 'undefined' && item.tags.length > 0){ for(var len=item.tags.length, index = len-1; index >= 0; --index){ @@ -751,6 +762,26 @@ CatchAnnotation.prototype = { } } }, + _onZoomToImageBoundsButtonClick: function(evt){ + var zoomToBounds = $(evt.target).hasClass('zoomToImageBounds')?$(evt.target):$(evt.target).parents('.zoomToImageBounds:first'), + osdaId = zoomToBounds.find('.idAnnotation').html(), + uri = zoomToBounds.find('.uri').html(); + + var allannotations = this.annotator.plugins['Store'].annotations, + osda = this.annotator.osda; + + for(var item in allannotations){ + var an = allannotations[item]; + if (typeof an.id!='undefined' && an.id == osdaId){//this is the annotation + var bounds = new OpenSeadragon.Rect(an.bounds.x, an.bounds.y, an.bounds.width, an.bounds.height); + osda.viewer.viewport.fitBounds(bounds, false); + + console.log(an.target.container); + $('html,body').animate({scrollTop: $("#"+an.target.container).offset().top}, + 'slow'); + } + } + }, _onQuoteMediaButton: function(evt){ var quote = $(evt.target).hasClass('quote')?$(evt.target):$(evt.target).parents('.quote:first'), id = quote.find('.idAnnotation').html(), diff --git a/common/static/js/vendor/ova/richText-annotator.js b/common/static/js/vendor/ova/richText-annotator.js index b5add53706..fa7908d678 100644 --- a/common/static/js/vendor/ova/richText-annotator.js +++ b/common/static/js/vendor/ova/richText-annotator.js @@ -78,7 +78,6 @@ Annotator.Plugin.RichText = (function(_super) { annotator.subscribe("annotationEditorShown", function(){ $(annotator.editor.element).find('.mce-tinymce')[0].style.display='block'; - $(annotator.editor.element).find('.mce-container').css('z-index',3000000000); annotator.editor.checkOrientation(); }); annotator.subscribe("annotationEditorHidden", function(){ @@ -91,9 +90,6 @@ Annotator.Plugin.RichText = (function(_super) { //set the modification in the textarea of annotator $(editor.element).find('textarea')[0].value = tinymce.activeEditor.getContent(); }); - ed.on('Init', function(ed){ - $('.mce-container').css('z-index','3090000000000000000'); - }); //New button to add Rubrics of the url https://gteavirtual.org/rubric ed.addButton('rubric', { icon: 'rubric', diff --git a/common/static/js/vendor/ova/tags-annotator.js b/common/static/js/vendor/ova/tags-annotator.js index dde5529e6f..0083953a5f 100644 --- a/common/static/js/vendor/ova/tags-annotator.js +++ b/common/static/js/vendor/ova/tags-annotator.js @@ -35,7 +35,7 @@ (function ($) { // Default settings var DEFAULT_SETTINGS = { - // Search settings + // Search settings method: "GET", contentType: "json", queryParam: "q", @@ -44,33 +44,33 @@ var DEFAULT_SETTINGS = { propertyToSearch: "name", jsonContainer: null, - // Display settings + // Display settings hintText: "Type in a search term", noResultsText: "Not Found. Hit ENTER to add a personal tag.", searchingText: "Searching...", deleteText: "×", animateDropdown: true, - // Tokenization settings + // Tokenization settings tokenLimit: null, tokenDelimiter: ",", preventDuplicates: false, - // Output settings + // Output settings tokenValue: "id", - // Prepopulation settings + // Prepopulation settings prePopulate: null, processPrePopulate: false, // Manipulation settings idPrefix: "token-input-", - // Formatters + // Formatters resultsFormatter: function(item){ return "
  • " + item[this.propertyToSearch]+ "
  • " }, tokenFormatter: function(item) { return "
  • " + item[this.propertyToSearch] + "

  • " }, - // Callbacks + // Callbacks onResult: null, onAdd: null, onDelete: null, @@ -139,8 +139,8 @@ var methods = { return this; }, get: function() { - return this.data("tokenInputObject").getTokens(); - } + return this.data("tokenInputObject").getTokens(); + } } // Expose the .tokenInput function to jQuery as a plugin @@ -441,8 +441,8 @@ $.TokenList = function (input, url_or_data, settings) { } this.getTokens = function() { - return saved_tokens; - } + return saved_tokens; + } // // Private functions @@ -893,232 +893,232 @@ var _ref, __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.HighlightTags = (function(_super) { - __extends(HighlightTags, _super); - - HighlightTags.prototype.options = null; - + __extends(HighlightTags, _super); - function HighlightTags(element,options) { - this.pluginSubmit = __bind(this.pluginSubmit, this); - this.updateViewer = __bind(this.updateViewer, this); - this.colorize = __bind(this.colorize, this); - this.updateField = __bind(this.updateField, this); + HighlightTags.prototype.options = null; + + + function HighlightTags(element,options) { + this.pluginSubmit = __bind(this.pluginSubmit, this); + this.updateViewer = __bind(this.updateViewer, this); + this.colorize = __bind(this.colorize, this); + this.updateField = __bind(this.updateField, this); this.options = options; - _ref = HighlightTags.__super__.constructor.apply(this, arguments); - return _ref; - } - + _ref = HighlightTags.__super__.constructor.apply(this, arguments); + return _ref; + } + //example variables to be used to receive input in the annotator view - HighlightTags.prototype.field = null; - HighlightTags.prototype.input = null; - HighlightTags.prototype.colors = null; + HighlightTags.prototype.field = null; + HighlightTags.prototype.input = null; + HighlightTags.prototype.colors = null; HighlightTags.prototype.isFirstTime = true; //this function will initialize the plug in. Create your fields here in the editor and viewer. HighlightTags.prototype.pluginInit = function() { - console.log("HighlightTags-pluginInit"); - //Check that annotator is working - if (!Annotator.supported()) { - return; - } - - this.field = this.annotator.editor.addField({ - type: 'input', - load: this.updateField, - submit: this.pluginSubmit, - }); - - - - var self = this; - - var newfield = Annotator.$('
  • '+ "
    "+'
  • '); + console.log("HighlightTags-pluginInit"); + //Check that annotator is working + if (!Annotator.supported()) { + return; + } + + this.field = this.annotator.editor.addField({ + type: 'input', + load: this.updateField, + submit: this.pluginSubmit, + }); + + + + var self = this; + + var newfield = Annotator.$('
  • '+ "
    "+'
  • '); Annotator.$(self.field).replaceWith(newfield); self.field=newfield[0]; // - - - //-- Viewer - var newview = this.annotator.viewer.addField({ - load: this.updateViewer, - }); - - this.colors = this.getHighlightTags(); - var self = this; - this.annotator.subscribe('annotationsLoaded', function(){setTimeout(function(){self.colorize()},1000)}); - this.annotator.subscribe('annotationUpdated', this.colorize); - this.annotator.subscribe('flaggedAnnotation', this.updateViewer); - this.annotator.subscribe('annotationCreated', this.colorize); - - }; - - HighlightTags.prototype.getHighlightTags = function(){ - if (typeof this.options.tag != 'undefined') { - var self = this; - var final = {}, prelim = this.options.tag.split(","); - prelim.forEach(function(item){ - var temp = item.split(":"); - final[temp[0]] = self.getRGB(temp[1]); - }); - return final; - } - return {}; - } - - HighlightTags.prototype.getRGB = function(item){ - function getColorValues( color ){ - var values = { red:null, green:null, blue:null, alpha:null }; - if( typeof color == 'string' ){ - /* hex */ - if( color.indexOf('#') === 0 ){ - color = color.substr(1) - if( color.length == 3 ) - values = { - red: parseInt( color[0]+color[0], 16 ), - green: parseInt( color[1]+color[1], 16 ), - blue: parseInt( color[2]+color[2], 16 ), - alpha: .3 - } - else - values = { - red: parseInt( color.substr(0,2), 16 ), - green: parseInt( color.substr(2,2), 16 ), - blue: parseInt( color.substr(4,2), 16 ), - alpha: .3 - } - /* rgb */ - }else if( color.indexOf('rgb(') === 0 ){ - var pars = color.indexOf(','); - values = { - red: parseInt(color.substr(4,pars)), - green: parseInt(color.substr(pars+1,color.indexOf(',',pars))), - blue: parseInt(color.substr(color.indexOf(',',pars+1)+1,color.indexOf(')'))), - alpha: .3 - } - /* rgba */ - }else if( color.indexOf('rgba(') === 0 ){ - var pars = color.indexOf(','), - repars = color.indexOf(',',pars+1); - values = { - red: parseInt(color.substr(5,pars)), - green: parseInt(color.substr(pars+1,repars)), - blue: parseInt(color.substr(color.indexOf(',',pars+1)+1,color.indexOf(',',repars))), - alpha: parseFloat(color.substr(color.indexOf(',',repars+1)+1,color.indexOf(')'))) - } - /* verbous */ - }else{ - var stdCol = { acqua:'#0ff', teal:'#008080', blue:'#00f', navy:'#000080', - yellow:'#ff0', olive:'#808000', lime:'#0f0', green:'#008000', - fuchsia:'#f0f', purple:'#800080', red:'#f00', maroon:'#800000', - white:'#fff', gray:'#808080', silver:'#c0c0c0', black:'#000' }; - if( stdCol[color]!=undefined ) - values = getColorValues(stdCol[color]); - } - } - return values -} - return getColorValues(item) - } - - HighlightTags.prototype.colorize = function(){ - - var annotations = Array.prototype.slice.call($(".annotator-hl")); - for (annNum = 0; annNum < annotations.length; ++annNum){ - var anns = $.data(annotations[annNum],"annotation"); - if (typeof anns.tags != "undefined" && anns.tags.length == 0) { - $(annotations[annNum]).css("background-color",""); - } - if (typeof anns.tags != "undefined" && this.colors !== {}) { - - for(var index = 0; index < anns.tags.length; ++index){ - - if (typeof this.colors[anns.tags[index]] != "undefined") { - var finalcolor = this.colors[anns.tags[index]]; - $(annotations[annNum]).css("background","rgba("+finalcolor.red+","+finalcolor.green+","+finalcolor.blue+",0.3"); - }else{ - $(annotations[annNum]).css("background",""); - } - } - - }else{ - $(annotations[annNum]).css("background",""); - } - } - } - - HighlightTags.prototype.updateField = function(field, annotation){ + - + //-- Viewer + var newview = this.annotator.viewer.addField({ + load: this.updateViewer, + }); + + this.colors = this.getHighlightTags(); + var self = this; + this.annotator.subscribe('annotationsLoaded', function(){setTimeout(function(){self.colorize()},1000)}); + this.annotator.subscribe('annotationUpdated', this.colorize); + this.annotator.subscribe('flaggedAnnotation', this.updateViewer); + this.annotator.subscribe('annotationCreated', this.colorize); + + }; + + HighlightTags.prototype.getHighlightTags = function(){ + if (typeof this.options.tag != 'undefined') { + var self = this; + var final = {}, prelim = this.options.tag.split(","); + prelim.forEach(function(item){ + var temp = item.split(":"); + final[temp[0]] = self.getRGB(temp[1]); + }); + return final; + } + return {}; + } + + HighlightTags.prototype.getRGB = function(item){ + function getColorValues( color ){ + var values = { red:null, green:null, blue:null, alpha:null }; + if( typeof color == 'string' ){ + /* hex */ + if( color.indexOf('#') === 0 ){ + color = color.substr(1) + if( color.length == 3 ) + values = { + red: parseInt( color[0]+color[0], 16 ), + green: parseInt( color[1]+color[1], 16 ), + blue: parseInt( color[2]+color[2], 16 ), + alpha: .3 + } + else + values = { + red: parseInt( color.substr(0,2), 16 ), + green: parseInt( color.substr(2,2), 16 ), + blue: parseInt( color.substr(4,2), 16 ), + alpha: .3 + } + /* rgb */ + }else if( color.indexOf('rgb(') === 0 ){ + var pars = color.indexOf(','); + values = { + red: parseInt(color.substr(4,pars)), + green: parseInt(color.substr(pars+1,color.indexOf(',',pars))), + blue: parseInt(color.substr(color.indexOf(',',pars+1)+1,color.indexOf(')'))), + alpha: .3 + } + /* rgba */ + }else if( color.indexOf('rgba(') === 0 ){ + var pars = color.indexOf(','), + repars = color.indexOf(',',pars+1); + values = { + red: parseInt(color.substr(5,pars)), + green: parseInt(color.substr(pars+1,repars)), + blue: parseInt(color.substr(color.indexOf(',',pars+1)+1,color.indexOf(',',repars))), + alpha: parseFloat(color.substr(color.indexOf(',',repars+1)+1,color.indexOf(')'))) + } + /* verbous */ + }else{ + var stdCol = { acqua:'#0ff', teal:'#008080', blue:'#00f', navy:'#000080', + yellow:'#ff0', olive:'#808000', lime:'#0f0', green:'#008000', + fuchsia:'#f0f', purple:'#800080', red:'#f00', maroon:'#800000', + white:'#fff', gray:'#808080', silver:'#c0c0c0', black:'#000' }; + if( stdCol[color]!=undefined ) + values = getColorValues(stdCol[color]); + } + } + return values +} + return getColorValues(item) + } + + HighlightTags.prototype.colorize = function(){ + + var annotations = Array.prototype.slice.call($(".annotator-hl")); + for (annNum = 0; annNum < annotations.length; ++annNum){ + var anns = $.data(annotations[annNum],"annotation"); + if (typeof anns.tags != "undefined" && anns.tags.length == 0) { + $(annotations[annNum]).css("background-color",""); + } + if (typeof anns.tags != "undefined" && this.colors !== {}) { + + for(var index = 0; index < anns.tags.length; ++index){ + + if (typeof this.colors[anns.tags[index]] != "undefined") { + var finalcolor = this.colors[anns.tags[index]]; + $(annotations[annNum]).css("background","rgba("+finalcolor.red+","+finalcolor.green+","+finalcolor.blue+",0.3"); + }else{ + $(annotations[annNum]).css("background",""); + } + } + + }else{ + $(annotations[annNum]).css("background",""); + } + } + } + + HighlightTags.prototype.updateField = function(field, annotation){ + + if(this.isFirstTime){ var tags = this.options.tag.split(","); - var tokensavailable = []; + var tokensavailable = []; tags.forEach (function(tagnames){ - lonename = tagnames.split(":"); - - tokensavailable.push({'id': lonename[0], 'name':lonename[0]}); - }); + lonename = tagnames.split(":"); + + tokensavailable.push({'id': lonename[0], 'name':lonename[0]}); + }); $("#tag-input").tokenInput(tokensavailable); this.isFirstTime = false; } $('#token-input-tag-input').attr('placeholder','Add tags...'); - $('#tag-input').tokenInput('clear'); + $('#tag-input').tokenInput('clear'); if (typeof annotation.tags != "undefined") { for (tagnum = 0; tagnum < annotation.tags.length; tagnum++){ var n = annotation.tags[tagnum]; - if (typeof this.annotator.plugins["HighlightTags"] != 'undefined') { - if (annotation.tags[tagnum].indexOf("flagged-")==-1){ - $('#tag-input').tokenInput('add',{'id':n,'name':n}); - } - } else{ - $('#tag-input').tokenInput('add',{'id':n,'name':n}); - } + if (typeof this.annotator.plugins["HighlightTags"] != 'undefined') { + if (annotation.tags[tagnum].indexOf("flagged-")==-1){ + $('#tag-input').tokenInput('add',{'id':n,'name':n}); + } + } else{ + $('#tag-input').tokenInput('add',{'id':n,'name':n}); + } } } - - } + + } //The following function is run when a person hits submit. HighlightTags.prototype.pluginSubmit = function(field, annotation) { - var tokens = Array.prototype.slice.call($(".token-input-input-token").parent().find('.token-input-token')); - var arr = []; - tokens.forEach(function(element){ - tag = element.firstChild.firstChild; - arr.push(tag.nodeValue); - }); - annotation.tags = arr; + var tokens = Array.prototype.slice.call($(".token-input-input-token").parent().find('.token-input-token')); + var arr = []; + tokens.forEach(function(element){ + tag = element.firstChild.firstChild; + arr.push(tag.nodeValue); + }); + annotation.tags = arr; } //The following allows you to edit the annotation popup when the viewer has already //hit submit and is just viewing the annotation. - HighlightTags.prototype.updateViewer = function(field, annotation) { - if (typeof annotation.tags != "undefined") { - if (annotation.tags.length == 0) { - $(field).remove(); - return; - } - var nonFlagTags = true; + HighlightTags.prototype.updateViewer = function(field, annotation) { + if (typeof annotation.tags != "undefined") { + if (annotation.tags.length == 0) { + $(field).remove(); + return; + } + var nonFlagTags = true; var tokenList = "
      "; - for (tagnum = 0; tagnum < annotation.tags.length; ++tagnum){ - if (typeof this.annotator.plugins["Flagging"] != 'undefined') { - if (annotation.tags[tagnum].indexOf("flagged-")==-1){ - tokenList += "
    • "+ annotation.tags[tagnum]+"

    • "; - nonFlagTags = false; - } - } else{ - tokenList += "
    • "+ annotation.tags[tagnum]+"

    • "; - } - } + for (tagnum = 0; tagnum < annotation.tags.length; ++tagnum){ + if (typeof this.annotator.plugins["Flagging"] != 'undefined') { + if (annotation.tags[tagnum].indexOf("flagged-")==-1){ + tokenList += "
    • "+ annotation.tags[tagnum]+"

    • "; + nonFlagTags = false; + } + } else{ + tokenList += "
    • "+ annotation.tags[tagnum]+"

    • "; + } + } tokenList += "
    "; $(field).append(tokenList); - if (nonFlagTags) { - $(field).remove(); - } - - } else{ - $(field).remove(); - } + if (nonFlagTags) { + $(field).remove(); + } + + } else{ + $(field).remove(); + } this.annotator.publish("finishedDrawingTags"); } diff --git a/lms/templates/imageannotation.html b/lms/templates/imageannotation.html index 72b73e7188..3342d296bb 100644 --- a/lms/templates/imageannotation.html +++ b/lms/templates/imageannotation.html @@ -35,6 +35,7 @@