Mercurial > hg > digilib-old
comparison webapp/src/main/webapp/jquery/jquery.digilib.annotator.js @ 1115:526dafa4690d
using annotator in digilib works now. code still ugly.
author | robcast |
---|---|
date | Fri, 02 Nov 2012 20:49:51 +0100 |
parents | 1525c820ee27 |
children | 08206603c7dc |
comparison
equal
deleted
inserted
replaced
1114:1525c820ee27 | 1115:526dafa4690d |
---|---|
8 */ | 8 */ |
9 | 9 |
10 (function($) { | 10 (function($) { |
11 | 11 |
12 // affine geometry | 12 // affine geometry |
13 var geom; | 13 var geom = null; |
14 // plugin object with digilib data | 14 // plugin object with digilib data |
15 var digilib; | 15 var digilib = null; |
16 // our Annotator instance | 16 // our Annotator instance |
17 var annotator; | 17 var annotator = null; |
18 | |
19 var FULL_AREA; | |
20 | 18 |
21 var buttons = { | 19 var buttons = { |
22 annotations : { | 20 annotations : { |
23 onclick : "toggleAnnotations", | 21 onclick : "toggleAnnotations", |
24 tooltip : "show or hide annotations", | 22 tooltip : "show or hide annotations", |
35 icon : "annotation-mark.png" | 33 icon : "annotation-mark.png" |
36 } | 34 } |
37 }; | 35 }; |
38 | 36 |
39 var defaults = { | 37 var defaults = { |
40 'annotatorInstance' : null, | |
41 // are annotations active? | 38 // are annotations active? |
42 'isAnnotationsVisible' : true, | 39 'isAnnotationsVisible' : true, |
43 // buttonset of this plugin | 40 // buttonset of this plugin |
44 'annotationSet' : ['annotations', 'annotationuser', 'annotationmark', 'lessoptions'], | 41 'annotationSet' : ['annotations', 'annotationuser', 'annotationmark', 'lessoptions'], |
45 // URL of annotation server | 42 // URL of annotation server |
114 } | 111 } |
115 }, | 112 }, |
116 }; | 113 }; |
117 | 114 |
118 /** | 115 /** |
119 * create a new annotation object | |
120 */ | |
121 var newAnnotation = function (data, mpos, text, id, uri, user, permissions, tags) { | |
122 var annot = { | |
123 pos : mpos, | |
124 text : text, | |
125 id : id, | |
126 uri : uri, | |
127 user : user, | |
128 permissions : permissions, | |
129 tags : tags | |
130 }; | |
131 // TODO: use prototype? | |
132 annot.getUserName = data.settings.annotationServerUserString; | |
133 return annot; | |
134 }; | |
135 | |
136 /** | |
137 * returns an annotatable url to this digilib image | 116 * returns an annotatable url to this digilib image |
138 */ | 117 */ |
139 var getAnnotationPageUrl = function(data) { | 118 var getAnnotationPageUrl = function(data) { |
140 var url = data.settings.digilibBaseUrl + '/jquery/digilib.html?'; | 119 var url = data.settings.digilibBaseUrl + '/jquery/digilib.html?'; |
141 url += digilib.fn.getParamString(data.settings, ['fn', 'pn'], digilib.defaults); | 120 url += digilib.fn.getParamString(data.settings, ['fn', 'pn'], digilib.defaults); |
145 /** | 124 /** |
146 * add a mark-annotation where clicked. | 125 * add a mark-annotation where clicked. |
147 */ | 126 */ |
148 var setAnnotationMark = function(data) { | 127 var setAnnotationMark = function(data) { |
149 var $scaler = data.$scaler; | 128 var $scaler = data.$scaler; |
150 annotator = data.settings.annotatorInstance; | |
151 // unbind other handler TODO: do we need to do this? | 129 // unbind other handler TODO: do we need to do this? |
152 $scaler.off(".dlZoomDrag"); | 130 $scaler.off(".dlZoomDrag"); |
153 // start event capturing | 131 // start event capturing |
154 $scaler.one('mousedown.dlSetAnnotationMark', function(evt) { | 132 $scaler.one('mousedown.dlSetAnnotationMark', function(evt) { |
155 // event handler adding a new mark | 133 // event handler adding a new mark |
156 console.log("setAnnotationMark at=", evt); | 134 console.log("setAnnotationMark at=", evt); |
157 var mpos = geom.position(evt); | 135 var mpos = geom.position(evt); |
158 var pos = data.imgTrafo.invtransform(mpos); | 136 var pos = data.imgTrafo.invtransform(mpos); |
159 | 137 // mark selected areas |
160 console.debug("showing annotator editor!"); | 138 annotator.selectedAreas = [geom.rectangle(pos)]; |
139 // create and edit new annotation | |
161 var annotation = annotator.createAnnotation(); | 140 var annotation = annotator.createAnnotation(); |
162 annotation.areas = [geom.rectangle(pos)]; | |
163 annotator.showEditor(annotation, mpos.getAsCss()); | 141 annotator.showEditor(annotation, mpos.getAsCss()); |
164 | |
165 return false; | 142 return false; |
166 // Annotation text entered in JS-prompt | |
167 var text = window.prompt("Annotation text:"); | |
168 if (text == null) return false; | |
169 var annotation = newAnnotation(data, pos, text, null, null, data.settings.annotationUser); | |
170 storeAnnotation(data, annotation); | |
171 data.annotations.push(annotation); | |
172 digilib.fn.redisplay(data); | |
173 return false; | |
174 }); | 143 }); |
175 }; | 144 }; |
176 | 145 |
177 /** | 146 /** |
178 * place annotations on the image | 147 * place annotations on the image |
189 // clear annotations | 158 // clear annotations |
190 $elem.find('div.' + cssPrefix + 'annotationmark').remove(); | 159 $elem.find('div.' + cssPrefix + 'annotationmark').remove(); |
191 if (!data.settings.isAnnotationsVisible) return; | 160 if (!data.settings.isAnnotationsVisible) return; |
192 for (var i = 0; i < annotations.length; i++) { | 161 for (var i = 0; i < annotations.length; i++) { |
193 var annotation = annotations[i]; | 162 var annotation = annotations[i]; |
194 renderAnnotation(data, annotation, i+1); | 163 annotation.idx = i+1; |
195 } | 164 renderAnnotation(data, annotation); |
196 }; | 165 } |
197 | 166 }; |
198 /** | 167 |
199 * place annotation on the image | 168 /** |
200 */ | 169 * place single annotation on the image |
201 var renderAnnotation = function (data, annotation, idx) { | 170 */ |
171 var renderAnnotation = function (data, annotation) { | |
202 console.debug("renderAnnotation: annotation=", annotation); | 172 console.debug("renderAnnotation: annotation=", annotation); |
203 if (annotation == null || data.$img == null || data.imgTrafo == null) | 173 if (annotation == null || annotation.areas == null || data.$img == null || data.imgTrafo == null) |
204 return; | 174 return; |
175 if (!data.settings.isAnnotationsVisible) return; | |
205 var cssPrefix = data.settings.cssPrefix; | 176 var cssPrefix = data.settings.cssPrefix; |
206 var $elem = data.$elem; | 177 var $elem = data.$elem; |
178 var idx = annotation.idx; | |
207 if (idx == null) idx = '?'; | 179 if (idx == null) idx = '?'; |
208 // try to show annotation user state | |
209 $elem.find('div#'+cssPrefix+'button-annotationuser').attr('title', 'annotation user: '+data.settings.annotationUser); | |
210 if (!data.settings.isAnnotationsVisible) return; | |
211 var pos = geom.position(annotation.areas[0]); | 180 var pos = geom.position(annotation.areas[0]); |
212 if (data.zoomArea.containsPosition(pos)) { | 181 if (data.zoomArea.containsPosition(pos)) { |
213 var mpos = data.imgTrafo.transform(pos); | 182 var mpos = data.imgTrafo.transform(pos); |
214 console.debug("renderannotations: pos=", mpos); | 183 console.debug("renderannotations: pos=", mpos); |
215 // create annotation | 184 // create annotation |
216 var html = '<div class="'+cssPrefix+'annotationmark '+cssPrefix+'overlay annotator-hl">'+idx+'</div>'; | 185 var html = '<div class="'+cssPrefix+'annotationmark '+cssPrefix+'overlay annotator-hl">'+idx+'</div>'; |
217 var $annotation = $(html); | 186 var $annotation = $(html); |
187 // save annotation in data for Annotator | |
218 $annotation.data('annotation', annotation); | 188 $annotation.data('annotation', annotation); |
219 // set text as tooltip | 189 // save reference to div |
220 //$annotation.attr('title', "Annotation: " + annotation.text); | 190 annotation.$div = $annotation; |
221 $elem.append($annotation); | 191 $elem.append($annotation); |
192 // hook up Annotator events | |
222 $annotation.on("mouseover", annotator.onHighlightMouseover); | 193 $annotation.on("mouseover", annotator.onHighlightMouseover); |
223 $annotation.on("mouseout", annotator.startViewerHideTimer); | 194 $annotation.on("mouseout", annotator.startViewerHideTimer); |
224 mpos.adjustDiv($annotation); | 195 mpos.adjustDiv($annotation); |
225 } | 196 } |
226 }; | 197 }; |
252 data.settings.annotationUser = "anonymous"; | 223 data.settings.annotationUser = "anonymous"; |
253 //loadAnnotations(data); | 224 //loadAnnotations(data); |
254 }); | 225 }); |
255 }; | 226 }; |
256 | 227 |
257 /** | |
258 * loads all annotations for this url from the annotation server. | |
259 */ | |
260 var loadAnnotations = function(data) { | |
261 var settings = data.settings; | |
262 // we use the search API | |
263 var url = settings.annotationServerUrl + '/search'; | |
264 var pageUrl = getAnnotationPageUrl(data); | |
265 // send authentication token in header | |
266 headers = {}; | |
267 if (data.annotationToken != null) { | |
268 headers['x-annotator-auth-token'] = data.annotationToken; | |
269 } | |
270 // get only 20 annotations with this url | |
271 var query = { | |
272 limit : 20, | |
273 uri : pageUrl | |
274 }; | |
275 $.ajax(url, { | |
276 dataType : 'json', | |
277 data : query, | |
278 headers : headers, | |
279 success : function(annotData, annotStatus) { | |
280 console.debug("got annotation data=", annotData); | |
281 data.annotationData = annotData; | |
282 parseAnnotations(data, annotData); | |
283 renderAnnotations(data); | |
284 } | |
285 }); | |
286 }; | |
287 | |
288 /** | |
289 * parse all JSON-annotations in annotationData.rows and put in data.annotations | |
290 */ | |
291 var parseAnnotations = function(data, annotationData) { | |
292 var annotations = []; | |
293 for (var i = 0; i < annotationData.rows.length; ++i) { | |
294 var ann = annotationData.rows[i]; | |
295 var annot = parseAnnotation(data, ann); | |
296 if (annot != null) { | |
297 annotations.push(annot); | |
298 } | |
299 } | |
300 data.annotations = annotations; | |
301 }; | |
302 | |
303 /** | |
304 * Parse a JSON-annotation. | |
305 * | |
306 * Returns an annotation object. | |
307 */ | |
308 var parseAnnotation = function(data, ann) { | |
309 // TODO: check validity of annotation data | |
310 if (ann.areas != null && ann.areas.length > 0) { | |
311 var area = ann.areas[0]; | |
312 // currently only point annotations | |
313 var pos = geom.position(area.x, area.y); | |
314 return newAnnotation(data, pos, ann.text, ann.id, ann.uri, ann.user, ann.permissions, ann.tags); | |
315 } | |
316 return null; | |
317 }; | |
318 | |
319 /** | |
320 * Store an annotation on the annotation server. | |
321 */ | |
322 var storeAnnotation = function(data, annotation) { | |
323 console.debug("storeAnnotation:", annotation); | |
324 var settings = data.settings; | |
325 var url = settings.annotationServerUrl + '/annotations'; | |
326 var pageUrl = getAnnotationPageUrl(data); | |
327 // send authentication token in header | |
328 headers = { | |
329 'x-annotator-auth-token' : data.annotationToken | |
330 }; | |
331 // create annotation object to send | |
332 var annotData = { | |
333 areas : [{ | |
334 x : annotation.pos.x, | |
335 y : annotation.pos.y | |
336 }], | |
337 text : annotation.text, | |
338 uri : pageUrl, | |
339 user : settings.annotationUser | |
340 }; | |
341 var dataString = JSON.stringify(annotData); | |
342 $.ajax(url, { | |
343 type : 'POST', | |
344 dataType : 'json', | |
345 contentType : 'application/json', | |
346 data : dataString, | |
347 headers : headers, | |
348 success : function(annotData, annotStatus) { | |
349 console.debug("sent annotation data, got=", annotData, " status=" + annotStatus); | |
350 var annot = parseAnnotation(data, annotData); | |
351 // TODO: we have to add the returned data to the real annotation! | |
352 //renderAnnotations(data); | |
353 } | |
354 }); | |
355 | |
356 }; | |
357 | |
358 /** | 228 /** |
359 * install additional buttons | 229 * install additional buttons |
360 */ | 230 */ |
361 var installButtons = function(data) { | 231 var installButtons = function(data) { |
362 var settings = data.settings; | 232 var settings = data.settings; |
374 /** | 244 /** |
375 * plugin installation. called by digilib on plugin object. | 245 * plugin installation. called by digilib on plugin object. |
376 */ | 246 */ |
377 var install = function(plugin) { | 247 var install = function(plugin) { |
378 digilib = plugin; | 248 digilib = plugin; |
379 console.debug('installing annotations plugin. digilib:', digilib); | 249 console.debug('installing annotator plugin. digilib:', digilib); |
380 // import geometry classes | 250 // import geometry classes |
381 geom = digilib.fn.geometry; | 251 geom = digilib.fn.geometry; |
382 FULL_AREA = geom.rectangle(0, 0, 1, 1); | 252 FULL_AREA = geom.rectangle(0, 0, 1, 1); |
383 // add defaults, actins, buttons | 253 // add defaults, actins, buttons |
384 $.extend(digilib.defaults, defaults); | 254 $.extend(digilib.defaults, defaults); |
386 $.extend(digilib.buttons, buttons); | 256 $.extend(digilib.buttons, buttons); |
387 }; | 257 }; |
388 | 258 |
389 /** plugin initialization */ | 259 /** plugin initialization */ |
390 var init = function(data) { | 260 var init = function(data) { |
391 console.debug('initialising annotations plugin. data:', data); | 261 console.debug('initialising annotator plugin. data:', data); |
392 var $data = $(data); | 262 var $data = $(data); |
393 // set up | 263 // set up |
394 data.annotations = []; | 264 data.annotations = []; |
395 if (digilib.plugins.buttons != null) { | 265 if (digilib.plugins.buttons != null) { |
396 installButtons(data); | 266 installButtons(data); |
422 annotator = new Annotator(data.$elem.get(0)) | 292 annotator = new Annotator(data.$elem.get(0)) |
423 //.addPlugin('Tags') | 293 //.addPlugin('Tags') |
424 .addPlugin('Auth', { | 294 .addPlugin('Auth', { |
425 token : data.annotationToken, | 295 token : data.annotationToken, |
426 //tokenUrl: 'http://annotateit.org/api/token' | 296 //tokenUrl: 'http://annotateit.org/api/token' |
427 //tokenUrl: 'http://localhost:8080/test/annotator/token?user=anonymous' | |
428 //autoFetch: false | 297 //autoFetch: false |
429 }) | 298 }) |
430 .addPlugin('Permissions', { | 299 .addPlugin('Permissions', { |
431 user: data.settings.annotationUser, | 300 user: data.settings.annotationUser, |
432 userString: function (user) { | 301 userString: function (user) { |
442 return user; | 311 return user; |
443 } | 312 } |
444 }) | 313 }) |
445 .addPlugin('Store', { | 314 .addPlugin('Store', { |
446 prefix : data.settings.annotationServerUrl, | 315 prefix : data.settings.annotationServerUrl, |
447 //prefix: 'http://localhost:18080/AnnotationManager/annotator', | |
448 //prefix: 'http://tuxserve03.mpiwg-berlin.mpg.de/AnnotationManager/annotator', | |
449 //prefix: 'http://annotateit.org/api', | |
450 annotationData: { | 316 annotationData: { |
451 'uri': uri | 317 'uri': uri |
452 }, | 318 }, |
453 loadFromSearch: { | 319 loadFromSearch: { |
454 'limit': 20, | 320 'limit': 20, |
456 } | 322 } |
457 }) | 323 }) |
458 ; | 324 ; |
459 | 325 |
460 // monkey-patch Annotator.setupAnnotation | 326 // monkey-patch Annotator.setupAnnotation |
327 annotator.setupRangeAnnotation = annotator.setupAnnotation; | |
461 annotator.setupAnnotation = function(annotation, fireEvents) { | 328 annotator.setupAnnotation = function(annotation, fireEvents) { |
462 if (fireEvents == null) { | 329 if (annotator.selectedAreas == null && annotation.areas == null) { |
463 fireEvents = true; | 330 // pass call to original method |
464 } | 331 return annotator.setupRangeAnnotation.apply(this, arguments); |
465 | 332 } else { |
466 renderAnnotation(data, annotation); | 333 // set up digilib-area annotation |
467 | 334 if (fireEvents == null) { |
468 if (fireEvents) { | 335 fireEvents = true; |
469 this.publish('annotationCreated', [annotation]); | 336 } |
470 } | 337 if (annotation.areas == null) { |
471 return annotation; | 338 annotation.areas = annotator.selectedAreas; |
339 } | |
340 // compatibility crap | |
341 annotation.highlights = []; | |
342 // pre-render this annotation | |
343 renderAnnotation(data, annotation); | |
344 if (fireEvents) { | |
345 this.publish('annotationCreated', [annotation]); | |
346 } | |
347 return annotation; | |
348 } | |
472 }; | 349 }; |
473 | 350 |
474 | 351 // hook Annotator events |
475 data.settings.annotatorInstance = annotator; | 352 annotator.subscribe('annotationDeleted', function (ann) { |
476 /* load annotations from server | 353 console.debug("got annotationDeleted!"); |
477 if (data.annotationToken != null) { | 354 if (ann.$div != null) { |
478 loadAnnotations(data); | 355 ann.$div.remove(); |
479 } else { | 356 delete ann.$div; |
480 loadAnnotationToken(data); | 357 } |
481 } */ | 358 }); |
359 | |
360 // TODO: should we really export annotator? | |
361 data.annotator = annotator; | |
482 }; | 362 }; |
483 | 363 |
484 /** | 364 /** |
485 * update renders all annotations. | 365 * update renders all annotations. |
486 */ | 366 */ |
491 }; | 371 }; |
492 | 372 |
493 // plugin object with name and init | 373 // plugin object with name and init |
494 // shared objects filled by digilib on registration | 374 // shared objects filled by digilib on registration |
495 var plugin = { | 375 var plugin = { |
496 name : 'annotations', | 376 name : 'annotator', |
497 install : install, | 377 install : install, |
498 init : init, | 378 init : init, |
499 buttons : {}, | 379 buttons : {}, |
500 actions : {}, | 380 actions : {}, |
501 fn : {}, | 381 fn : {}, |
502 plugins : {} | 382 plugins : {} |
503 }; | 383 }; |
504 | 384 |
505 if ($.fn.digilib == null) { | 385 if ($.fn.digilib == null) { |
506 $.error("jquery.digilib.annotations must be loaded after jquery.digilib!"); | 386 $.error("jquery.digilib.annotator must be loaded after jquery.digilib!"); |
507 } else { | 387 } else { |
508 $.fn.digilib('plugin', plugin); | 388 $.fn.digilib('plugin', plugin); |
509 } | 389 } |
510 })(jQuery); | 390 })(jQuery); |