Image Annotation Tool: Add linkback functionality to image thumbnails
Changes requested in PR
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -147,3 +147,4 @@ David Bodor <david.gabor.bodor@gmail.com>
|
||||
Sébastien Hinderer <Sebastien.Hinderer@inria.fr>
|
||||
Kristin Stephens <ksteph@cs.berkeley.edu>
|
||||
Ben Patterson <bpatterson@edx.org>
|
||||
Luis Duarte <lduarte1991@gmail.com>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"<div><p>Helper Test Instructions.</p></div>"
|
||||
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('<annotatable>foo</annotatable>')
|
||||
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)
|
||||
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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"<div><p>Image Test Instructions.</p></div>"
|
||||
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('<annotatable>foo</annotatable>')
|
||||
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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -68,9 +68,9 @@ class VideoAnnotationModule(AnnotatableFields, XModule):
|
||||
""" Removes <instructions> 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. """
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
1478
common/static/js/vendor/ova/OpenSeaDragonAnnotation.js
vendored
1478
common/static/js/vendor/ova/OpenSeaDragonAnnotation.js
vendored
@@ -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 b<a?-1:b>a?1:0;
|
||||
else
|
||||
return a<b?-1:a>b?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 b<a?-1:b>a?1:0;
|
||||
else
|
||||
return a<b?-1:a>b?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 = '<li><span id="osd-input-rangePosition-annotations"></span></li>',
|
||||
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 = '<li><span id="osd-input-rangePosition-annotations"></span></li>';
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
13
common/static/js/vendor/ova/catch/css/main.css
vendored
13
common/static/js/vendor/ova/catch/css/main.css
vendored
@@ -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;
|
||||
|
||||
67
common/static/js/vendor/ova/catch/js/catch.js
vendored
67
common/static/js/vendor/ova/catch/js/catch.js
vendored
@@ -222,7 +222,11 @@ annotationDetail:
|
||||
'</div>'+
|
||||
'{{/if}}'+
|
||||
'{{#if mediatypeforgrid.image}}'+
|
||||
'<img src="http://www.paraemigrantes.com/wp-content/themes/daily/images/default-thumb.gif">'+
|
||||
'<div class="zoomToImageBounds">'+
|
||||
'<img src="{{{ thumbnailLink }}}">'+
|
||||
'<span class="idAnnotation" style="display:none">{{{ id }}}</span>'+
|
||||
'<span class="uri" style="display:none">{{{uri}}}</span>'+
|
||||
'</div>'+
|
||||
'{{/if}}'+
|
||||
'<div class="body">'+
|
||||
'{{{ text }}}'+
|
||||
@@ -254,10 +258,6 @@ annotationDetail:
|
||||
'{{/if}}'+
|
||||
|
||||
'<div class="controlPanel">'+
|
||||
//'<img class="privacy_button" src="'+root+'privacy_icon.png" width="36" height="36" alt="Privacy Settings" title="Privacy Settings">'+
|
||||
// '<img class="groups_button" src="'+root+'groups_icon.png" width="36" height="36" alt="Groups Access" title="Groups Access">'+
|
||||
// '<img class="reply_button" src="'+root+'groups_icon.png" width="36" height="36" alt="Reply" title="Reply" idAnnotation="{{{ id }}}">'+
|
||||
//'<img class="share_button" src="'+root+'share_icon.png" width="36" height="36" alt="Share Annotation" title="Share Annotation"/>'+
|
||||
'</div>'+
|
||||
'</div>',
|
||||
};
|
||||
@@ -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(),
|
||||
|
||||
@@ -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',
|
||||
|
||||
404
common/static/js/vendor/ova/tags-annotator.js
vendored
404
common/static/js/vendor/ova/tags-annotator.js
vendored
@@ -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 "<li>" + item[this.propertyToSearch]+ "</li>" },
|
||||
tokenFormatter: function(item) { return "<li><p>" + item[this.propertyToSearch] + "</p></li>" },
|
||||
|
||||
// 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.$('<li class="annotator-item">'+ "<div><input placeholder =\"Add tags\" type=\"text\" id=\"tag-input\" name=\"tags\" /></div>"+'</li>');
|
||||
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.$('<li class="annotator-item">'+ "<div><input placeholder =\"Add tags\" type=\"text\" id=\"tag-input\" name=\"tags\" /></div>"+'</li>');
|
||||
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 = "<ul class=\"token-input-list\">";
|
||||
for (tagnum = 0; tagnum < annotation.tags.length; ++tagnum){
|
||||
if (typeof this.annotator.plugins["Flagging"] != 'undefined') {
|
||||
if (annotation.tags[tagnum].indexOf("flagged-")==-1){
|
||||
tokenList += "<li class=\"token-input-token\"><p>"+ annotation.tags[tagnum]+"</p></span></li>";
|
||||
nonFlagTags = false;
|
||||
}
|
||||
} else{
|
||||
tokenList += "<li class=\"token-input-token\"><p>"+ annotation.tags[tagnum]+"</p></span></li>";
|
||||
}
|
||||
}
|
||||
for (tagnum = 0; tagnum < annotation.tags.length; ++tagnum){
|
||||
if (typeof this.annotator.plugins["Flagging"] != 'undefined') {
|
||||
if (annotation.tags[tagnum].indexOf("flagged-")==-1){
|
||||
tokenList += "<li class=\"token-input-token\"><p>"+ annotation.tags[tagnum]+"</p></span></li>";
|
||||
nonFlagTags = false;
|
||||
}
|
||||
} else{
|
||||
tokenList += "<li class=\"token-input-token\"><p>"+ annotation.tags[tagnum]+"</p></span></li>";
|
||||
}
|
||||
}
|
||||
tokenList += "</ul>";
|
||||
$(field).append(tokenList);
|
||||
if (nonFlagTags) {
|
||||
$(field).remove();
|
||||
}
|
||||
|
||||
} else{
|
||||
$(field).remove();
|
||||
}
|
||||
if (nonFlagTags) {
|
||||
$(field).remove();
|
||||
}
|
||||
|
||||
} else{
|
||||
$(field).remove();
|
||||
}
|
||||
this.annotator.publish("finishedDrawingTags");
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
<script type="text/javascript" src="${static.url('js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js', raw=True)}" />
|
||||
</div>
|
||||
<div id="catchDIV">
|
||||
## Translators: Notes below refer to annotations. They wil later be put under a "Notes" section.
|
||||
<div class="annotationListContainer">${_('You do not have any notes.')}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user