Mercurial > hg > digilib-old
view webapp/src/main/webapp/jquery/jquery.digilib.annotations.js @ 1112:121d3aadfa1e
real authentication for annotation user.
author | robcast |
---|---|
date | Tue, 30 Oct 2012 20:23:24 +0100 |
parents | ccdac39eb3da |
children |
line wrap: on
line source
/** digilib plugin for annotations. currently only point-like annotations (like marks). Annotations are stored on a Annotator http://annotateit.org compatible server. */ (function($) { // affine geometry var geom; // plugin object with digilib data var digilib; var FULL_AREA; var buttons = { annotations : { onclick : "toggleAnnotations", tooltip : "show or hide annotations", icon : "annotations.png" }, annotationuser : { onclick : "setAnnotationUser", tooltip : "set user account for annotations", icon : "annotation-user.png" }, annotationmark : { onclick : "setAnnotationMark", tooltip : "create an annotation for a point", icon : "annotation-mark.png" } }; var defaults = { // are annotations active? 'isAnnotationsVisible' : true, // buttonset of this plugin 'annotationSet' : ['annotations', 'annotationuser', 'annotationmark', 'lessoptions'], // URL of annotation server 'annotationServerUrl' : 'http://virtuoso.mpiwg-berlin.mpg.de:8080/AnnotationManager/annotator', // URL of authentication token server 'annotationTokenUrl' : 'http://localhost:8080/test/annotator/token', // annotation user name 'annotationUser' : 'anonymous', // function to translate user name from annotation server format 'annotationServerUserString' : function() { if (this.user && this.user.name) { return this.user.name; } return this.user; }, }; var actions = { /** * show/hide annotations */ toggleAnnotations : function (data) { var show = !data.settings.isAnnotationsVisible; data.settings.isAnnotationsVisible = show; digilib.fn.highlightButtons(data, 'annotations', show); renderAnnotations(data); }, /** * set user account for annotations */ setAnnotationUser : function (data, user, password) { var settings = data.settings; if (user == null) { // user name entered in JS-prompt user = window.prompt("User name:", settings.annotationUser); if (user != null) { // password entered in JS-prompt password = window.prompt("Password:", ''); settings.annotationUser = user; data.dlOpts.annotationUser = user; digilib.fn.storeOptions(data); loadAnnotationToken(data, password); } } else { settings.annotationUser = user; data.dlOpts.annotationUser = user; digilib.fn.storeOptions(data); loadAnnotationToken(data, password); } }, /** * set a mark-annotation by clicking (or giving a position and a text) * * @param data * @param mpos * @param text */ setAnnotationMark : function (data, mpos, text) { if (mpos == null) { // interactive setAnnotationMark(data); } else { // use position and text (and user-id) var annotation = newAnnotation(data, mpos, text, null, null, data.settings.annotationUser); storeAnnotation(data, annotation); // TODO: replace with annotation returned by server data.annotations.push(annotation); digilib.fn.redisplay(data); } }, }; /** * create a new annotation object */ var newAnnotation = function (data, mpos, text, id, uri, user, permissions, tags) { var annot = { pos : mpos, text : text, id : id, uri : uri, user : user, permissions : permissions, tags : tags }; // TODO: use prototype? annot.getUserName = data.settings.annotationServerUserString; return annot; }; /** * returns an annotatable url to this digilib image */ var getAnnotationPageUrl = function(data) { var url = data.settings.digilibBaseUrl + '/jquery/digilib.html?'; url += digilib.fn.getParamString(data.settings, ['fn', 'pn'], digilib.defaults); return url; }; /** * add a mark-annotation where clicked. */ var setAnnotationMark = function(data) { var $scaler = data.$scaler; // unbind other handler TODO: do we need to do this? $scaler.off(".dlZoomDrag"); // start event capturing $scaler.one('mousedown.dlSetAnnotationMark', function(evt) { // event handler adding a new mark console.log("setAnnotationMark at=", evt); var mpos = geom.position(evt); var pos = data.imgTrafo.invtransform(mpos); // Annotation text entered in JS-prompt var text = window.prompt("Annotation text:"); if (text == null) return false; var annotation = newAnnotation(data, pos, text, null, null, data.settings.annotationUser); storeAnnotation(data, annotation); data.annotations.push(annotation); digilib.fn.redisplay(data); return false; }); }; /** * place annotations on the image */ var renderAnnotations = function(data) { if (data.annotations == null || data.$img == null || data.imgTrafo == null) return; var cssPrefix = data.settings.cssPrefix; var $elem = data.$elem; // try to show annotation user state $elem.find('div#'+cssPrefix+'button-annotationuser').attr('title', 'annotation user: '+data.settings.annotationUser); var annotations = data.annotations; console.debug("renderAnnotations: annotations=", annotations); // clear annotations $elem.find('div.' + cssPrefix + 'annotationmark').remove(); if (!data.settings.isAnnotationsVisible) return; for (var i = 0; i < annotations.length; i++) { var annotation = annotations[i]; if (data.zoomArea.containsPosition(annotation.pos)) { var mpos = data.imgTrafo.transform(annotation.pos); console.debug("renderannotations: pos=", mpos); // create annotation var html = '<div class="' + cssPrefix + 'annotationmark ' + cssPrefix + 'overlay">' + (i + 1) + '</div>'; // set text as tooltip if ($.fn.tooltip != null) { html += '<div class="tooltip '+cssPrefix+'annotationbody" style="display:none">' // + '<h3>Annotation</h3>' + '<div class="'+cssPrefix+'text">'+annotation.text+'</div>' + '<div class="'+cssPrefix+'creator">Creator: '+annotation.getUserName()+'</div>'; if (annotation.tags != null && annotation.tags.length > 0) { html += '<div class="'+cssPrefix+'tags">Tags: '+annotation.tags+'</div>'; } html += '</div>'; var $annotation = $(html); } else { // default browser tooltip var $annotation = $(html); $annotation.attr('title', "Annotation: " + annotation.text); } $elem.append($annotation); mpos.adjustDiv($annotation); } } if ($.fn.tooltip != null) { $('div.'+cssPrefix+'annotationmark').tooltip(); } }; /** * Get an authentication token from the token server. * * Stores the token and loads annotations on success. */ var loadAnnotationToken = function(data, password) { var settings = data.settings; var url = settings.annotationTokenUrl; var params = {'user': settings.annotationUser}; if (password != null) { params.password = password; } // TODO: better error handling $.post(url, params) .done(function (authToken, authStatus) { console.debug("got auth token data=", authToken); data.annotationToken = authToken; data.dlOpts.annotationToken = authToken; digilib.fn.storeOptions(data); loadAnnotations(data); }) .fail(function (xhr, status) { console.error("got auth token error:", xhr); data.annotationToken = null; data.settings.annotationUser = "anonymous"; loadAnnotations(data); }); }; /** * loads all annotations for this url from the annotation server. */ var loadAnnotations = function(data) { var settings = data.settings; // we use the search API var url = settings.annotationServerUrl + '/search'; var pageUrl = getAnnotationPageUrl(data); // send authentication token in header headers = {}; if (data.annotationToken != null) { headers['x-annotator-auth-token'] = data.annotationToken; } // get only 20 annotations with this url var query = { limit : 20, uri : pageUrl }; $.ajax(url, { dataType : 'json', data : query, headers : headers, success : function(annotData, annotStatus) { console.debug("got annotation data=", annotData); data.annotationData = annotData; parseAnnotations(data, annotData); renderAnnotations(data); } }); }; /** * parse all JSON-annotations in annotationData.rows and put in data.annotations */ var parseAnnotations = function(data, annotationData) { var annotations = []; for (var i = 0; i < annotationData.rows.length; ++i) { var ann = annotationData.rows[i]; var annot = parseAnnotation(data, ann); if (annot != null) { annotations.push(annot); } } data.annotations = annotations; }; /** * Parse a JSON-annotation. * * Returns an annotation object. */ var parseAnnotation = function(data, ann) { // TODO: check validity of annotation data if (ann.areas != null && ann.areas.length > 0) { var area = ann.areas[0]; // currently only point annotations var pos = geom.position(area.x, area.y); return newAnnotation(data, pos, ann.text, ann.id, ann.uri, ann.user, ann.permissions, ann.tags); } return null; }; /** * Store an annotation on the annotation server. */ var storeAnnotation = function(data, annotation) { console.debug("storeAnnotation:", annotation); var settings = data.settings; var url = settings.annotationServerUrl + '/annotations'; var pageUrl = getAnnotationPageUrl(data); // send authentication token in header headers = { 'x-annotator-auth-token' : data.annotationToken }; // create annotation object to send var annotData = { areas : [{ x : annotation.pos.x, y : annotation.pos.y }], text : annotation.text, uri : pageUrl, user : settings.annotationUser }; var dataString = JSON.stringify(annotData); $.ajax(url, { type : 'POST', dataType : 'json', contentType : 'application/json', data : dataString, headers : headers, success : function(annotData, annotStatus) { console.debug("sent annotation data, got=", annotData, " status=" + annotStatus); var annot = parseAnnotation(data, annotData); // TODO: we have to add the returned data to the real annotation! //renderAnnotations(data); } }); }; /** * install additional buttons */ var installButtons = function(data) { var settings = data.settings; var mode = settings.interactionMode; var buttonSettings = settings.buttonSettings[mode]; // configure buttons through digilib "annotationSet" option var buttonSet = settings.annotationSet || annotationSet; // set annotationSet to [] or '' for no buttons (when showing annotations only) if (buttonSet.length && buttonSet.length > 0) { buttonSettings.annotationSet = buttonSet; buttonSettings.buttonSets.push('annotationSet'); } }; /** * plugin installation. called by digilib on plugin object. */ var install = function(plugin) { digilib = plugin; console.debug('installing annotations plugin. digilib:', digilib); // import geometry classes geom = digilib.fn.geometry; FULL_AREA = geom.rectangle(0, 0, 1, 1); // add defaults, actins, buttons $.extend(digilib.defaults, defaults); $.extend(digilib.actions, actions); $.extend(digilib.buttons, buttons); }; /** plugin initialization */ var init = function(data) { console.debug('initialising annotations plugin. data:', data); var $data = $(data); // set up data.annotations = []; if (digilib.plugins.buttons != null) { installButtons(data); } if (data.dlOpts.annotationUser != null) { // get annotation user from cookie data.settings.annotationUser = data.dlOpts.annotationUser; } if (data.dlOpts.annotationToken != null) { // get annotation token from cookie data.annotationToken = data.dlOpts.annotationToken; } // install event handler $data.bind('setup', handleSetup); $data.bind('update', handleUpdate); }; /** * setup loads all annotations. */ var handleSetup = function(evt) { console.debug("annotations: handleSetup"); var data = this; // load annotations from server if (data.annotationToken != null) { loadAnnotations(data); } else { loadAnnotationToken(data); } }; /** * update renders all annotations. */ var handleUpdate = function(evt) { console.debug("annotations: handleUpdate"); var data = this; if (data.marks != null) { renderAnnotations(data); } }; // plugin object with name and init // shared objects filled by digilib on registration var plugin = { name : 'annotations', install : install, init : init, buttons : {}, actions : {}, fn : {}, plugins : {} }; if ($.fn.digilib == null) { $.error("jquery.digilib.annotations must be loaded after jquery.digilib!"); } else { $.fn.digilib('plugin', plugin); } })(jQuery);