Mercurial > hg > digilib-old
annotate webapp/src/main/webapp/jquery/jquery.digilib.annotations.js @ 1101:34f893492adb
annotations with nicer tooltips using jquery-tools.
author | robcast |
---|---|
date | Thu, 25 Oct 2012 19:35:33 +0200 |
parents | c5ed20cd24ae |
children | ccdac39eb3da |
rev | line source |
---|---|
1083 | 1 /** |
2 digilib plugin for annotations. | |
3 | |
1086 | 4 currently only point-like annotations (like marks). |
5 | |
6 Annotations are stored on a Annotator http://annotateit.org compatible server. | |
1083 | 7 |
8 */ | |
9 | |
10 (function($) { | |
11 | |
12 // affine geometry | |
13 var geom; | |
14 // plugin object with digilib data | |
15 var digilib; | |
16 | |
17 var FULL_AREA; | |
18 | |
19 var buttons = { | |
20 annotations : { | |
21 onclick : "toggleAnnotations", | |
22 tooltip : "show or hide annotations", | |
23 icon : "annotations.png" | |
24 }, | |
1100 | 25 annotationuser : { |
26 onclick : "setAnnotationUser", | |
27 tooltip : "set user account for annotations", | |
28 icon : "annotation-user.png" | |
29 }, | |
1083 | 30 annotationmark : { |
31 onclick : "setAnnotationMark", | |
32 tooltip : "create an annotation for a point", | |
33 icon : "annotation-mark.png" | |
34 } | |
35 }; | |
36 | |
37 var defaults = { | |
38 // are annotations active? | |
39 'isAnnotationsVisible' : true, | |
40 // buttonset of this plugin | |
1100 | 41 'annotationSet' : ['annotations', 'annotationuser', 'annotationmark', 'lessoptions'], |
1083 | 42 // URL of annotation server |
43 'annotationServerUrl' : 'http://virtuoso.mpiwg-berlin.mpg.de:8080/AnnotationManager/annotator', | |
44 // URL of authentication token server | |
1100 | 45 'annotationTokenUrl' : 'http://localhost:8080/test/annotator/token', |
1083 | 46 // annotation user name |
1101
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
47 'annotationUser' : 'anonymous', |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
48 // function to translate user name from annotation server format |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
49 'annotationServerUserString' : function() { |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
50 if (this.user && this.user.name) { |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
51 return this.user.name; |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
52 } |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
53 return this.user; |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
54 }, |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
55 |
1083 | 56 }; |
57 | |
58 var actions = { | |
59 /** | |
60 * show/hide annotations | |
61 */ | |
1100 | 62 toggleAnnotations : function (data) { |
1083 | 63 var show = !data.settings.isAnnotationsVisible; |
64 data.settings.isAnnotationsVisible = show; | |
1097 | 65 digilib.fn.highlightButtons(data, 'annotations', show); |
1083 | 66 renderAnnotations(data); |
67 }, | |
1100 | 68 |
69 /** | |
70 * set user account for annotations | |
71 */ | |
72 setAnnotationUser : function (data, user) { | |
73 var settings = data.settings; | |
74 if (user == null) { | |
75 // user name entered in JS-prompt | |
76 user = window.prompt("User name:", settings.annotationUser); | |
77 if (user != null) { | |
78 settings.annotationUser = user; | |
79 } | |
80 } else { | |
81 settings.annotationUser = user; | |
82 } | |
83 }, | |
1083 | 84 |
85 /** | |
86 * set a mark-annotation by clicking (or giving a position and a text) | |
87 * | |
88 * @param data | |
89 * @param mpos | |
90 * @param text | |
91 */ | |
1100 | 92 setAnnotationMark : function (data, mpos, text) { |
1083 | 93 if (mpos == null) { |
94 // interactive | |
95 setAnnotationMark(data); | |
96 } else { | |
97 // use position and text | |
1101
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
98 var annotation = newAnnotation(data, mpos, text); |
1083 | 99 storeAnnotation(data, annotation); |
100 data.annotations.push(annotation); | |
101 digilib.fn.redisplay(data); | |
102 } | |
103 }, | |
104 }; | |
105 | |
1086 | 106 /** |
107 * create a new annotation object | |
108 */ | |
1101
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
109 var newAnnotation = function (data, mpos, text, id, uri, user, permissions, tags) { |
1083 | 110 var annot = { |
111 pos : mpos, | |
112 text : text, | |
113 id : id, | |
114 uri : uri, | |
1101
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
115 user : user, |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
116 permissions : permissions, |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
117 tags : tags |
1083 | 118 }; |
1101
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
119 // TODO: use prototype? |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
120 annot.getUserName = data.settings.annotationServerUserString; |
1083 | 121 return annot; |
122 }; | |
123 | |
124 /** | |
125 * returns an annotatable url to this digilib image | |
126 */ | |
127 var getAnnotationPageUrl = function(data) { | |
128 var url = data.settings.digilibBaseUrl + '/jquery/digilib.html?'; | |
129 url += digilib.fn.getParamString(data.settings, ['fn', 'pn'], digilib.defaults); | |
130 return url; | |
1086 | 131 }; |
132 | |
1083 | 133 /** |
134 * add a mark-annotation where clicked. | |
135 */ | |
136 var setAnnotationMark = function(data) { | |
137 var $scaler = data.$scaler; | |
138 // unbind other handler TODO: do we need to do this? | |
139 $scaler.off(".dlZoomDrag"); | |
140 // start event capturing | |
141 $scaler.one('mousedown.dlSetAnnotationMark', function(evt) { | |
142 // event handler adding a new mark | |
143 console.log("setAnnotationMark at=", evt); | |
144 var mpos = geom.position(evt); | |
145 var pos = data.imgTrafo.invtransform(mpos); | |
1086 | 146 // Annotation text entered in JS-prompt |
1083 | 147 var text = window.prompt("Annotation text:"); |
1100 | 148 if (text == null) return false; |
1101
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
149 var annotation = newAnnotation(data, pos, text); |
1083 | 150 storeAnnotation(data, annotation); |
151 data.annotations.push(annotation); | |
152 digilib.fn.redisplay(data); | |
153 return false; | |
154 }); | |
155 }; | |
156 | |
157 /** | |
158 * place annotations on the image | |
159 */ | |
160 var renderAnnotations = function(data) { | |
161 if (data.annotations == null || data.$img == null || data.imgTrafo == null) | |
162 return; | |
163 var cssPrefix = data.settings.cssPrefix; | |
164 var $elem = data.$elem; | |
165 var annotations = data.annotations; | |
1101
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
166 console.debug("renderAnnotations: annotations=", annotations); |
1083 | 167 // clear annotations |
168 $elem.find('div.' + cssPrefix + 'annotationmark').remove(); | |
1097 | 169 if (!data.settings.isAnnotationsVisible) return; |
1083 | 170 for (var i = 0; i < annotations.length; i++) { |
171 var annotation = annotations[i]; | |
172 if (data.zoomArea.containsPosition(annotation.pos)) { | |
173 var mpos = data.imgTrafo.transform(annotation.pos); | |
174 console.debug("renderannotations: pos=", mpos); | |
175 // create annotation | |
176 var html = '<div class="' + cssPrefix + 'annotationmark ' + cssPrefix + 'overlay">' + (i + 1) + '</div>'; | |
1101
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
177 // set text as tooltip |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
178 if ($.fn.tooltip != null) { |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
179 html += '<div class="tooltip '+cssPrefix+'annotationbody" style="display:none">' |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
180 // + '<h3>Annotation</h3>' |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
181 + '<div class="'+cssPrefix+'text">'+annotation.text+'</div>' |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
182 + '<div class="'+cssPrefix+'creator">Creator: '+annotation.getUserName()+'</div>'; |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
183 if (annotation.tags != null && annotation.tags.length > 0) { |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
184 html += '<div class="'+cssPrefix+'tags">Tags: '+annotation.tags+'</div>'; |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
185 } |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
186 html += '</div>'; |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
187 var $annotation = $(html); |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
188 } else { |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
189 // default browser tooltip |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
190 var $annotation = $(html); |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
191 $annotation.attr('title', "Annotation: " + annotation.text); |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
192 } |
1083 | 193 $elem.append($annotation); |
194 mpos.adjustDiv($annotation); | |
195 } | |
196 } | |
1101
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
197 if ($.fn.tooltip != null) { |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
198 $('div.'+cssPrefix+'annotationmark').tooltip(); |
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
199 } |
1083 | 200 }; |
201 | |
1086 | 202 /** |
203 * Get an authentication token from the token server. | |
204 * | |
205 * Stores the token and loads annotations on success. | |
206 */ | |
1083 | 207 var loadAnnotationToken = function(data) { |
208 var settings = data.settings; | |
209 var url = settings.annotationTokenUrl; | |
210 // TODO: better error handling | |
211 $.get(url, function(authToken, authStatus) { | |
212 console.debug("got auth token data=", authToken); | |
213 data.annotationToken = authToken; | |
214 loadAnnotations(data); | |
215 }); | |
216 }; | |
217 | |
1086 | 218 /** |
219 * loads all annotations for this url from the annotation server. | |
220 */ | |
1083 | 221 var loadAnnotations = function(data) { |
222 var settings = data.settings; | |
1086 | 223 // we use the search API |
1083 | 224 var url = settings.annotationServerUrl + '/search'; |
1084 | 225 var pageUrl = getAnnotationPageUrl(data); |
1083 | 226 // send authentication token in header |
227 headers = { | |
228 'x-annotator-auth-token' : data.annotationToken | |
229 }; | |
1086 | 230 // get only 20 annotations with this url |
1083 | 231 var query = { |
232 limit : 20, | |
233 uri : pageUrl | |
234 }; | |
235 $.ajax(url, { | |
236 dataType : 'json', | |
237 data : query, | |
238 headers : headers, | |
239 success : function(annotData, annotStatus) { | |
240 console.debug("got annotation data=", annotData); | |
241 data.annotationData = annotData; | |
242 parseAnnotations(data, annotData); | |
243 renderAnnotations(data); | |
244 } | |
245 }); | |
246 }; | |
247 | |
1086 | 248 /** |
249 * parse all JSON-annotations in annotationData.rows and put in data.annotations | |
250 */ | |
1083 | 251 var parseAnnotations = function(data, annotationData) { |
252 var annotations = []; | |
253 for (var i = 0; i < annotationData.rows.length; ++i) { | |
254 var ann = annotationData.rows[i]; | |
1101
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
255 var annot = parseAnnotation(data, ann); |
1083 | 256 if (annot != null) { |
257 annotations.push(annot); | |
258 } | |
259 } | |
260 data.annotations = annotations; | |
261 }; | |
262 | |
1086 | 263 /** |
264 * Parse a JSON-annotation. | |
265 * | |
266 * Returns an annotation object. | |
267 */ | |
1101
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
268 var parseAnnotation = function(data, ann) { |
1083 | 269 // TODO: check validity of annotation data |
1084 | 270 if (ann.areas != null && ann.areas.length > 0) { |
271 var area = ann.areas[0]; | |
1086 | 272 // currently only point annotations |
1084 | 273 var pos = geom.position(area.x, area.y); |
1101
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
274 return newAnnotation(data, pos, ann.text, ann.id, ann.uri, ann.user, ann.permissions, ann.tags); |
1083 | 275 } |
276 return null; | |
277 }; | |
278 | |
1086 | 279 /** |
280 * Store an annotation on the annotation server. | |
281 */ | |
1083 | 282 var storeAnnotation = function(data, annotation) { |
283 console.debug("storeAnnotation:", annotation); | |
284 var settings = data.settings; | |
285 var url = settings.annotationServerUrl + '/annotations'; | |
286 var pageUrl = getAnnotationPageUrl(data); | |
287 // send authentication token in header | |
288 headers = { | |
289 'x-annotator-auth-token' : data.annotationToken | |
290 }; | |
291 // create annotation object to send | |
292 var annotData = { | |
1084 | 293 areas : [{ |
294 x : annotation.pos.x, | |
295 y : annotation.pos.y | |
296 }], | |
1083 | 297 text : annotation.text, |
298 uri : pageUrl, | |
299 user : settings.annotationUser | |
300 }; | |
301 var dataString = JSON.stringify(annotData); | |
302 $.ajax(url, { | |
303 type : 'POST', | |
304 dataType : 'json', | |
305 contentType : 'application/json', | |
306 data : dataString, | |
307 headers : headers, | |
308 success : function(annotData, annotStatus) { | |
1084 | 309 console.debug("sent annotation data, got=", annotData, " status=" + annotStatus); |
1101
34f893492adb
annotations with nicer tooltips using jquery-tools.
robcast
parents:
1100
diff
changeset
|
310 var annot = parseAnnotation(data, annotData); |
1083 | 311 // TODO: we have to add the returned data to the real annotation! |
312 //renderAnnotations(data); | |
313 } | |
314 }); | |
315 | |
1086 | 316 }; |
317 | |
318 /** | |
319 * install additional buttons | |
320 */ | |
1083 | 321 var installButtons = function(data) { |
322 var settings = data.settings; | |
323 var mode = settings.interactionMode; | |
324 var buttonSettings = settings.buttonSettings[mode]; | |
325 // configure buttons through digilib "annotationSet" option | |
326 var buttonSet = settings.annotationSet || annotationSet; | |
327 // set annotationSet to [] or '' for no buttons (when showing annotations only) | |
328 if (buttonSet.length && buttonSet.length > 0) { | |
329 buttonSettings.annotationSet = buttonSet; | |
330 buttonSettings.buttonSets.push('annotationSet'); | |
331 } | |
332 }; | |
333 | |
1086 | 334 /** |
335 * plugin installation. called by digilib on plugin object. | |
336 */ | |
1083 | 337 var install = function(plugin) { |
338 digilib = plugin; | |
339 console.debug('installing annotations plugin. digilib:', digilib); | |
340 // import geometry classes | |
341 geom = digilib.fn.geometry; | |
342 FULL_AREA = geom.rectangle(0, 0, 1, 1); | |
343 // add defaults, actins, buttons | |
344 $.extend(digilib.defaults, defaults); | |
345 $.extend(digilib.actions, actions); | |
346 $.extend(digilib.buttons, buttons); | |
347 }; | |
348 | |
349 /** plugin initialization */ | |
350 var init = function(data) { | |
351 console.debug('initialising annotations plugin. data:', data); | |
352 var $data = $(data); | |
353 // set up | |
354 data.annotations = []; | |
355 if (digilib.plugins.buttons != null) { | |
356 installButtons(data); | |
357 } | |
358 // install event handler | |
359 $data.bind('setup', handleSetup); | |
360 $data.bind('update', handleUpdate); | |
361 }; | |
362 | |
1086 | 363 /** |
364 * setup loads all annotations. | |
365 */ | |
1083 | 366 var handleSetup = function(evt) { |
367 console.debug("annotations: handleSetup"); | |
368 var data = this; | |
369 // load annotations from server | |
370 loadAnnotationToken(data); | |
371 }; | |
372 | |
1086 | 373 /** |
374 * update renders all annotations. | |
375 */ | |
1083 | 376 var handleUpdate = function(evt) { |
377 console.debug("annotations: handleUpdate"); | |
378 var data = this; | |
379 if (data.marks != null) { | |
380 renderAnnotations(data); | |
381 } | |
382 }; | |
383 | |
384 // plugin object with name and init | |
385 // shared objects filled by digilib on registration | |
386 var plugin = { | |
387 name : 'annotations', | |
388 install : install, | |
389 init : init, | |
390 buttons : {}, | |
391 actions : {}, | |
392 fn : {}, | |
393 plugins : {} | |
394 }; | |
395 | |
396 if ($.fn.digilib == null) { | |
397 $.error("jquery.digilib.annotations must be loaded after jquery.digilib!"); | |
398 } else { | |
399 $.fn.digilib('plugin', plugin); | |
400 } | |
401 })(jQuery); |