changeset 1101:34f893492adb

annotations with nicer tooltips using jquery-tools.
author robcast
date Thu, 25 Oct 2012 19:35:33 +0200
parents c5ed20cd24ae
children 8878c6e36fd5
files webapp/src/main/webapp/jquery/digilib-ann.html webapp/src/main/webapp/jquery/img/fullscreen/32/annotation-user.png webapp/src/main/webapp/jquery/img/fullscreen/32/digilib.png webapp/src/main/webapp/jquery/jquery.digilib.annotations.js webapp/src/main/webapp/jquery/jquery.digilib.css webapp/src/main/webapp/jquery/jquery.tools-tt-1.2.7.min.js webapp/src/main/webapp/jquery/jquery.tools.min.js
diffstat 7 files changed, 84 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/webapp/src/main/webapp/jquery/digilib-ann.html	Thu Oct 25 17:22:36 2012 +0200
+++ b/webapp/src/main/webapp/jquery/digilib-ann.html	Thu Oct 25 19:35:33 2012 +0200
@@ -12,6 +12,7 @@
         </style>
 
         <script type="text/javascript" src="jquery.js"></script>
+        <script type="text/javascript" src="jquery.tools.min.js"></script>
         <script type="text/javascript" src="jquery.cookie.js"></script>
         <script type="text/javascript" src="jquery.digilib.js"></script>
         <script type="text/javascript" src="jquery.digilib.geometry.js"></script>
@@ -34,9 +35,9 @@
                     showRegionNumbers : true,
                     // URL of annotation server
                     //'annotationServerUrl' : 'http://localhost:18080/AnnotationManager/annotator',
-                    'annotationServerUrl' : 'http://virtuoso.mpiwg-berlin.mpg.de:8080/AnnotationManager/annotator',
+                    'annotationServerUrl' : 'http://tuxserve03.mpiwg-berlin.mpg.de/AnnotationManager/annotator',
                     // URL of authentication token server
-                    'annotationTokenUrl' : 'http://r583-1.mpiwg-berlin.mpg.de:8080/test/annotator/token?user=anonymous',
+                    'annotationTokenUrl' : 'http://r583-1.mpiwg-berlin.mpg.de:8080/test/annotator/token',
                     };
                 var $div = $('div#digilib');
                 $div.digilib(opts);
Binary file webapp/src/main/webapp/jquery/img/fullscreen/32/annotation-user.png has changed
Binary file webapp/src/main/webapp/jquery/img/fullscreen/32/digilib.png has changed
--- a/webapp/src/main/webapp/jquery/jquery.digilib.annotations.js	Thu Oct 25 17:22:36 2012 +0200
+++ b/webapp/src/main/webapp/jquery/jquery.digilib.annotations.js	Thu Oct 25 19:35:33 2012 +0200
@@ -44,7 +44,15 @@
         // URL of authentication token server
         'annotationTokenUrl' : 'http://localhost:8080/test/annotator/token',
         // annotation user name
-        'annotationUser' : 'anonymous'
+        '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 = {
@@ -87,7 +95,7 @@
                 setAnnotationMark(data);
             } else {
                 // use position and text
-                var annotation = newAnnotation(mpos, text);
+                var annotation = newAnnotation(data, mpos, text);
                 storeAnnotation(data, annotation);
                 data.annotations.push(annotation);
                 digilib.fn.redisplay(data);
@@ -98,14 +106,18 @@
     /**
      * create a new annotation object
      */
-    var newAnnotation = function (mpos, text, id, uri, user) {
+    var newAnnotation = function (data, mpos, text, id, uri, user, permissions, tags) {
         var annot = {
             pos : mpos,
             text : text,
             id : id,
             uri : uri,
-            user : user
+            user : user,
+            permissions : permissions,
+            tags : tags
         };
+        // TODO: use prototype?
+        annot.getUserName = data.settings.annotationServerUserString;
         return annot;
     };
 
@@ -134,7 +146,7 @@
             // Annotation text entered in JS-prompt
             var text = window.prompt("Annotation text:");
             if (text == null) return false;
-            var annotation = newAnnotation(pos, text);
+            var annotation = newAnnotation(data, pos, text);
             storeAnnotation(data, annotation);
             data.annotations.push(annotation);
             digilib.fn.redisplay(data);
@@ -151,7 +163,7 @@
         var cssPrefix = data.settings.cssPrefix;
         var $elem = data.$elem;
         var annotations = data.annotations;
-        console.debug("renderAnnotations: annotations=" + annotations);
+        console.debug("renderAnnotations: annotations=", annotations);
         // clear annotations
         $elem.find('div.' + cssPrefix + 'annotationmark').remove();
         if (!data.settings.isAnnotationsVisible) return;
@@ -162,13 +174,29 @@
                 console.debug("renderannotations: pos=", mpos);
                 // create annotation
                 var html = '<div class="' + cssPrefix + 'annotationmark ' + cssPrefix + 'overlay">' + (i + 1) + '</div>';
-                var $annotation = $(html);
-                // set text as tooltip TODO: have real popup with editing
-                $annotation.attr('title', "Annotation: " + annotation.text);
+                // 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();
+        }                
     };
 
     /**
@@ -224,7 +252,7 @@
         var annotations = [];
         for (var i = 0; i < annotationData.rows.length; ++i) {
             var ann = annotationData.rows[i];
-            var annot = parseAnnotation(ann)
+            var annot = parseAnnotation(data, ann);
             if (annot != null) {
                 annotations.push(annot);
             }
@@ -237,13 +265,13 @@
      * 
      * Returns an annotation object.
      */
-    var parseAnnotation = function(ann) {
+    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(pos, ann.text, ann.id, ann.uri, ann.user);
+            return newAnnotation(data, pos, ann.text, ann.id, ann.uri, ann.user, ann.permissions, ann.tags);
         }
         return null;
     };
@@ -279,7 +307,7 @@
             headers : headers,
             success : function(annotData, annotStatus) {
                 console.debug("sent annotation data, got=", annotData, " status=" + annotStatus);
-                var annot = parseAnnotation(annotData);
+                var annot = parseAnnotation(data, annotData);
                 // TODO: we have to add the returned data to the real annotation!
                 //renderAnnotations(data);
             }
--- a/webapp/src/main/webapp/jquery/jquery.digilib.css	Thu Oct 25 17:22:36 2012 +0200
+++ b/webapp/src/main/webapp/jquery/jquery.digilib.css	Thu Oct 25 19:35:33 2012 +0200
@@ -290,6 +290,20 @@
     margin-bottom: 20px;
 }
 
+/* annotations */
+div.dl-digilib div.dl-annotationbody {
+     background-color: yellow;
+     border-radius: 5px;  
+}
+div.dl-digilib div.dl-annotationbody div.dl-text {
+    padding: 10px;
+}
+div.dl-digilib div.dl-annotationbody div.dl-creator {
+    color: gray;
+    padding: 5px;
+    border-top: 1px solid silver;
+}
+
 /* scroll arrows */
 div.dl-digilib table.dl-scalertable {
 	border: 0;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webapp/src/main/webapp/jquery/jquery.tools-tt-1.2.7.min.js	Thu Oct 25 19:35:33 2012 +0200
@@ -0,0 +1,13 @@
+/*!
+ * jQuery Tools v1.2.7 - The missing UI library for the Web
+ * 
+ * tooltip/tooltip.js
+ * tooltip/tooltip.dynamic.js
+ * 
+ * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
+ * 
+ * http://flowplayer.org/tools/
+ * 
+ */
+(function(a){a.tools=a.tools||{version:"v1.2.7"},a.tools.tooltip={conf:{effect:"toggle",fadeOutSpeed:"fast",predelay:0,delay:30,opacity:1,tip:0,fadeIE:!1,position:["top","center"],offset:[0,0],relative:!1,cancelDefault:!0,events:{def:"mouseenter,mouseleave",input:"focus,blur",widget:"focus mouseenter,blur mouseleave",tooltip:"mouseenter,mouseleave"},layout:"<div/>",tipClass:"tooltip"},addEffect:function(a,c,d){b[a]=[c,d]}};var b={toggle:[function(a){var b=this.getConf(),c=this.getTip(),d=b.opacity;d<1&&c.css({opacity:d}),c.show(),a.call()},function(a){this.getTip().hide(),a.call()}],fade:[function(b){var c=this.getConf();!a.browser.msie||c.fadeIE?this.getTip().fadeTo(c.fadeInSpeed,c.opacity,b):(this.getTip().show(),b())},function(b){var c=this.getConf();!a.browser.msie||c.fadeIE?this.getTip().fadeOut(c.fadeOutSpeed,b):(this.getTip().hide(),b())}]};function c(b,c,d){var e=d.relative?b.position().top:b.offset().top,f=d.relative?b.position().left:b.offset().left,g=d.position[0];e-=c.outerHeight()-d.offset[0],f+=b.outerWidth()+d.offset[1],/iPad/i.test(navigator.userAgent)&&(e-=a(window).scrollTop());var h=c.outerHeight()+b.outerHeight();g=="center"&&(e+=h/2),g=="bottom"&&(e+=h),g=d.position[1];var i=c.outerWidth()+b.outerWidth();g=="center"&&(f-=i/2),g=="left"&&(f-=i);return{top:e,left:f}}function d(d,e){var f=this,g=d.add(f),h,i=0,j=0,k=d.attr("title"),l=d.attr("data-tooltip"),m=b[e.effect],n,o=d.is(":input"),p=o&&d.is(":checkbox, :radio, select, :button, :submit"),q=d.attr("type"),r=e.events[q]||e.events[o?p?"widget":"input":"def"];if(!m)throw"Nonexistent effect \""+e.effect+"\"";r=r.split(/,\s*/);if(r.length!=2)throw"Tooltip: bad events configuration for "+q;d.on(r[0],function(a){clearTimeout(i),e.predelay?j=setTimeout(function(){f.show(a)},e.predelay):f.show(a)}).on(r[1],function(a){clearTimeout(j),e.delay?i=setTimeout(function(){f.hide(a)},e.delay):f.hide(a)}),k&&e.cancelDefault&&(d.removeAttr("title"),d.data("title",k)),a.extend(f,{show:function(b){if(!h){l?h=a(l):e.tip?h=a(e.tip).eq(0):k?h=a(e.layout).addClass(e.tipClass).appendTo(document.body).hide().append(k):(h=d.next(),h.length||(h=d.parent().next()));if(!h.length)throw"Cannot find tooltip for "+d}if(f.isShown())return f;h.stop(!0,!0);var o=c(d,h,e);e.tip&&h.html(d.data("title")),b=a.Event(),b.type="onBeforeShow",g.trigger(b,[o]);if(b.isDefaultPrevented())return f;o=c(d,h,e),h.css({position:"absolute",top:o.top,left:o.left}),n=!0,m[0].call(f,function(){b.type="onShow",n="full",g.trigger(b)});var p=e.events.tooltip.split(/,\s*/);h.data("__set")||(h.off(p[0]).on(p[0],function(){clearTimeout(i),clearTimeout(j)}),p[1]&&!d.is("input:not(:checkbox, :radio), textarea")&&h.off(p[1]).on(p[1],function(a){a.relatedTarget!=d[0]&&d.trigger(r[1].split(" ")[0])}),e.tip||h.data("__set",!0));return f},hide:function(c){if(!h||!f.isShown())return f;c=a.Event(),c.type="onBeforeHide",g.trigger(c);if(!c.isDefaultPrevented()){n=!1,b[e.effect][1].call(f,function(){c.type="onHide",g.trigger(c)});return f}},isShown:function(a){return a?n=="full":n},getConf:function(){return e},getTip:function(){return h},getTrigger:function(){return d}}),a.each("onHide,onBeforeShow,onShow,onBeforeHide".split(","),function(b,c){a.isFunction(e[c])&&a(f).on(c,e[c]),f[c]=function(b){b&&a(f).on(c,b);return f}})}a.fn.tooltip=function(b){var c=this.data("tooltip");if(c)return c;b=a.extend(!0,{},a.tools.tooltip.conf,b),typeof b.position=="string"&&(b.position=b.position.split(/,?\s/)),this.each(function(){c=new d(a(this),b),a(this).data("tooltip",c)});return b.api?c:this}})(jQuery);
+(function(a){var b=a.tools.tooltip;b.dynamic={conf:{classNames:"top right bottom left"}};function c(b){var c=a(window),d=c.width()+c.scrollLeft(),e=c.height()+c.scrollTop();return[b.offset().top<=c.scrollTop(),d<=b.offset().left+b.width(),e<=b.offset().top+b.height(),c.scrollLeft()>=b.offset().left]}function d(a){var b=a.length;while(b--)if(a[b])return!1;return!0}a.fn.dynamic=function(e){typeof e=="number"&&(e={speed:e}),e=a.extend({},b.dynamic.conf,e);var f=a.extend(!0,{},e),g=e.classNames.split(/\s/),h;this.each(function(){var b=a(this).tooltip().onBeforeShow(function(b,e){var i=this.getTip(),j=this.getConf();h||(h=[j.position[0],j.position[1],j.offset[0],j.offset[1],a.extend({},j)]),a.extend(j,h[4]),j.position=[h[0],h[1]],j.offset=[h[2],h[3]],i.css({visibility:"hidden",position:"absolute",top:e.top,left:e.left}).show();var k=a.extend(!0,{},f),l=c(i);if(!d(l)){l[2]&&(a.extend(j,k.top),j.position[0]="top",i.addClass(g[0])),l[3]&&(a.extend(j,k.right),j.position[1]="right",i.addClass(g[1])),l[0]&&(a.extend(j,k.bottom),j.position[0]="bottom",i.addClass(g[2])),l[1]&&(a.extend(j,k.left),j.position[1]="left",i.addClass(g[3]));if(l[0]||l[2])j.offset[0]*=-1;if(l[1]||l[3])j.offset[1]*=-1}i.css({visibility:"visible"}).hide()});b.onBeforeShow(function(){var a=this.getConf(),b=this.getTip();setTimeout(function(){a.position=[h[0],h[1]],a.offset=[h[2],h[3]]},0)}),b.onHide(function(){var a=this.getTip();a.removeClass(e.classNames)}),ret=b});return e.api?ret:this}})(jQuery);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webapp/src/main/webapp/jquery/jquery.tools.min.js	Thu Oct 25 19:35:33 2012 +0200
@@ -0,0 +1,13 @@
+/*!
+ * jQuery Tools v1.2.7 - The missing UI library for the Web
+ * 
+ * tooltip/tooltip.js
+ * tooltip/tooltip.dynamic.js
+ * 
+ * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
+ * 
+ * http://flowplayer.org/tools/
+ * 
+ */
+(function(a){a.tools=a.tools||{version:"v1.2.7"},a.tools.tooltip={conf:{effect:"toggle",fadeOutSpeed:"fast",predelay:0,delay:30,opacity:1,tip:0,fadeIE:!1,position:["top","center"],offset:[0,0],relative:!1,cancelDefault:!0,events:{def:"mouseenter,mouseleave",input:"focus,blur",widget:"focus mouseenter,blur mouseleave",tooltip:"mouseenter,mouseleave"},layout:"<div/>",tipClass:"tooltip"},addEffect:function(a,c,d){b[a]=[c,d]}};var b={toggle:[function(a){var b=this.getConf(),c=this.getTip(),d=b.opacity;d<1&&c.css({opacity:d}),c.show(),a.call()},function(a){this.getTip().hide(),a.call()}],fade:[function(b){var c=this.getConf();!a.browser.msie||c.fadeIE?this.getTip().fadeTo(c.fadeInSpeed,c.opacity,b):(this.getTip().show(),b())},function(b){var c=this.getConf();!a.browser.msie||c.fadeIE?this.getTip().fadeOut(c.fadeOutSpeed,b):(this.getTip().hide(),b())}]};function c(b,c,d){var e=d.relative?b.position().top:b.offset().top,f=d.relative?b.position().left:b.offset().left,g=d.position[0];e-=c.outerHeight()-d.offset[0],f+=b.outerWidth()+d.offset[1],/iPad/i.test(navigator.userAgent)&&(e-=a(window).scrollTop());var h=c.outerHeight()+b.outerHeight();g=="center"&&(e+=h/2),g=="bottom"&&(e+=h),g=d.position[1];var i=c.outerWidth()+b.outerWidth();g=="center"&&(f-=i/2),g=="left"&&(f-=i);return{top:e,left:f}}function d(d,e){var f=this,g=d.add(f),h,i=0,j=0,k=d.attr("title"),l=d.attr("data-tooltip"),m=b[e.effect],n,o=d.is(":input"),p=o&&d.is(":checkbox, :radio, select, :button, :submit"),q=d.attr("type"),r=e.events[q]||e.events[o?p?"widget":"input":"def"];if(!m)throw"Nonexistent effect \""+e.effect+"\"";r=r.split(/,\s*/);if(r.length!=2)throw"Tooltip: bad events configuration for "+q;d.on(r[0],function(a){clearTimeout(i),e.predelay?j=setTimeout(function(){f.show(a)},e.predelay):f.show(a)}).on(r[1],function(a){clearTimeout(j),e.delay?i=setTimeout(function(){f.hide(a)},e.delay):f.hide(a)}),k&&e.cancelDefault&&(d.removeAttr("title"),d.data("title",k)),a.extend(f,{show:function(b){if(!h){l?h=a(l):e.tip?h=a(e.tip).eq(0):k?h=a(e.layout).addClass(e.tipClass).appendTo(document.body).hide().append(k):(h=d.next(),h.length||(h=d.parent().next()));if(!h.length)throw"Cannot find tooltip for "+d}if(f.isShown())return f;h.stop(!0,!0);var o=c(d,h,e);e.tip&&h.html(d.data("title")),b=a.Event(),b.type="onBeforeShow",g.trigger(b,[o]);if(b.isDefaultPrevented())return f;o=c(d,h,e),h.css({position:"absolute",top:o.top,left:o.left}),n=!0,m[0].call(f,function(){b.type="onShow",n="full",g.trigger(b)});var p=e.events.tooltip.split(/,\s*/);h.data("__set")||(h.off(p[0]).on(p[0],function(){clearTimeout(i),clearTimeout(j)}),p[1]&&!d.is("input:not(:checkbox, :radio), textarea")&&h.off(p[1]).on(p[1],function(a){a.relatedTarget!=d[0]&&d.trigger(r[1].split(" ")[0])}),e.tip||h.data("__set",!0));return f},hide:function(c){if(!h||!f.isShown())return f;c=a.Event(),c.type="onBeforeHide",g.trigger(c);if(!c.isDefaultPrevented()){n=!1,b[e.effect][1].call(f,function(){c.type="onHide",g.trigger(c)});return f}},isShown:function(a){return a?n=="full":n},getConf:function(){return e},getTip:function(){return h},getTrigger:function(){return d}}),a.each("onHide,onBeforeShow,onShow,onBeforeHide".split(","),function(b,c){a.isFunction(e[c])&&a(f).on(c,e[c]),f[c]=function(b){b&&a(f).on(c,b);return f}})}a.fn.tooltip=function(b){var c=this.data("tooltip");if(c)return c;b=a.extend(!0,{},a.tools.tooltip.conf,b),typeof b.position=="string"&&(b.position=b.position.split(/,?\s/)),this.each(function(){c=new d(a(this),b),a(this).data("tooltip",c)});return b.api?c:this}})(jQuery);
+(function(a){var b=a.tools.tooltip;b.dynamic={conf:{classNames:"top right bottom left"}};function c(b){var c=a(window),d=c.width()+c.scrollLeft(),e=c.height()+c.scrollTop();return[b.offset().top<=c.scrollTop(),d<=b.offset().left+b.width(),e<=b.offset().top+b.height(),c.scrollLeft()>=b.offset().left]}function d(a){var b=a.length;while(b--)if(a[b])return!1;return!0}a.fn.dynamic=function(e){typeof e=="number"&&(e={speed:e}),e=a.extend({},b.dynamic.conf,e);var f=a.extend(!0,{},e),g=e.classNames.split(/\s/),h;this.each(function(){var b=a(this).tooltip().onBeforeShow(function(b,e){var i=this.getTip(),j=this.getConf();h||(h=[j.position[0],j.position[1],j.offset[0],j.offset[1],a.extend({},j)]),a.extend(j,h[4]),j.position=[h[0],h[1]],j.offset=[h[2],h[3]],i.css({visibility:"hidden",position:"absolute",top:e.top,left:e.left}).show();var k=a.extend(!0,{},f),l=c(i);if(!d(l)){l[2]&&(a.extend(j,k.top),j.position[0]="top",i.addClass(g[0])),l[3]&&(a.extend(j,k.right),j.position[1]="right",i.addClass(g[1])),l[0]&&(a.extend(j,k.bottom),j.position[0]="bottom",i.addClass(g[2])),l[1]&&(a.extend(j,k.left),j.position[1]="left",i.addClass(g[3]));if(l[0]||l[2])j.offset[0]*=-1;if(l[1]||l[3])j.offset[1]*=-1}i.css({visibility:"visible"}).hide()});b.onBeforeShow(function(){var a=this.getConf(),b=this.getTip();setTimeout(function(){a.position=[h[0],h[1]],a.offset=[h[2],h[3]]},0)}),b.onHide(function(){var a=this.getTip();a.removeClass(e.classNames)}),ret=b});return e.api?ret:this}})(jQuery);