comparison annotator_files/lib/annotator.js @ 4:6979313586cf

new version of annotator.
author casties
date Mon, 27 Aug 2012 19:05:38 +0200
parents 6356e78ccf5c
children
comparison
equal deleted inserted replaced
3:6356e78ccf5c 4:6979313586cf
1 var Annotator, util, _Annotator, 1 // Generated by CoffeeScript 1.3.3
2 var Annotator, g, util, _Annotator, _ref,
2 __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, 3 __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
3 __hasProp = Object.prototype.hasOwnProperty, 4 __hasProp = {}.hasOwnProperty,
4 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; 5 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
5 6
6 util = { 7 util = {
7 uuid: (function() { 8 uuid: (function() {
8 var counter; 9 var counter;
9 counter = 0; 10 counter = 0;
14 getGlobal: function() { 15 getGlobal: function() {
15 return (function() { 16 return (function() {
16 return this; 17 return this;
17 })(); 18 })();
18 }, 19 },
20 maxZIndex: function($elements) {
21 var all, el;
22 all = (function() {
23 var _i, _len, _results;
24 _results = [];
25 for (_i = 0, _len = $elements.length; _i < _len; _i++) {
26 el = $elements[_i];
27 if ($(el).css('position') === 'static') {
28 _results.push(-1);
29 } else {
30 _results.push(parseInt($(el).css('z-index'), 10) || -1);
31 }
32 }
33 return _results;
34 })();
35 return Math.max.apply(Math, all);
36 },
19 mousePosition: function(e, offsetEl) { 37 mousePosition: function(e, offsetEl) {
20 var offset; 38 var offset;
21 offset = $(offsetEl).offset(); 39 offset = $(offsetEl).offset();
22 return { 40 return {
23 top: e.pageY - offset.top, 41 top: e.pageY - offset.top,
41 ".annotator-hl mouseover": "onHighlightMouseover", 59 ".annotator-hl mouseover": "onHighlightMouseover",
42 ".annotator-hl mouseout": "startViewerHideTimer" 60 ".annotator-hl mouseout": "startViewerHideTimer"
43 }; 61 };
44 62
45 Annotator.prototype.html = { 63 Annotator.prototype.html = {
46 hl: '<span class="annotator-hl"></span>',
47 adder: '<div class="annotator-adder"><button>' + _t('Annotate') + '</button></div>', 64 adder: '<div class="annotator-adder"><button>' + _t('Annotate') + '</button></div>',
48 wrapper: '<div class="annotator-wrapper"></div>' 65 wrapper: '<div class="annotator-wrapper"></div>'
49 }; 66 };
50 67
51 Annotator.prototype.options = { 68 Annotator.prototype.options = {
66 83
67 Annotator.prototype.viewerHideTimer = null; 84 Annotator.prototype.viewerHideTimer = null;
68 85
69 function Annotator(element, options) { 86 function Annotator(element, options) {
70 this.onDeleteAnnotation = __bind(this.onDeleteAnnotation, this); 87 this.onDeleteAnnotation = __bind(this.onDeleteAnnotation, this);
88
71 this.onEditAnnotation = __bind(this.onEditAnnotation, this); 89 this.onEditAnnotation = __bind(this.onEditAnnotation, this);
90
72 this.onAdderClick = __bind(this.onAdderClick, this); 91 this.onAdderClick = __bind(this.onAdderClick, this);
92
73 this.onAdderMousedown = __bind(this.onAdderMousedown, this); 93 this.onAdderMousedown = __bind(this.onAdderMousedown, this);
94
74 this.onHighlightMouseover = __bind(this.onHighlightMouseover, this); 95 this.onHighlightMouseover = __bind(this.onHighlightMouseover, this);
96
75 this.checkForEndSelection = __bind(this.checkForEndSelection, this); 97 this.checkForEndSelection = __bind(this.checkForEndSelection, this);
98
76 this.checkForStartSelection = __bind(this.checkForStartSelection, this); 99 this.checkForStartSelection = __bind(this.checkForStartSelection, this);
100
77 this.clearViewerHideTimer = __bind(this.clearViewerHideTimer, this); 101 this.clearViewerHideTimer = __bind(this.clearViewerHideTimer, this);
102
78 this.startViewerHideTimer = __bind(this.startViewerHideTimer, this); 103 this.startViewerHideTimer = __bind(this.startViewerHideTimer, this);
104
79 this.showViewer = __bind(this.showViewer, this); 105 this.showViewer = __bind(this.showViewer, this);
106
80 this.onEditorSubmit = __bind(this.onEditorSubmit, this); 107 this.onEditorSubmit = __bind(this.onEditorSubmit, this);
108
81 this.onEditorHide = __bind(this.onEditorHide, this); 109 this.onEditorHide = __bind(this.onEditorHide, this);
110
82 this.showEditor = __bind(this.showEditor, this); 111 this.showEditor = __bind(this.showEditor, this);
83 var name, src, _ref;
84 Annotator.__super__.constructor.apply(this, arguments); 112 Annotator.__super__.constructor.apply(this, arguments);
85 this.plugins = {}; 113 this.plugins = {};
86 if (!Annotator.supported()) return this; 114 if (!Annotator.supported()) {
87 if (!this.options.readOnly) this._setupDocumentEvents(); 115 return this;
116 }
117 if (!this.options.readOnly) {
118 this._setupDocumentEvents();
119 }
88 this._setupWrapper()._setupViewer()._setupEditor(); 120 this._setupWrapper()._setupViewer()._setupEditor();
89 _ref = this.html; 121 this._setupDynamicStyle();
90 for (name in _ref) { 122 this.adder = $(this.html.adder).appendTo(this.wrapper).hide();
91 src = _ref[name];
92 if (name !== 'wrapper') this[name] = $(src).appendTo(this.wrapper).hide();
93 }
94 } 123 }
95 124
96 Annotator.prototype._setupWrapper = function() { 125 Annotator.prototype._setupWrapper = function() {
97 this.wrapper = $(this.html.wrapper); 126 this.wrapper = $(this.html.wrapper);
98 this.element.find('script').remove(); 127 this.element.find('script').remove();
144 "mousedown": this.checkForStartSelection 173 "mousedown": this.checkForStartSelection
145 }); 174 });
146 return this; 175 return this;
147 }; 176 };
148 177
178 Annotator.prototype._setupDynamicStyle = function() {
179 var max, sel, style, x;
180 style = $('#annotator-dynamic-style');
181 if (!style.length) {
182 style = $('<style id="annotator-dynamic-style"></style>').appendTo(document.head);
183 }
184 sel = '*' + ((function() {
185 var _i, _len, _ref, _results;
186 _ref = ['adder', 'outer', 'notice', 'filter'];
187 _results = [];
188 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
189 x = _ref[_i];
190 _results.push(":not(.annotator-" + x + ")");
191 }
192 return _results;
193 })()).join('');
194 max = util.maxZIndex($(document.body).find(sel));
195 max = Math.max(max, 1000);
196 style.text([".annotator-adder, .annotator-outer, .annotator-notice {", " z-index: " + (max + 20) + ";", "}", ".annotator-filter {", " z-index: " + (max + 10) + ";", "}"].join("\n"));
197 return this;
198 };
199
149 Annotator.prototype.getSelectedRanges = function() { 200 Annotator.prototype.getSelectedRanges = function() {
150 var browserRange, i, normedRange, r, ranges, rangesToIgnore, selection, _i, _len; 201 var browserRange, i, normedRange, r, ranges, rangesToIgnore, selection, _i, _len;
151 selection = util.getGlobal().getSelection(); 202 selection = util.getGlobal().getSelection();
152 ranges = []; 203 ranges = [];
153 rangesToIgnore = []; 204 rangesToIgnore = [];
154 if (!selection.isCollapsed) { 205 if (!selection.isCollapsed) {
155 ranges = (function() { 206 ranges = (function() {
156 var _ref, _results; 207 var _i, _ref, _results;
157 _results = []; 208 _results = [];
158 for (i = 0, _ref = selection.rangeCount; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) { 209 for (i = _i = 0, _ref = selection.rangeCount; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
159 r = selection.getRangeAt(i); 210 r = selection.getRangeAt(i);
160 browserRange = new Range.BrowserRange(r); 211 browserRange = new Range.BrowserRange(r);
161 normedRange = browserRange.normalize().limit(this.wrapper[0]); 212 normedRange = browserRange.normalize().limit(this.wrapper[0]);
162 if (normedRange === null) rangesToIgnore.push(r); 213 if (normedRange === null) {
214 rangesToIgnore.push(r);
215 }
163 _results.push(normedRange); 216 _results.push(normedRange);
164 } 217 }
165 return _results; 218 return _results;
166 }).call(this); 219 }).call(this);
167 selection.removeAllRanges(); 220 selection.removeAllRanges();
169 for (_i = 0, _len = rangesToIgnore.length; _i < _len; _i++) { 222 for (_i = 0, _len = rangesToIgnore.length; _i < _len; _i++) {
170 r = rangesToIgnore[_i]; 223 r = rangesToIgnore[_i];
171 selection.addRange(r); 224 selection.addRange(r);
172 } 225 }
173 return $.grep(ranges, function(range) { 226 return $.grep(ranges, function(range) {
174 if (range) selection.addRange(range.toRange()); 227 if (range) {
228 selection.addRange(range.toRange());
229 }
175 return range; 230 return range;
176 }); 231 });
177 }; 232 };
178 233
179 Annotator.prototype.createAnnotation = function() { 234 Annotator.prototype.createAnnotation = function() {
182 this.publish('beforeAnnotationCreated', [annotation]); 237 this.publish('beforeAnnotationCreated', [annotation]);
183 return annotation; 238 return annotation;
184 }; 239 };
185 240
186 Annotator.prototype.setupAnnotation = function(annotation, fireEvents) { 241 Annotator.prototype.setupAnnotation = function(annotation, fireEvents) {
187 var normed, normedRanges, r, sniffed, _i, _len; 242 var normed, normedRanges, r, root, _i, _j, _len, _len1, _ref;
188 if (fireEvents == null) fireEvents = true; 243 if (fireEvents == null) {
244 fireEvents = true;
245 }
246 root = this.wrapper[0];
189 annotation.ranges || (annotation.ranges = this.selectedRanges); 247 annotation.ranges || (annotation.ranges = this.selectedRanges);
190 normedRanges = (function() { 248 normedRanges = [];
191 var _i, _len, _ref, _results; 249 _ref = annotation.ranges;
192 _ref = annotation.ranges; 250 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
193 _results = []; 251 r = _ref[_i];
194 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 252 try {
195 r = _ref[_i]; 253 normedRanges.push(Range.sniff(r).normalize(root));
196 if (!(r != null)) continue; 254 } catch (e) {
197 sniffed = Range.sniff(r); 255 if (e instanceof Range.RangeError) {
198 _results.push(sniffed.normalize(this.wrapper[0])); 256 this.publish('rangeNormalizeFail', [annotation, r, e]);
199 } 257 } else {
200 return _results; 258 throw e;
201 }).call(this); 259 }
202 normedRanges = $.grep(normedRanges, function(range) { 260 }
203 return range !== null; 261 }
204 });
205 annotation.quote = []; 262 annotation.quote = [];
206 annotation.ranges = []; 263 annotation.ranges = [];
207 annotation.highlights = []; 264 annotation.highlights = [];
208 for (_i = 0, _len = normedRanges.length; _i < _len; _i++) { 265 for (_j = 0, _len1 = normedRanges.length; _j < _len1; _j++) {
209 normed = normedRanges[_i]; 266 normed = normedRanges[_j];
210 annotation.quote.push($.trim(normed.text())); 267 annotation.quote.push($.trim(normed.text()));
211 annotation.ranges.push(normed.serialize(this.wrapper[0], '.annotator-hl')); 268 annotation.ranges.push(normed.serialize(this.wrapper[0], '.annotator-hl'));
212 $.merge(annotation.highlights, this.highlightRange(normed)); 269 $.merge(annotation.highlights, this.highlightRange(normed));
213 } 270 }
214 annotation.quote = annotation.quote.join(' / '); 271 annotation.quote = annotation.quote.join(' / ');
215 $(annotation.highlights).data('annotation', annotation); 272 $(annotation.highlights).data('annotation', annotation);
216 if (fireEvents) this.publish('annotationCreated', [annotation]); 273 if (fireEvents) {
274 this.publish('annotationCreated', [annotation]);
275 }
217 return annotation; 276 return annotation;
218 }; 277 };
219 278
220 Annotator.prototype.updateAnnotation = function(annotation) { 279 Annotator.prototype.updateAnnotation = function(annotation) {
221 this.publish('beforeAnnotationUpdated', [annotation]); 280 this.publish('beforeAnnotationUpdated', [annotation]);
235 }; 294 };
236 295
237 Annotator.prototype.loadAnnotations = function(annotations) { 296 Annotator.prototype.loadAnnotations = function(annotations) {
238 var clone, loader, 297 var clone, loader,
239 _this = this; 298 _this = this;
240 if (annotations == null) annotations = []; 299 if (annotations == null) {
300 annotations = [];
301 }
241 loader = function(annList) { 302 loader = function(annList) {
242 var n, now, _i, _len; 303 var n, now, _i, _len;
243 if (annList == null) annList = []; 304 if (annList == null) {
305 annList = [];
306 }
244 now = annList.splice(0, 10); 307 now = annList.splice(0, 10);
245 for (_i = 0, _len = now.length; _i < _len; _i++) { 308 for (_i = 0, _len = now.length; _i < _len; _i++) {
246 n = now[_i]; 309 n = now[_i];
247 _this.setupAnnotation(n, false); 310 _this.setupAnnotation(n, false);
248 } 311 }
249 if (annList.length > 0) { 312 if (annList.length > 0) {
250 return setTimeout((function() { 313 return setTimeout((function() {
251 return loader(annList); 314 return loader(annList);
252 }), 1); 315 }), 10);
253 } else { 316 } else {
254 return _this.publish('annotationsLoaded', [clone]); 317 return _this.publish('annotationsLoaded', [clone]);
255 } 318 }
256 }; 319 };
257 clone = annotations.slice(); 320 clone = annotations.slice();
258 if (annotations.length) loader(annotations); 321 if (annotations.length) {
322 loader(annotations);
323 }
259 return this; 324 return this;
260 }; 325 };
261 326
262 Annotator.prototype.dumpAnnotations = function() { 327 Annotator.prototype.dumpAnnotations = function() {
263 if (this.plugins['Store']) { 328 if (this.plugins['Store']) {
265 } else { 330 } else {
266 return console.warn(_t("Can't dump annotations without Store plugin.")); 331 return console.warn(_t("Can't dump annotations without Store plugin."));
267 } 332 }
268 }; 333 };
269 334
270 Annotator.prototype.highlightRange = function(normedRange) { 335 Annotator.prototype.highlightRange = function(normedRange, cssClass) {
271 var node, white, _i, _len, _ref, _results; 336 var hl, node, white, _i, _len, _ref, _results;
337 if (cssClass == null) {
338 cssClass = 'annotator-hl';
339 }
272 white = /^\s*$/; 340 white = /^\s*$/;
341 hl = $("<span class='" + cssClass + "'></span>");
273 _ref = normedRange.textNodes(); 342 _ref = normedRange.textNodes();
274 _results = []; 343 _results = [];
275 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 344 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
276 node = _ref[_i]; 345 node = _ref[_i];
277 if (!white.test(node.nodeValue)) { 346 if (!white.test(node.nodeValue)) {
278 _results.push($(node).wrapAll(this.hl).parent().show()[0]); 347 _results.push($(node).wrapAll(hl).parent().show()[0]);
279 } 348 }
280 } 349 }
281 return _results; 350 return _results;
351 };
352
353 Annotator.prototype.highlightRanges = function(normedRanges, cssClass) {
354 var highlights, r, _i, _len;
355 if (cssClass == null) {
356 cssClass = 'annotator-hl';
357 }
358 highlights = [];
359 for (_i = 0, _len = normedRanges.length; _i < _len; _i++) {
360 r = normedRanges[_i];
361 $.merge(highlights, this.highlightRange(r, cssClass));
362 }
363 return highlights;
282 }; 364 };
283 365
284 Annotator.prototype.addPlugin = function(name, options) { 366 Annotator.prototype.addPlugin = function(name, options) {
285 var klass, _base; 367 var klass, _base;
286 if (this.plugins[name]) { 368 if (this.plugins[name]) {
301 }; 383 };
302 384
303 Annotator.prototype.showEditor = function(annotation, location) { 385 Annotator.prototype.showEditor = function(annotation, location) {
304 this.editor.element.css(location); 386 this.editor.element.css(location);
305 this.editor.load(annotation); 387 this.editor.load(annotation);
388 this.publish('annotationEditorShown', [this.editor, annotation]);
306 return this; 389 return this;
307 }; 390 };
308 391
309 Annotator.prototype.onEditorHide = function() { 392 Annotator.prototype.onEditorHide = function() {
310 this.publish('annotationEditorHidden', [this.editor]); 393 this.publish('annotationEditorHidden', [this.editor]);
345 }; 428 };
346 429
347 Annotator.prototype.checkForEndSelection = function(event) { 430 Annotator.prototype.checkForEndSelection = function(event) {
348 var container, range, _i, _len, _ref; 431 var container, range, _i, _len, _ref;
349 this.mouseIsDown = false; 432 this.mouseIsDown = false;
350 if (this.ignoreMouseup) return; 433 if (this.ignoreMouseup) {
434 return;
435 }
351 this.selectedRanges = this.getSelectedRanges(); 436 this.selectedRanges = this.getSelectedRanges();
352 _ref = this.selectedRanges; 437 _ref = this.selectedRanges;
353 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 438 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
354 range = _ref[_i]; 439 range = _ref[_i];
355 container = range.commonAncestor; 440 container = range.commonAncestor;
356 if (this.isAnnotator(container)) return; 441 if ($(container).hasClass('annotator-hl')) {
442 container = $(container).parents('[class^=annotator-hl]')[0];
443 }
444 if (this.isAnnotator(container)) {
445 return;
446 }
357 } 447 }
358 if (event && this.selectedRanges.length) { 448 if (event && this.selectedRanges.length) {
359 return this.adder.css(util.mousePosition(event, this.wrapper[0])).show(); 449 return this.adder.css(util.mousePosition(event, this.wrapper[0])).show();
360 } else { 450 } else {
361 return this.adder.hide(); 451 return this.adder.hide();
367 }; 457 };
368 458
369 Annotator.prototype.onHighlightMouseover = function(event) { 459 Annotator.prototype.onHighlightMouseover = function(event) {
370 var annotations; 460 var annotations;
371 this.clearViewerHideTimer(); 461 this.clearViewerHideTimer();
372 if (this.mouseIsDown || this.viewer.isShown()) return false; 462 if (this.mouseIsDown || this.viewer.isShown()) {
463 return false;
464 }
373 annotations = $(event.target).parents('.annotator-hl').andSelf().map(function() { 465 annotations = $(event.target).parents('.annotator-hl').andSelf().map(function() {
374 return $(this).data("annotation"); 466 return $(this).data("annotation");
375 }); 467 });
376 return this.showViewer($.makeArray(annotations), util.mousePosition(event, this.wrapper[0])); 468 return this.showViewer($.makeArray(annotations), util.mousePosition(event, this.wrapper[0]));
377 }; 469 };
378 470
379 Annotator.prototype.onAdderMousedown = function(event) { 471 Annotator.prototype.onAdderMousedown = function(event) {
380 if (event != null) event.preventDefault(); 472 if (event != null) {
473 event.preventDefault();
474 }
381 return this.ignoreMouseup = true; 475 return this.ignoreMouseup = true;
382 }; 476 };
383 477
384 Annotator.prototype.onAdderClick = function(event) { 478 Annotator.prototype.onAdderClick = function(event) {
385 var position; 479 var highlights, position, r, ranges;
386 if (event != null) event.preventDefault(); 480 if (event != null) {
481 event.preventDefault();
482 }
387 position = this.adder.position(); 483 position = this.adder.position();
388 this.adder.hide(); 484 this.adder.hide();
485 if (this.selectedRanges && this.selectedRanges.length) {
486 ranges = (function() {
487 var _i, _len, _ref, _results;
488 _ref = this.selectedRanges;
489 _results = [];
490 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
491 r = _ref[_i];
492 _results.push(Range.sniff(r).normalize());
493 }
494 return _results;
495 }).call(this);
496 highlights = this.highlightRanges(ranges, 'annotator-hl annotator-hl-temporary');
497 this.editor.element.one('hide', function() {
498 var h, _i, _len, _results;
499 _results = [];
500 for (_i = 0, _len = highlights.length; _i < _len; _i++) {
501 h = highlights[_i];
502 _results.push($(h).replaceWith(h.childNodes));
503 }
504 return _results;
505 });
506 }
389 return this.showEditor(this.createAnnotation(), position); 507 return this.showEditor(this.createAnnotation(), position);
390 }; 508 };
391 509
392 Annotator.prototype.onEditAnnotation = function(annotation) { 510 Annotator.prototype.onEditAnnotation = function(annotation) {
393 var offset; 511 var offset;
417 535
418 return Plugin; 536 return Plugin;
419 537
420 })(Delegator); 538 })(Delegator);
421 539
540 g = util.getGlobal();
541
542 if (!(((_ref = g.document) != null ? _ref.evaluate : void 0) != null)) {
543 $.getScript('http://assets.annotateit.org/vendor/xpath.min.js');
544 }
545
546 if (!(g.getSelection != null)) {
547 $.getScript('http://assets.annotateit.org/vendor/ierange.min.js');
548 }
549
550 if (!(g.JSON != null)) {
551 $.getScript('http://assets.annotateit.org/vendor/json2.min.js');
552 }
553
422 Annotator.$ = $; 554 Annotator.$ = $;
423 555
424 Annotator.Delegator = Delegator; 556 Annotator.Delegator = Delegator;
425 557
426 Annotator.Range = Range; 558 Annotator.Range = Range;