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);