source: main/trunk/model-cols-dev/peijones/js/annotator/pkg/annotator-full.min.js@ 24947

Last change on this file since 24947 was 24947, checked in by papitha, 12 years ago

Latest Annotator

File size: 82.0 KB
Line 
1(function () {
2 var h, o, b, p, n, i, l, a, e, d, c, r, s, j;
3 var m = Array.prototype.slice,
4 g = function (t, u) {
5 return function () {
6 return t.apply(u, arguments)
7 }
8 },
9 k = Object.prototype.hasOwnProperty,
10 q = function (w, u) {
11 for (var t in u) {
12 if (k.call(u, t)) {
13 w[t] = u[t]
14 }
15 }
16 function v() {
17 this.constructor = w
18 }
19 v.prototype = u.prototype;
20 w.prototype = new v;
21 w.__super__ = u.prototype;
22 return w
23 },
24 f = Array.prototype.indexOf ||
25 function (v) {
26 for (var u = 0, t = this.length; u < t; u++) {
27 if (this[u] === v) {
28 return u
29 }
30 }
31 return -1
32 };
33 if (!(typeof jQuery !== "undefined" && jQuery !== null ? (j = jQuery.fn) != null ? j.jquery : void 0 : void 0)) {
34 console.error("Annotator requires jQuery: have you included lib/vendor/jquery.js?")
35 }
36 if (!(JSON && JSON.parse && JSON.stringify)) {
37 console.error("Annotator requires a JSON implementation: have you included lib/vendor/json2.js?")
38 }
39 h = jQuery.sub();
40 h.flatten = function (u) {
41 var t;
42 t = function (w) {
43 var x, z, y, v;
44 z = [];
45 for (y = 0, v = w.length; y < v; y++) {
46 x = w[y];
47 z = z.concat(x && h.isArray(x) ? t(x) : x)
48 }
49 return z
50 };
51 return t(u)
52 };
53 h.plugin = function (u, t) {
54 return jQuery.fn[u] = function (w) {
55 var v;
56 v = Array.prototype.slice.call(arguments, 1);
57 return this.each(function () {
58 var x;
59 x = h.data(this, u);
60 if (x) {
61 return w && x[w].apply(x, v)
62 } else {
63 x = new t(this, w);
64 return h.data(this, u, x)
65 }
66 })
67 }
68 };
69 h.fn.textNodes = function () {
70 var t;
71 t = function (v) {
72 var u;
73 if (v && v.nodeType !== 3) {
74 u = [];
75 if (v.nodeType !== 8) {
76 v = v.lastChild;
77 while (v) {
78 u.push(t(v));
79 v = v.previousSibling
80 }
81 }
82 return u.reverse()
83 } else {
84 return v
85 }
86 };
87 return this.map(function () {
88 return h.flatten(t(this))
89 })
90 };
91 h.fn.xpath = function (t) {
92 var u;
93 u = this.map(function () {
94 var w, v, x;
95 x = "";
96 w = this;
97 while (w && w.nodeType === 1 && w !== t) {
98 v = h(w.parentNode).children(w.tagName).index(w) + 1;
99 v = v > 1 ? "[" + v + "]" : "";
100 x = "/" + w.tagName.toLowerCase() + v + x;
101 w = w.parentNode
102 }
103 return x
104 });
105 return u.get()
106 };
107 h.escape = function (t) {
108 return t.replace(/&(?!\w+;)/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;")
109 };
110 h.fn.escape = function (t) {
111 if (arguments.length) {
112 return this.html(h.escape(t))
113 }
114 return this.html()
115 };
116 l = ["log", "debug", "info", "warn", "exception", "assert", "dir", "dirxml", "trace", "group", "groupEnd", "groupCollapsed", "time", "timeEnd", "profile", "profileEnd", "count", "clear", "table", "error", "notifyFirebug", "firebug", "userObjects"];
117 if (typeof console !== "undefined" && console !== null) {
118 if (!(console.group != null)) {
119 console.group = function (t) {
120 return console.log("GROUP: ", t)
121 }
122 }
123 if (!(console.groupCollapsed != null)) {
124 console.groupCollapsed = console.group
125 }
126 for (d = 0, r = l.length; d < r; d++) {
127 i = l[d];
128 if (!(console[i] != null)) {
129 console[i] = function () {
130 return console.log("Not implemented: console." + name)
131 }
132 }
133 }
134 } else {
135 this.console = {};
136 for (c = 0, s = l.length; c < s; c++) {
137 i = l[c];
138 this.console[i] = function () {}
139 }
140 this.console.error = function () {
141 var t;
142 t = 1 <= arguments.length ? m.call(arguments, 0) : [];
143 return alert("ERROR: " + (t.join(", ")))
144 };
145 this.console.warn = function () {
146 var t;
147 t = 1 <= arguments.length ? m.call(arguments, 0) : [];
148 return alert("WARNING: " + (t.join(", ")))
149 }
150 }
151 b = (function () {
152 t.prototype.events = {};
153 t.prototype.options = {};
154 t.prototype.element = null;
155
156 function t(v, u) {
157 this.options = h.extend(true, {}, this.options, u);
158 this.element = h(v);
159 this.on = this.subscribe;
160 this.addEvents()
161 }
162 t.prototype.addEvents = function () {
163 var x, z, y, u, w, B, A, v;
164 B = this.events;
165 v = [];
166 for (y in B) {
167 z = B[y];
168 A = y.split(" "), u = 2 <= A.length ? m.call(A, 0, w = A.length - 1) : (w = 0, []), x = A[w++];
169 v.push(this.addEvent(u.join(" "), x, z))
170 }
171 return v
172 };
173 t.prototype.addEvent = function (u, w, x) {
174 var y, v;
175 y = g(function () {
176 return this[x].apply(this, arguments)
177 }, this);
178 v = typeof u === "string" && u.replace(/\s+/g, "") === "";
179 if (v) {
180 u = this.element
181 }
182 if (typeof u === "string") {
183 this.element.delegate(u, w, y)
184 } else {
185 if (this.isCustomEvent(w)) {
186 this.subscribe(w, y)
187 } else {
188 h(u).bind(w, y)
189 }
190 }
191 return this
192 };
193 t.prototype.isCustomEvent = function (v) {
194 var u;
195 u = "blur focus focusin focusout load resize scroll unload click dblclick\nmousedown mouseup mousemove mouseover mouseout mouseenter mouseleave\nchange select submit keydown keypress keyup error".split(/[^a-z]+/);
196 v = v.split(".")[0];
197 return h.inArray(v, u) === -1
198 };
199 t.prototype.publish = function () {
200 this.element.triggerHandler.apply(this.element, arguments);
201 return this
202 };
203 t.prototype.subscribe = function (u, w) {
204 var v;
205 v = function () {
206 return w.apply(this, [].slice.call(arguments, 1))
207 };
208 v.guid = w.guid = (h.guid += 1);
209 this.element.bind(u, v);
210 return this
211 };
212 t.prototype.unsubscribe = function () {
213 this.element.unbind.apply(this.element, arguments);
214 return this
215 };
216 return t
217 })();
218 p = {};
219 p.sniff = function (t) {
220 if (t.commonAncestorContainer != null) {
221 return new p.BrowserRange(t)
222 } else {
223 if (typeof t.start === "string") {
224 return new p.SerializedRange(t)
225 } else {
226 if (t.start && typeof t.start === "object") {
227 return new p.NormalizedRange(t)
228 } else {
229 console.error("Couldn't not sniff range type");
230 return false
231 }
232 }
233 }
234 };
235 p.BrowserRange = (function () {
236 function t(u) {
237 this.commonAncestorContainer = u.commonAncestorContainer;
238 this.startContainer = u.startContainer;
239 this.startOffset = u.startOffset;
240 this.endContainer = u.endContainer;
241 this.endOffset = u.endOffset
242 }
243 t.prototype.normalize = function (C) {
244 var B, x, D, A, w, v, z, u, y;
245 if (this.tainted) {
246 console.error("You may only call normalize() once on a BrowserRange!");
247 return false
248 } else {
249 this.tainted = true
250 }
251 v = {};
252 D = {};
253 y = ["start", "end"];
254 for (z = 0, u = y.length; z < u; z++) {
255 w = y[z];
256 x = this[w + "Container"];
257 A = this[w + "Offset"];
258 if (x.nodeType === 1) {
259 B = x.childNodes[A];
260 x = B || x.childNodes[A - 1];
261 while (x.nodeType !== 3) {
262 x = x.firstChild
263 }
264 A = B ? 0 : x.nodeValue.length
265 }
266 v[w] = x;
267 v[w + "Offset"] = A
268 }
269 D.start = v.startOffset > 0 ? v.start.splitText(v.startOffset) : v.start;
270 if (v.start === v.end) {
271 if ((v.endOffset - v.startOffset) < D.start.nodeValue.length) {
272 D.start.splitText(v.endOffset - v.startOffset)
273 }
274 D.end = D.start
275 } else {
276 if (v.endOffset < v.end.nodeValue.length) {
277 v.end.splitText(v.endOffset)
278 }
279 D.end = v.end
280 }
281 D.commonAncestor = this.commonAncestorContainer;
282 while (D.commonAncestor.nodeType !== 1) {
283 D.commonAncestor = D.commonAncestor.parentNode
284 }
285 return new p.NormalizedRange(D)
286 };
287 t.prototype.serialize = function (u, v) {
288 return this.normalize(u).serialize(u, v)
289 };
290 return t
291 })();
292 p.NormalizedRange = (function () {
293 function t(u) {
294 this.commonAncestor = u.commonAncestor;
295 this.start = u.start;
296 this.end = u.end
297 }
298 t.prototype.normalize = function (u) {
299 return this
300 };
301 t.prototype.limit = function (y) {
302 var u, x, v, w, A, z;
303 u = h.grep(this.textNodes(), function (B) {
304 return B.parentNode === y || h.contains(y, B.parentNode)
305 });
306 if (!u.length) {
307 return null
308 }
309 this.start = u[0];
310 this.end = u[u.length - 1];
311 v = h(this.start).parents();
312 z = h(this.end).parents();
313 for (w = 0, A = z.length; w < A; w++) {
314 x = z[w];
315 if (v.index(x) !== -1) {
316 this.commonAncestor = x;
317 break
318 }
319 }
320 return this
321 };
322 t.prototype.serialize = function (w, x) {
323 var v, u, y;
324 u = function (D, C) {
325 var B, A, F, I, H, G, E, z;
326 if (x) {
327 I = h(D).parents(":not(" + x + ")").eq(0)
328 } else {
329 I = h(D).parent()
330 }
331 G = I.xpath(w)[0];
332 H = I.textNodes();
333 A = H.slice(0, H.index(D));
334 F = 0;
335 for (E = 0, z = A.length; E < z; E++) {
336 B = A[E];
337 F += B.nodeValue.length
338 }
339 if (C) {
340 return [G, F + D.nodeValue.length]
341 } else {
342 return [G, F]
343 }
344 };
345 y = u(this.start);
346 v = u(this.end, true);
347 return new p.SerializedRange({
348 start: y[0],
349 end: v[0],
350 startOffset: y[1],
351 endOffset: v[1]
352 })
353 };
354 t.prototype.text = function () {
355 var u;
356 return ((function () {
357 var w, y, x, v;
358 x = this.textNodes();
359 v = [];
360 for (w = 0, y = x.length; w < y; w++) {
361 u = x[w];
362 v.push(u.nodeValue)
363 }
364 return v
365 }).call(this)).join("")
366 };
367 t.prototype.textNodes = function () {
368 var u, x, v, w;
369 v = h(this.commonAncestor).textNodes();
370 w = [v.index(this.start), v.index(this.end)], x = w[0], u = w[1];
371 return h.makeArray(v.slice(x, (u + 1) || 9000000000))
372 };
373 return t
374 })();
375 p.SerializedRange = (function () {
376 function t(u) {
377 this.start = u.start;
378 this.startOffset = u.startOffset;
379 this.end = u.end;
380 this.endOffset = u.endOffset
381 }
382 t.prototype._nodeFromXPath = function (u) {
383 var z, y, v, x, w;
384 y = function (B, A) {
385 if (A == null) {
386 A = null
387 }
388 return document.evaluate(B, document, A, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue
389 };
390 if (!h.isXMLDoc(document.documentElement)) {
391 return y(u)
392 } else {
393 z = document.createNSResolver(document.ownerDocument === null ? document.documentElement : document.ownerDocument.documentElement);
394 x = y(u, z);
395 if (!x) {
396 u = ((function () {
397 var B, D, C, A;
398 C = u.split("/");
399 A = [];
400 for (B = 0, D = C.length; B < D; B++) {
401 w = C[B];
402 A.push(w && w.indexOf(":") === -1 ? w.replace(/^([a-z]+)/, "xhtml:$1") : w)
403 }
404 return A
405 })()).join("/");
406 v = document.lookupNamespaceURI(null);
407 z = function (A) {
408 if (A === "xhtml") {
409 return v
410 } else {
411 return document.documentElement.getAttribute("xmlns:" + A)
412 }
413 };
414 x = y(u, z)
415 }
416 return x
417 }
418 };
419 t.prototype.normalize = function (G) {
420 var K, D, C, I, A, F, H, E, B, z, v, u, L, J, y, x, w;
421 H = h(G).xpath()[0];
422 B = this.start.split("/");
423 C = this.end.split("/");
424 D = [];
425 E = {};
426 for (I = 0, y = B.length; 0 <= y ? I < y : I > y; 0 <= y ? I++ : I--) {
427 if (B[I] === C[I]) {
428 D.push(B[I])
429 } else {
430 break
431 }
432 }
433 K = H + D.join("/");
434 E.commonAncestorContainer = this._nodeFromXPath(K);
435 if (!E.commonAncestorContainer) {
436 console.error("Error deserializing range: can't find XPath '" + K + "'. Is this the right document?");
437 return null
438 }
439 x = ["start", "end"];
440 for (v = 0, L = x.length; v < L; v++) {
441 F = x[v];
442 A = 0;
443 w = h(this._nodeFromXPath(H + this[F])).textNodes();
444 for (u = 0, J = w.length; u < J; u++) {
445 z = w[u];
446 if (A + z.nodeValue.length >= this[F + "Offset"]) {
447 E[F + "Container"] = z;
448 E[F + "Offset"] = this[F + "Offset"] - A;
449 break
450 } else {
451 A += z.nodeValue.length
452 }
453 }
454 }
455 return new p.BrowserRange(E).normalize(G)
456 };
457 t.prototype.serialize = function (u, v) {
458 return this.normalize(u).serialize(u, v)
459 };
460 t.prototype.toObject = function () {
461 return {
462 start: this.start,
463 startOffset: this.startOffset,
464 end: this.end,
465 endOffset: this.endOffset
466 }
467 };
468 return t
469 })();
470 a = {
471 getGlobal: function () {
472 return (function () {
473 return this
474 })()
475 },
476 mousePosition: function (t, v) {
477 var u;
478 u = h(v).offset();
479 return {
480 top: t.pageY - u.top,
481 left: t.pageX - u.left
482 }
483 }
484 };
485 e = this.Annotator;
486 o = (function () {
487 q(t, b);
488 t.prototype.events = {
489 ".annotator-adder button click": "onAdderClick",
490 ".annotator-adder button mousedown": "onAdderMousedown",
491 ".annotator-hl mouseover": "onHighlightMouseover",
492 ".annotator-hl mouseout": "startViewerHideTimer"
493 };
494 t.prototype.html = {
495 hl: '<span class="annotator-hl"></span>',
496 adder: '<div class="annotator-adder"><button>Annotate</button></div>',
497 wrapper: '<div class="annotator-wrapper"></div>'
498 };
499 t.prototype.options = {};
500 t.prototype.plugins = {};
501 t.prototype.editor = null;
502 t.prototype.viewer = null;
503 t.prototype.selectedRanges = null;
504 t.prototype.mouseIsDown = false;
505 t.prototype.ignoreMouseup = false;
506 t.prototype.viewerHideTimer = null;
507
508 function t(w, v) {
509 this.onDeleteAnnotation = g(this.onDeleteAnnotation, this);
510 this.onEditAnnotation = g(this.onEditAnnotation, this);
511 this.onAdderClick = g(this.onAdderClick, this);
512 this.onAdderMousedown = g(this.onAdderMousedown, this);
513 this.onHighlightMouseover = g(this.onHighlightMouseover, this);
514 this.checkForEndSelection = g(this.checkForEndSelection, this);
515 this.checkForStartSelection = g(this.checkForStartSelection, this);
516 this.clearViewerHideTimer = g(this.clearViewerHideTimer, this);
517 this.startViewerHideTimer = g(this.startViewerHideTimer, this);
518 this.showViewer = g(this.showViewer, this);
519 this.onEditorSubmit = g(this.onEditorSubmit, this);
520 this.onEditorHide = g(this.onEditorHide, this);
521 this.showEditor = g(this.showEditor, this);
522 var u, x, y;
523 t.__super__.constructor.apply(this, arguments);
524 this.plugins = {};
525 if (!t.supported()) {
526 return this
527 }
528 this._setupDocumentEvents()._setupWrapper()._setupViewer()._setupEditor();
529 y = this.html;
530 for (u in y) {
531 x = y[u];
532 if (u !== "wrapper") {
533 this[u] = h(x).appendTo(this.wrapper).hide()
534 }
535 }
536 }
537 t.prototype._setupWrapper = function () {
538 this.wrapper = h(this.html.wrapper);
539 this.element.find("script").remove();
540 this.element.wrapInner(this.wrapper);
541 this.wrapper = this.element.find(".annotator-wrapper");
542 return this
543 };
544 t.prototype._setupViewer = function () {
545 this.viewer = new t.Viewer();
546 this.viewer.hide().on("edit", this.onEditAnnotation).on("delete", this.onDeleteAnnotation).addField({
547 load: g(function (v, u) {
548 h(v).escape(u.text || "");
549 return this.publish("annotationViewerTextField", [v, u])
550 }, this)
551 }).element.appendTo(this.wrapper).bind({
552 mouseover: this.clearViewerHideTimer,
553 mouseout: this.startViewerHideTimer
554 });
555 return this
556 };
557 t.prototype._setupEditor = function () {
558 this.editor = new t.Editor();
559 this.editor.hide().on("hide", this.onEditorHide).on("save", this.onEditorSubmit).addField({
560 type: "textarea",
561 label: "Comments\u2026",
562 load: function (v, u) {
563 return h(v).find("textarea").val(u.text || "")
564 },
565 submit: function (v, u) {
566 return u.text = h(v).find("textarea").val()
567 }
568 });
569 this.editor.element.appendTo(this.wrapper);
570 return this
571 };
572 t.prototype._setupDocumentEvents = function () {
573 h(document).bind({
574 mouseup: this.checkForEndSelection,
575 mousedown: this.checkForStartSelection
576 });
577 return this
578 };
579 t.prototype.getSelectedRanges = function () {
580 var x, v, u, w;
581 w = a.getGlobal().getSelection();
582 u = [];
583 if (!w.isCollapsed) {
584 u = (function () {
585 var z, y;
586 y = [];
587 for (v = 0, z = w.rangeCount; 0 <= z ? v < z : v > z; 0 <= z ? v++ : v--) {
588 x = new p.BrowserRange(w.getRangeAt(v));
589 y.push(x.normalize().limit(this.wrapper[0]))
590 }
591 return y
592 }).call(this)
593 }
594 return h.grep(u, function (y) {
595 return y
596 })
597 };
598 t.prototype.createAnnotation = function () {
599 var u;
600 u = {};
601 this.publish("beforeAnnotationCreated", [u]);
602 return u
603 };
604 t.prototype.setupAnnotation = function (u, w) {
605 var v, A, z, x, y, B;
606 if (w == null) {
607 w = true
608 }
609 u.ranges || (u.ranges = this.selectedRanges);
610 A = (function () {
611 var D, F, E, C;
612 E = u.ranges;
613 C = [];
614 for (D = 0, F = E.length; D < F; D++) {
615 z = E[D];
616 x = p.sniff(z);
617 C.push(x.normalize(this.wrapper[0]))
618 }
619
620 return C
621 }).call(this);
622 A = h.grep(A, function (C) {
623 return C !== null
624 });
625 u.quote = [];
626 u.ranges = [];
627 u.highlights = [];
628 for (y = 0, B = A.length; y < B; y++) {
629 v = A[y];
630 u.quote.push(h.trim(v.text()));
631 u.ranges.push(v.serialize(this.wrapper[0], ".annotator-hl"));
632 h.merge(u.highlights, this.highlightRange(v))
633 }
634 u.quote = u.quote.join(" / ");
635 h(u.highlights).data("annotation", u);
636 if (w) {
637 this.publish("annotationCreated", [u])
638 }
639
640 var rangeString = u.ranges[0].startOffset + "_" + u.ranges[0].endOffset;
641
642 var found = false;
643 for(var i = 0; i < gs.annotationArray.keys.length; i++){if(gs.annotationArray.keys[i] == rangeString){found = true; break;}}
644
645 if(!found)
646 {
647 gs.annotationArray.keys.push(rangeString);
648 }
649 gs.annotationArray[rangeString] = u;
650 console.log("(setup) Adding " + u.quote + ", " + u.text + ", " + u.tags + " to " + rangeString);
651 return u
652 };
653 t.prototype.updateAnnotation = function (u) {
654 this.publish("beforeAnnotationUpdated", [u]);
655 this.publish("annotationUpdated", [u]);
656 return u
657 };
658 t.prototype.deleteAnnotation = function (u) {
659 var w, v, y, x;
660 x = u.highlights;
661 for (v = 0, y = x.length; v < y; v++) {
662 w = x[v];
663 h(w).replaceWith(w.childNodes)
664 }
665 this.publish("annotationDeleted", [u]);
666 return u
667 };
668 t.prototype.loadAnnotations = function (v) {
669 var w, u;
670 if (v == null) {
671 v = []
672 }
673 u = g(function (z) {
674 var B, x, y, A;
675 if (z == null) {
676 z = []
677 }
678 x = z.splice(0, 10);
679 for (y = 0, A = x.length; y < A; y++) {
680 B = x[y];
681 this.setupAnnotation(B, false)
682 }
683 if (z.length > 0) {
684 return setTimeout((function () {
685 return u(z)
686 }), 100)
687 } else {
688 return this.publish("annotationsLoaded", [w])
689 }
690 }, this);
691 w = v.slice();
692 if (v.length) {
693 u(v)
694 }
695 return this
696 };
697 t.prototype.dumpAnnotations = function () {
698 if (this.plugins.Store) {
699 return this.plugins.Store.dumpAnnotations()
700 } else {
701 return console.warn("Can't dump annotations without Store plugin.")
702 }
703 };
704 t.prototype.highlightRange = function (v) {
705 var u, w, x;
706 return u = (function () {
707 var z, B, A, y;
708 A = v.textNodes();
709 y = [];
710 for (z = 0, B = A.length; z < B; z++) {
711 w = A[z];
712 x = this.hl.clone().show();
713 y.push(h(w).wrap(x).parent().get(0))
714 }
715 return y
716 }).call(this)
717 };
718 t.prototype.addPlugin = function (w, v) {
719 var u, x;
720 if (this.plugins[w]) {
721 console.error("You cannot have more than one instance of any plugin.")
722 } else {
723 u = t.Plugin[w];
724 if (typeof u === "function") {
725 this.plugins[w] = new u(this.element[0], v);
726 this.plugins[w].annotator = this;
727 if (typeof (x = this.plugins[w]).pluginInit === "function") {
728 x.pluginInit()
729 }
730 } else {
731 console.error("Could not load " + w + " plugin. Have you included the appropriate <script> tag?")
732 }
733 }
734 return this
735 };
736 t.prototype.showEditor = function (u, v) {
737 this.editor.element.css(v);
738 this.editor.load(u);
739 return this
740 };
741 t.prototype.onEditorHide = function () {
742 this.publish("annotationEditorHidden", [this.editor]);
743 return this.ignoreMouseup = false
744 };
745 t.prototype.onEditorSubmit = function (u) {
746 this.publish("annotationEditorSubmit", [this.editor, u]);
747 if (u.ranges === void 0) {
748 return this.setupAnnotation(u)
749 } else {
750 return this.updateAnnotation(u)
751 }
752 };
753 t.prototype.showViewer = function (v, u) {
754 this.viewer.element.css(u);
755 this.viewer.load(v);
756 return this.publish("annotationViewerShown", [this.viewer, v])
757 };
758 t.prototype.startViewerHideTimer = function () {
759 if (!this.viewerHideTimer) {
760 return this.viewerHideTimer = setTimeout(h.proxy(this.viewer.hide, this.viewer), 250)
761 }
762 };
763 t.prototype.clearViewerHideTimer = function () {
764 clearTimeout(this.viewerHideTimer);
765 return this.viewerHideTimer = false
766 };
767 t.prototype.checkForStartSelection = function (u) {
768 if (!(u && this.isAnnotator(u.target))) {
769 this.startViewerHideTimer();
770 return this.mouseIsDown = true
771 }
772 };
773 t.prototype.checkForEndSelection = function (x) {
774 var u, v, w, z, y;
775 this.mouseIsDown = false;
776 if (this.ignoreMouseup) {
777 return
778 }
779 this.selectedRanges = this.getSelectedRanges();
780 y = this.selectedRanges;
781 for (w = 0, z = y.length; w < z; w++) {
782 v = y[w];
783 u = v.commonAncestor;
784 if (this.isAnnotator(u)) {
785 return
786 }
787 }
788 if (x && this.selectedRanges.length) {
789 return this.adder.css(a.mousePosition(x, this.wrapper[0])).show()
790 } else {
791 return this.adder.hide()
792 }
793 };
794 t.prototype.isAnnotator = function (u) {
795 return !!h(u).parents().andSelf().filter("[class^=annotator-]").not(this.wrapper).length
796 };
797 t.prototype.onHighlightMouseover = function (u) {
798 var v;
799 this.clearViewerHideTimer();
800 if (this.mouseIsDown || this.viewer.isShown()) {
801 return false
802 }
803 v = h(u.target).parents(".annotator-hl").andSelf().map(function () {
804 return h(this).data("annotation")
805 });
806 return this.showViewer(h.makeArray(v), a.mousePosition(u, this.wrapper[0]))
807 };
808 t.prototype.onAdderMousedown = function (u) {
809 if (u != null) {
810 u.preventDefault()
811 }
812 return this.ignoreMouseup = true
813 };
814 t.prototype.onAdderClick = function (v) {
815 var u;
816 if (v != null) {
817 v.preventDefault()
818 }
819 u = this.adder.position();
820 this.adder.hide();
821 return this.showEditor(this.createAnnotation(), u)
822 };
823 t.prototype.onEditAnnotation = function (u) {
824 var v;
825 v = this.viewer.element.position();
826 this.viewer.hide();
827 return this.showEditor(u, v)
828 };
829 t.prototype.onDeleteAnnotation = function (u) {
830 this.viewer.hide();
831 return this.deleteAnnotation(u)
832 };
833 return t
834 })();
835 o.Plugin = (function () {
836 q(t, b);
837
838 function t(v, u) {
839 t.__super__.constructor.apply(this, arguments)
840 }
841 t.prototype.pluginInit = function () {};
842 return t
843 })();
844 o.$ = h;
845 o.supported = function () {
846 return (function () {
847 return !!this.getSelection
848 })()
849 };
850 o.noConflict = function () {
851 a.getGlobal().Annotator = e;
852 return this
853 };
854 h.plugin("annotator", o);
855 this.Annotator = o;
856 o.Widget = (function () {
857 q(t, b);
858 t.prototype.classes = {
859 hide: "annotator-hide",
860 invert: {
861 x: "annotator-invert-x",
862 y: "annotator-invert-y"
863 }
864 };
865
866 function t(v, u) {
867 t.__super__.constructor.apply(this, arguments);
868 this.classes = h.extend({}, o.Widget.prototype.classes, this.classes)
869 }
870 t.prototype.checkOrientation = function () {
871 var x, y, u, w, v;
872 this.resetOrientation();
873 v = h(a.getGlobal());
874 w = this.element.children(":first");
875 y = w.offset();
876 u = {
877 top: v.scrollTop(),
878 right: v.width() + v.scrollLeft()
879 };
880 x = {
881 top: y.top,
882 right: y.left + w.width()
883 };
884 if ((x.top - u.top) < 0) {
885 this.invertY()
886 }
887 if ((x.right - u.right) > 0) {
888 this.invertX()
889 }
890 return this
891 };
892 t.prototype.resetOrientation = function () {
893 this.element.removeClass(this.classes.invert.x).removeClass(this.classes.invert.y);
894 return this
895 };
896 t.prototype.invertX = function () {
897 this.element.addClass(this.classes.invert.x);
898 return this
899 };
900 t.prototype.invertY = function () {
901 this.element.addClass(this.classes.invert.y);
902 return this
903 };
904 return t
905 })();
906 o.Editor = (function () {
907 q(t, o.Widget);
908 t.prototype.events = {
909 "form submit": "submit",
910 ".annotator-save click": "submit",
911 ".annotator-cancel click": "hide",
912 ".annotator-cancel mouseover": "onCancelButtonMouseover",
913 "textarea keydown": "processKeypress"
914 };
915 t.prototype.classes = {
916 hide: "annotator-hide",
917 focus: "annotator-focus"
918 };
919 t.prototype.html = '<div class="annotator-outer annotator-editor">\n <form class="annotator-widget">\n <ul class="annotator-listing"></ul>\n <div class="annotator-controls">\n <a href="#cancel" class="annotator-cancel">Cancel</a>\n <a href="#save" class="annotator-save annotator-focus">Save</a>\n </div>\n <span class="annotator-resize"></span>\n </form>\n</div>';
920 t.prototype.options = {};
921
922 function t(u) {
923 this.onCancelButtonMouseover = g(this.onCancelButtonMouseover, this);
924 this.processKeypress = g(this.processKeypress, this);
925 this.submit = g(this.submit, this);
926 this.load = g(this.load, this);
927 this.hide = g(this.hide, this);
928 this.show = g(this.show, this);
929 t.__super__.constructor.call(this, h(this.html)[0], u);
930 this.fields = [];
931 this.annotation = {};
932 this.setupDragabbles()
933 }
934 t.prototype.show = function (u) {
935 if (u != null) {
936 u.preventDefault()
937 }
938 this.element.removeClass(this.classes.hide);
939 this.element.find(".annotator-save").addClass(this.classes.focus);
940 this.element.find(":input:first").focus();
941 return this.checkOrientation().publish("show")
942 };
943 t.prototype.hide = function (u) {
944 if (u != null) {
945 u.preventDefault()
946 }
947 this.element.addClass(this.classes.hide);
948 return this.publish("hide")
949 };
950 t.prototype.load = function (u) {
951 var w, v, y, x;
952 this.annotation = u;
953 this.publish("load", [this.annotation]);
954 x = this.fields;
955 for (v = 0, y = x.length; v < y; v++) {
956 w = x[v];
957 w.load(w.element, this.annotation)
958 }
959 return this.show()
960 };
961 t.prototype.submit = function (v) {
962 var w, u, y, x;
963 if (v != null) {
964 v.preventDefault()
965 }
966 x = this.fields;
967 for (u = 0, y = x.length; u < y; u++) {
968 w = x[u];
969 w.submit(w.element, this.annotation)
970 }
971 this.publish("save", [this.annotation]);
972 return this.hide()
973 };
974 t.prototype.addField = function (v) {
975 var w, x, u;
976 x = h.extend({
977 id: "annotator-field-" + (new Date()).getTime(),
978 type: "input",
979 label: "",
980 load: function () {},
981 submit: function () {}
982 }, v);
983 u = null;
984 w = h('<li class="annotator-item" />');
985 x.element = w[0];
986 switch (x.type) {
987 case "textarea":
988 u = h("<textarea />");
989 break;
990 case "input":
991 case "checkbox":
992 u = h("<input />")
993 }
994 w.append(u);
995 u.attr({
996 id: x.id,
997 placeholder: x.label
998 });
999 if (x.type === "checkbox") {
1000 u[0].type = "checkbox";
1001 w.addClass("annotator-checkbox");
1002 w.append(h("<label />", {
1003 "for": x.id,
1004 html: x.label
1005 }))
1006 }
1007 this.element.find("ul:first").append(w);
1008 this.fields.push(x);
1009 return x.element
1010 };
1011 t.prototype.checkOrientation = function () {
1012 var u, w, v;
1013 t.__super__.checkOrientation.apply(this, arguments);
1014 v = this.element.find("ul");
1015 u = this.element.find(".annotator-controls");
1016 w = function () {
1017 return v.children().each(function () {
1018 return h(this).parent().prepend(this)
1019 })
1020 };
1021 if (this.element.hasClass(this.classes.invert.y) && v.is(":first-child")) {
1022 u.insertBefore(v);
1023 w()
1024 } else {
1025 if (u.is(":first-child")) {
1026 u.insertAfter(v);
1027 w()
1028 }
1029 }
1030 return this
1031 };
1032 t.prototype.processKeypress = function (u) {
1033 if (u.keyCode === 27) {
1034 return this.hide()
1035 } else {
1036 if (u.keyCode === 13 && !u.shiftKey) {
1037 return this.submit()
1038 }
1039 }
1040 };
1041 t.prototype.onCancelButtonMouseover = function () {
1042 return this.element.find("." + this.classes.focus).removeClass(this.classes.focus)
1043 };
1044 t.prototype.setupDragabbles = function () {
1045 var w, D, z, u, y, B, x, v, A, C;
1046 u = null;
1047 w = this.classes;
1048 z = this.element;
1049 A = null;
1050 v = z.find(".annotator-resize");
1051 D = z.find(".annotator-controls");
1052 C = false;
1053 y = function (E) {
1054 if (E.target === this) {
1055 u = {
1056 element: this,
1057 top: E.pageY,
1058 left: E.pageX
1059 };
1060 A = z.find("textarea:first");
1061 h(window).bind({
1062 "mouseup.annotator-editor-resize": x,
1063 "mousemove.annotator-editor-resize": B
1064 });
1065 return E.preventDefault()
1066 }
1067 };
1068 x = function () {
1069 u = null;
1070 return h(window).unbind(".annotator-editor-resize")
1071 };
1072 B = g(function (I) {
1073 var J, G, F, E, H;
1074 if (u && C === false) {
1075 J = {
1076 top: I.pageY - u.top,
1077 left: I.pageX - u.left
1078 };
1079 if (u.element === v[0]) {
1080 E = A.outerHeight();
1081 H = A.outerWidth();
1082 G = z.hasClass(w.invert.x) ? -1 : 1;
1083 F = z.hasClass(w.invert.y) ? 1 : -1;
1084 A.height(E + (J.top * F));
1085 A.width(H + (J.left * G));
1086 if (A.outerHeight() !== E) {
1087 u.top = I.pageY
1088 }
1089 if (A.outerWidth() !== H) {
1090 u.left = I.pageX
1091 }
1092 } else {
1093 if (u.element === D[0]) {
1094 z.css({
1095 top: parseInt(z.css("top"), 10) + J.top,
1096 left: parseInt(z.css("left"), 10) + J.left
1097 });
1098 u.top = I.pageY;
1099 u.left = I.pageX
1100 }
1101 }
1102 C = true;
1103 return setTimeout(function () {
1104 return C = false
1105 }, 1000 / 60)
1106 }
1107 }, this);
1108 v.bind("mousedown", y);
1109 return D.bind("mousedown", y)
1110 };
1111 return t
1112 })();
1113 o.Viewer = (function () {
1114 q(t, o.Widget);
1115 t.prototype.events = {
1116 ".annotator-edit click": "onEditClick",
1117 ".annotator-delete click": "onDeleteClick"
1118 };
1119 t.prototype.classes = {
1120 hide: "annotator-hide",
1121 showControls: "annotator-visible"
1122 };
1123 t.prototype.html = {
1124 element: '<div class="annotator-outer annotator-viewer">\n <ul class="annotator-widget annotator-listing"></ul>\n</div>',
1125 item: '<li class="annotator-annotation annotator-item">\n <span class="annotator-controls">\n <button class="annotator-edit">Edit</button>\n <button class="annotator-delete">Delete</button>\n </span>\n</li>'
1126 };
1127
1128 function t(u) {
1129 this.onDeleteClick = g(this.onDeleteClick, this);
1130 this.onEditClick = g(this.onEditClick, this);
1131 this.load = g(this.load, this);
1132 this.hide = g(this.hide, this);
1133 this.show = g(this.show, this);
1134 t.__super__.constructor.call(this, h(this.html.element)[0], u);
1135 this.item = h(this.html.item)[0];
1136 this.fields = [];
1137 this.annotations = []
1138 }
1139 t.prototype.show = function (v) {
1140 var u;
1141 if (v != null) {
1142 v.preventDefault()
1143 }
1144 u = this.element.find(".annotator-controls").addClass(this.classes.showControls);
1145 setTimeout((g(function () {
1146 return u.removeClass(this.classes.showControls)
1147 }, this)), 500);
1148 this.element.removeClass(this.classes.hide);
1149 return this.checkOrientation().publish("show")
1150 };
1151 t.prototype.isShown = function () {
1152 return !this.element.hasClass(this.classes.hide)
1153 };
1154 t.prototype.hide = function (u) {
1155 if (u != null) {
1156 //u.preventDefault()
1157 }
1158 this.element.addClass(this.classes.hide);
1159 return this.publish("hide")
1160 };
1161 t.prototype.load = function (C) {
1162 var z, B, G, H, F, A, E, I, D, y, w, u, J, x, v;
1163 this.annotations = C || [];
1164 D = this.element.find("ul:first").empty();
1165 x = this.annotations;
1166 for (y = 0, u = x.length; y < u; y++) {
1167 z = x[y];
1168 I = h(this.item).clone().appendTo(D).data("annotation", z);
1169 G = I.find(".annotator-controls");
1170 F = G.find(".annotator-edit");
1171 H = G.find(".annotator-delete");
1172 B = {
1173 showEdit: function () {
1174 return F.removeAttr("disabled")
1175 },
1176 hideEdit: function () {
1177 return F.attr("disabled", "disabled")
1178 },
1179 showDelete: function () {
1180 return H.removeAttr("disabled")
1181 },
1182 hideDelete: function () {
1183 return H.attr("disabled", "disabled")
1184 }
1185 };
1186 v = this.fields;
1187 for (w = 0, J = v.length; w < J; w++) {
1188 E = v[w];
1189 A = h(E.element).clone().appendTo(I)[0];
1190 E.load(A, z, B)
1191 }
1192 }
1193 this.publish("load", [this.annotations]);
1194 return this.show()
1195 };
1196 t.prototype.addField = function (u) {
1197 var v;
1198 v = h.extend({
1199 load: function () {}
1200 }, u);
1201 v.element = h("<div />")[0];
1202 this.fields.push(v);
1203 v.element;
1204 return this
1205 };
1206 t.prototype.onEditClick = function (u) {
1207 return this.onButtonClick(u, "edit")
1208 };
1209 t.prototype.onDeleteClick = function (u) {
1210 return this.onButtonClick(u, "delete")
1211 };
1212 t.prototype.onButtonClick = function (w, u) {
1213 var v;
1214 v = h(w.target).parents(".annotator-annotation");
1215 return this.publish(u, [v.data("annotation")])
1216 };
1217 return t
1218 })();
1219 o = o || {};
1220 o.Notification = (function () {
1221 q(t, b);
1222 t.prototype.events = {
1223 click: "hide"
1224 };
1225 t.prototype.options = {
1226 html: "<div class='annotator-notice'></div>",
1227 classes: {
1228 show: "annotator-notice-show",
1229 info: "annotator-notice-info",
1230 success: "annotator-notice-success",
1231 error: "annotator-notice-error"
1232 }
1233 };
1234
1235 function t(u) {
1236 this.hide = g(this.hide, this);
1237 this.show = g(this.show, this);
1238 t.__super__.constructor.call(this, h(this.options.html).appendTo(document.body)[0], u)
1239 }
1240 t.prototype.show = function (v, u) {
1241 if (u == null) {
1242 u = o.Notification.INFO
1243 }
1244 h(this.element).addClass(this.options.classes.show).addClass(this.options.classes[u]).escape(v || "");
1245 setTimeout(this.hide, 5000);
1246 return this
1247 };
1248 t.prototype.hide = function () {
1249 h(this.element).removeClass(this.options.classes.show);
1250 return this
1251 };
1252 return t
1253 })();
1254 o.Notification.INFO = "show";
1255 o.Notification.SUCCESS = "success";
1256 o.Notification.ERROR = "error";
1257 h(function () {
1258 var t;
1259 t = new o.Notification;
1260 o.showNotification = t.show;
1261 return o.hideNotification = t.hide
1262 });
1263 o.Plugin.Tags = (function () {
1264 q(t, o.Plugin);
1265
1266 function t() {
1267 this.setAnnotationTags = g(this.setAnnotationTags, this);
1268 this.updateField = g(this.updateField, this);
1269 t.__super__.constructor.apply(this, arguments)
1270 }
1271 t.prototype.field = null;
1272 t.prototype.input = null;
1273 t.prototype.pluginInit = function () {
1274 if (!o.supported()) {
1275 return
1276 }
1277 this.field = this.annotator.editor.addField({
1278 label: "Add some tags here\u2026",
1279 load: this.updateField,
1280 submit: this.setAnnotationTags
1281 });
1282 this.annotator.viewer.addField({
1283 load: this.updateViewer
1284 });
1285 if (this.annotator.plugins.Filter) {
1286 this.annotator.plugins.Filter.addFilter({
1287 label: "Tag",
1288 property: "tags",
1289 isFiltered: o.Plugin.Tags.filterCallback
1290 })
1291 }
1292 return this.input = h(this.field).find(":input")
1293 };
1294 t.prototype.parseTags = function (v) {
1295 var u;
1296 v = h.trim(v);
1297 u = [];
1298 if (v) {
1299 u = v.split(/\s+/)
1300 }
1301 return u
1302 };
1303 t.prototype.stringifyTags = function (u) {
1304 return u.join(" ")
1305 };
1306 t.prototype.updateField = function (w, u) {
1307 var v;
1308 v = "";
1309 if (u.tags) {
1310 v = this.stringifyTags(u.tags)
1311 }
1312 return this.input.val(v)
1313 };
1314 t.prototype.setAnnotationTags = function (v, u) {
1315 return u.tags = this.parseTags(this.input.val())
1316 };
1317 t.prototype.updateViewer = function (v, u) {
1318 v = h(v);
1319 if (u.tags && h.isArray(u.tags) && u.tags.length) {
1320 return v.addClass("annotator-tags").html(function () {
1321 var w;
1322 return w = h.map(u.tags, function (x) {
1323 return '<span class="annotator-tag">' + o.$.escape(x) + "</span>"
1324 }).join(" ")
1325 })
1326 } else {
1327 return v.remove()
1328 }
1329 };
1330 return t
1331 })();
1332 o.Plugin.Tags.filterCallback = function (z, B) {
1333 var y, x, w, C, v, u, t, A;
1334 if (B == null) {
1335 B = []
1336 }
1337 w = 0;
1338 x = [];
1339 if (z) {
1340 x = z.split(/\s+/g);
1341 for (v = 0, t = x.length; v < t; v++) {
1342 y = x[v];
1343 if (B.length) {
1344 for (u = 0, A = B.length; u < A; u++) {
1345 C = B[u];
1346 if (C.indexOf(y) !== -1) {
1347 w += 1
1348 }
1349 }
1350 }
1351 }
1352 }
1353 return w === x.length
1354 };
1355 n = function (u) {
1356 var y, t, x, v, w, z;
1357 v = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
1358 y = u.match(new RegExp(v));
1359 x = 0;
1360 t = new Date(y[1], 0, 1);
1361 if (y[3]) {
1362 t.setMonth(y[3] - 1)
1363 }
1364 if (y[5]) {
1365 t.setDate(y[5])
1366 }
1367 if (y[7]) {
1368 t.setHours(y[7])
1369 }
1370 if (y[8]) {
1371 t.setMinutes(y[8])
1372 }
1373 if (y[10]) {
1374 t.setSeconds(y[10])
1375 }
1376 if (y[12]) {
1377 t.setMilliseconds(Number("0." + y[12]) * 1000)
1378 }
1379 if (y[14]) {
1380 x = (Number(y[16]) * 60) + Number(y[17]);
1381 x *= (z = y[15] === "-") != null ? z : {
1382 1: -1
1383 }
1384 }
1385 x -= t.getTimezoneOffset();
1386 w = Number(t) + (x * 60 * 1000);
1387 t.setTime(Number(w));
1388 return t
1389 };
1390 o.Plugin.Auth = (function () {
1391 q(t, o.Plugin);
1392 t.prototype.options = {
1393 token: null,
1394 tokenUrl: "/auth/token",
1395 autoFetch: true
1396 };
1397
1398 function t(v, u) {
1399 this.haveValidToken = g(this.haveValidToken, this);
1400 t.__super__.constructor.apply(this, arguments);
1401 this.element.data("annotator:auth", this);
1402 this.waitingForToken = [];
1403 if (this.options.token) {
1404 this.setToken(this.options.token)
1405 } else {
1406 this.requestToken()
1407 }
1408 }
1409 t.prototype.requestToken = function () {
1410 this.requestInProgress = true;
1411 return h.getJSON(this.options.tokenUrl, g(function (v, u, w) {
1412 if (u !== "success") {
1413 return console.error("Couldn't get auth token: " + u, w)
1414 } else {
1415 this.setToken(v);
1416 return this.requestInProgress = false
1417 }
1418 }, this))
1419 };
1420 t.prototype.setToken = function (v) {
1421 var u;
1422 this.token = v;
1423 if (this.haveValidToken()) {
1424 if (this.options.autoFetch) {
1425 this.refreshTimeout = setTimeout((g(function () {
1426 return this.requestToken()
1427 }, this)), (this.timeToExpiry() - 2) * 1000)
1428 }
1429 this.updateHeaders();
1430 u = [];
1431 while (this.waitingForToken.length > 0) {
1432 u.push(this.waitingForToken.pop().apply())
1433 }
1434 return u
1435 } else {
1436 console.warn("Didn't get a valid token.");
1437 if (this.options.autoFetch) {
1438 console.warn("Getting a new token in 10s.");
1439 return setTimeout((g(function () {
1440 return this.requestToken()
1441 }, this)), 10 * 1000)
1442 }
1443 }
1444 };
1445 t.prototype.haveValidToken = function () {
1446 var u;
1447 u = this.token && this.token.authToken && this.token.authTokenIssueTime && this.token.authTokenTTL && this.token.accountId && this.token.userId;
1448 return u && this.timeToExpiry() > 0
1449 };
1450 t.prototype.timeToExpiry = function () {
1451 var w, u, v, x;
1452 v = new Date().getTime() / 1000;
1453 u = n(this.token.authTokenIssueTime).getTime() / 1000;
1454 w = u + this.token.authTokenTTL;
1455 x = w - v;
1456 if (x > 0) {
1457 return x
1458 } else {
1459 return 0
1460 }
1461 };
1462 t.prototype.updateHeaders = function () {
1463 var u;
1464 u = this.element.data("annotator:headers");
1465 return this.element.data("annotator:headers", h.extend(u, {
1466 "x-annotator-auth-token": this.token.authToken,
1467 "x-annotator-auth-token-issue-time": this.token.authTokenIssueTime,
1468 "x-annotator-auth-token-ttl": this.token.authTokenTTL,
1469 "x-annotator-account-id": this.token.accountId,
1470 "x-annotator-user-id": this.token.userId
1471 }))
1472 };
1473 t.prototype.withToken = function (u) {
1474 if (!(u != null)) {
1475 return
1476 }
1477 if (this.haveValidToken()) {
1478 return u()
1479 } else {
1480 this.waitingForToken.push(u);
1481 if (!this.requestInProgress) {
1482 return this.requestToken()
1483 }
1484 }
1485 };
1486 return t
1487 })();
1488 o.Plugin.Store = (function () {
1489 q(t, o.Plugin);
1490 t.prototype.events = {
1491 annotationCreated: "annotationCreated",
1492 annotationDeleted: "annotationDeleted",
1493 annotationUpdated: "annotationUpdated"
1494 };
1495 t.prototype.options = {
1496 prefix: "/store",
1497 autoFetch: true,
1498 annotationData: {},
1499 loadFromSearch: false,
1500 urls: {
1501 create: "/annotations",
1502 read: "/annotations/:id",
1503 update: "/annotations/:id",
1504 destroy: "/annotations/:id",
1505 search: "/search"
1506 }
1507 };
1508
1509 function t(v, u) {
1510 this._onError = g(this._onError, this);
1511 this._onBeforeSend = g(this._onBeforeSend, this);
1512 this._onLoadAnnotationsFromSearch = g(this._onLoadAnnotationsFromSearch, this);
1513 this._onLoadAnnotations = g(this._onLoadAnnotations, this);
1514 this._getAnnotations = g(this._getAnnotations, this);
1515 t.__super__.constructor.apply(this, arguments);
1516 this.annotations = []
1517 }
1518 t.prototype.pluginInit = function () {
1519 var u;
1520 if (!o.supported()) {
1521 return
1522 }
1523 u = this.element.data("annotator:auth");
1524 if (u) {
1525 return u.withToken(this._getAnnotations)
1526 } else {
1527 return this._getAnnotations()
1528 }
1529 };
1530 t.prototype._getAnnotations = function () {
1531 if (this.options.loadFromSearch) {
1532 return this.loadAnnotationsFromSearch(this.options.loadFromSearch)
1533 } else {
1534 return this.loadAnnotations()
1535 }
1536 };
1537 t.prototype.annotationCreated = function (u) {
1538 if (f.call(this.annotations, u) < 0) {
1539 this.registerAnnotation(u);
1540 return this._apiRequest("create", u, g(function (v) {
1541 if (!(v.id != null)) {
1542 console.warn("Warning: No ID returned from server for annotation ", u)
1543 }
1544 return this.updateAnnotation(u, v)
1545 }, this))
1546 } else {
1547 return this.updateAnnotation(u, {})
1548 }
1549 };
1550 t.prototype.annotationUpdated = function (u) {
1551 if (f.call(this.annotations, u) >= 0) {
1552 return this._apiRequest("update", u, (g(function (v) {
1553 return this.updateAnnotation(u, v)
1554 }, this)))
1555 }
1556 };
1557 t.prototype.annotationDeleted = function (u) {
1558 if (f.call(this.annotations, u) >= 0) {
1559 return this._apiRequest("destroy", u, (g(function () {
1560 return this.unregisterAnnotation(u)
1561 }, this)))
1562 }
1563 };
1564 t.prototype.registerAnnotation = function (u) {
1565 return this.annotations.push(u)
1566 };
1567 t.prototype.unregisterAnnotation = function (u) {
1568 return this.annotations.splice(this.annotations.indexOf(u), 1)
1569 };
1570 t.prototype.updateAnnotation = function (u, v) {
1571 if (f.call(this.annotations, u) < 0) {
1572 console.error("Trying to update unregistered annotation!")
1573 } else {
1574 h.extend(u, v)
1575 }
1576
1577 var rangeString = u.ranges[0].startOffset + "_" + u.ranges[0].endOffset;
1578
1579 var found = false;
1580 for(var i = 0; i < gs.annotationArray.keys.length; i++){if(gs.annotationArray.keys[i] == rangeString){found = true; break;}}
1581
1582 if(!found)
1583 {
1584 gs.annotationArray.keys.push(rangeString);
1585 }
1586 gs.annotationArray[rangeString] = u;
1587 console.log("(setup) Adding " + u.quote + ", " + u.text + ", " + u.tags + " to " + rangeString);
1588 return h(u.highlights).data("annotation", u)
1589 };
1590 t.prototype.loadAnnotations = function () {
1591 return this._apiRequest("read", null, this._onLoadAnnotations)
1592 };
1593 t.prototype._onLoadAnnotations = function (u) {
1594 if (u == null) {
1595 u = []
1596 }
1597 this.annotations = u;
1598 return this.annotator.loadAnnotations(u.slice())
1599 };
1600 t.prototype.loadAnnotationsFromSearch = function (u) {
1601 return this._apiRequest("search", u, this._onLoadAnnotationsFromSearch)
1602 };
1603 t.prototype._onLoadAnnotationsFromSearch = function (u) {
1604 if (u == null) {
1605 u = {}
1606 }
1607 return this._onLoadAnnotations(u.rows || [])
1608 };
1609 t.prototype.dumpAnnotations = function () {
1610 var w, v, y, x, u;
1611 x = this.annotations;
1612 u = [];
1613 for (v = 0, y = x.length; v < y; v++) {
1614 w = x[v];
1615 u.push(JSON.parse(this._dataFor(w)))
1616 }
1617 return u
1618 };
1619 t.prototype._apiRequest = function (x, y, z) {
1620 var A, v, w, u;
1621 A = y && y.id;
1622 u = this._urlFor(x, A);
1623 v = this._apiRequestOptions(x, y, z);
1624 w = h.ajax(u, v);
1625 w._id = A;
1626 w._action = x;
1627 return w
1628 };
1629 t.prototype._apiRequestOptions = function (v, w, x) {
1630 var u;
1631 u = {
1632 type: this._methodFor(v),
1633 beforeSend: this._onBeforeSend,
1634 dataType: "json",
1635 success: x ||
1636 function () {},
1637 error: this._onError
1638 };
1639 if (v === "search") {
1640 u = h.extend(u, {
1641 data: w
1642 })
1643 } else {
1644 u = h.extend(u, {
1645 data: w && this._dataFor(w),
1646 contentType: "application/json; charset=utf-8"
1647 })
1648 }
1649 return u
1650 };
1651 t.prototype._urlFor = function (w, x) {
1652 var u, v;
1653 u = x != null ? "/" + x : "";
1654 v = this.options.prefix || "/";
1655 v += this.options.urls[w];
1656 v = v.replace(/\/:id/, u);
1657 return v
1658 };
1659 t.prototype._methodFor = function (v) {
1660 var u;
1661 u = {
1662 create: "POST",
1663 read: "GET",
1664 update: "PUT",
1665 destroy: "DELETE",
1666 search: "GET"
1667 };
1668 return u[v]
1669 };
1670 t.prototype._dataFor = function (u) {
1671 var v, w;
1672 w = u.highlights;
1673 delete u.highlights;
1674 h.extend(u, this.options.annotationData);
1675 v = JSON.stringify(u);
1676 if (w) {
1677 u.highlights = w
1678 }
1679 return v
1680 };
1681 t.prototype._onBeforeSend = function (y) {
1682 var x, v, w, u;
1683 x = this.element.data("annotator:headers");
1684 if (x) {
1685 u = [];
1686 for (v in x) {
1687 w = x[v];
1688 u.push(y.setRequestHeader(v, w))
1689 }
1690 return u
1691 }
1692 };
1693 t.prototype._onError = function (w) {
1694 var v, u;
1695 v = w._action;
1696 u = "Sorry we could not " + v + " this annotation";
1697 if (w._action === "search") {
1698 u = "Sorry we could not search the store for annotations"
1699 } else {
1700 if (w._action === "read" && !w._id) {
1701 u = "Sorry we could not " + v + " the annotations from the store"
1702 }
1703 }
1704 switch (w.status) {
1705 case 401:
1706 u = "Sorry you are not allowed to " + v + " this annotation";
1707 break;
1708 case 404:
1709 u = "Sorry we could not connect to the annotations store";
1710 break;
1711 case 500:
1712 u = "Sorry something went wrong with the annotation store"
1713 }
1714 o.showNotification(u, o.Notification.ERROR);
1715 return console.error("API request failed: '" + w.status + "'")
1716 };
1717 return t
1718 })();
1719 o.Plugin.Filter = (function () {
1720 q(t, o.Plugin);
1721 t.prototype.events = {
1722 ".annotator-filter-property input focus": "_onFilterFocus",
1723 ".annotator-filter-property input blur": "_onFilterBlur",
1724 ".annotator-filter-property input keyup": "_onFilterKeyup",
1725 ".annotator-filter-previous click": "_onPreviousClick",
1726 ".annotator-filter-next click": "_onNextClick",
1727 ".annotator-filter-clear click": "_onClearClick"
1728 };
1729 t.prototype.classes = {
1730 active: "annotator-filter-active",
1731 hl: {
1732 hide: "annotator-hl-filtered",
1733 active: "annotator-hl-active"
1734 }
1735 };
1736 t.prototype.html = {
1737 // element: '<div class="annotator-filter">\n <strong>Navigate:</strong>\n <span class="annotator-filter-navigation">\n <button class="annotator-filter-previous">Previous</button>\n <button class="annotator-filter-next">Next</button>\n </span>\n <strong>Filter by:</strong>\n</div>',
1738 filter: '<span class="annotator-filter-property">\n <label></label>\n <input/>\n <button class="annotator-filter-clear">Clear</button>\n</span>'
1739 };
1740 t.prototype.options = {
1741 appendTo: "body",
1742 filters: [],
1743 addAnnotationFilter: true,
1744 isFiltered: function (v, x) {
1745 var u, w, z, y;
1746 if (!(v && x)) {
1747 return false
1748 }
1749 y = v.split(/\s*/);
1750 for (w = 0, z = y.length; w < z; w++) {
1751 u = y[w];
1752 if (x.indexOf(u) === -1) {
1753 return false
1754 }
1755 }
1756 return true
1757 }
1758 };
1759
1760 function t(v, u) {
1761 this._onPreviousClick = g(this._onPreviousClick, this);
1762 this._onNextClick = g(this._onNextClick, this);
1763 this._onFilterKeyup = g(this._onFilterKeyup, this);
1764 this._onFilterBlur = g(this._onFilterBlur, this);
1765 this._onFilterFocus = g(this._onFilterFocus, this);
1766 this.updateHighlights = g(this.updateHighlights, this);
1767 v = h(this.html.element).appendTo(this.options.appendTo);
1768 t.__super__.constructor.call(this, v, u);
1769 this.filter = h(this.html.filter);
1770 this.filters = [];
1771 this.current = 0
1772 }
1773 t.prototype.pluginInit = function () {
1774 var v, u, x, w;
1775 w = this.options.filters;
1776 for (u = 0, x = w.length; u < x; u++) {
1777 v = w[u];
1778 this.addFilter(v)
1779 }
1780 this.updateHighlights();
1781 this._setupListeners()._insertSpacer();
1782 if (this.options.addAnnotationFilter === true) {
1783 return this.addFilter({
1784 label: "Annotation",
1785 property: "text"
1786 })
1787 }
1788 };
1789 t.prototype._insertSpacer = function () {
1790 var v, u;
1791 u = h("html");
1792 v = parseInt(u.css("padding-top"), 10) || 0;
1793 u.css("padding-top", v + this.element.outerHeight());
1794 return this
1795 };
1796 t.prototype._setupListeners = function () {
1797 var w, u, v, x;
1798 u = ["annotationsLoaded", "annotationCreated", "annotationUpdated", "annotationDeleted"];
1799 for (v = 0, x = u.length; v < x; v++) {
1800 w = u[v];
1801 this.annotator.subscribe(w, this.updateHighlights)
1802 }
1803 return this
1804 };
1805 t.prototype.addFilter = function (u) {
1806 var w, v;
1807 v = h.extend({
1808 label: "",
1809 property: "",
1810 isFiltered: this.options.isFiltered
1811 }, u);
1812 if (!((function () {
1813 var y, A, z, x;
1814 z = this.filters;
1815 x = [];
1816 for (y = 0, A = z.length; y < A; y++) {
1817 w = z[y];
1818 if (w.property === v.property) {
1819 x.push(w)
1820 }
1821 }
1822 return x
1823 }).call(this)).length) {
1824 v.id = "annotator-filter-" + v.property;
1825 v.annotations = [];
1826 v.element = this.filter.clone().appendTo(this.element);
1827 v.element.find("label").html(v.label).attr("for", v.id);
1828 v.element.find("input").attr({
1829 id: v.id,
1830 placeholder: "Filter by " + v.label + "\u2026"
1831 });
1832 v.element.find("button").hide();
1833 v.element.data("filter", v);
1834 this.filters.push(v)
1835 }
1836 return this
1837 };
1838 t.prototype.updateFilter = function (x) {
1839 var u, z, v, y, w, B, A;
1840 x.annotations = [];
1841 this.updateHighlights();
1842 this.resetHighlights();
1843 v = h.trim(x.element.find("input").val());
1844 if (v) {
1845 z = this.highlights.map(function () {
1846 return h(this).data("annotation")
1847 });
1848 A = h.makeArray(z);
1849 for (w = 0, B = A.length; w < B; w++) {
1850 u = A[w];
1851 y = u[x.property];
1852 if (x.isFiltered(v, y)) {
1853 x.annotations.push(u)
1854 }
1855 }
1856 return this.filterHighlights()
1857 }
1858 };
1859 t.prototype.updateHighlights = function () {
1860 this.highlights = this.annotator.element.find(".annotator-hl:visible");
1861 return this.filtered = this.highlights.not(this.classes.hl.hide)
1862 };
1863 t.prototype.filterHighlights = function () {
1864 var v, x, y, B, z, A, C, u, w;
1865 v = h.grep(this.filters, function (D) {
1866 return !!D.annotations.length
1867 });
1868 B = ((w = v[0]) != null ? w.annotations : void 0) || [];
1869 if (v.length > 1) {
1870 y = [];
1871 h.each(v, function () {
1872 return h.merge(y, this.annotations)
1873 });
1874 C = [];
1875 B = [];
1876 h.each(y, function () {
1877 if (h.inArray(this, C) === -1) {
1878 return C.push(this)
1879 } else {
1880 return B.push(this)
1881 }
1882 })
1883 }
1884 z = this.highlights;
1885 for (A = 0, u = B.length; A < u; A++) {
1886 x = B[A];
1887 z = z.not(x.highlights)
1888 }
1889 z.addClass(this.classes.hl.hide);
1890 this.filtered = this.highlights.not(this.classes.hl.hide);
1891 return this
1892 };
1893 t.prototype.resetHighlights = function () {
1894 this.highlights.removeClass(this.classes.hl.hide);
1895 this.filtered = this.highlights;
1896 return this
1897 };
1898 t.prototype._onFilterFocus = function (v) {
1899 var u;
1900 u = h(v.target);
1901 u.parent().addClass(this.classes.active);
1902 return u.next("button").show()
1903 };
1904 t.prototype._onFilterBlur = function (v) {
1905 var u;
1906 if (!v.target.value) {
1907 u = h(v.target);
1908 u.parent().removeClass(this.classes.active);
1909 return u.next("button").hide()
1910 }
1911 };
1912 t.prototype._onFilterKeyup = function (v) {
1913 var u;
1914 u = h(v.target).parent().data("filter");
1915 if (u) {
1916 return this.updateFilter(u)
1917 }
1918 };
1919 t.prototype._findNextHighlight = function (z) {
1920 var v, w, B, A, y, x, u, C;
1921 if (!this.highlights.length) {
1922 return this
1923 }
1924 x = z ? 0 : -1;
1925 C = z ? -1 : 0;
1926 u = z ? "lt" : "gt";
1927 v = this.highlights.not("." + this.classes.hl.hide);
1928 B = v.filter("." + this.classes.hl.active);
1929 if (!B.length) {
1930 B = v.eq(x)
1931 }
1932 w = B.data("annotation");
1933 A = v.index(B[0]);
1934 y = v.filter(":" + u + "(" + A + ")").not(w.highlights).eq(C);
1935 if (!y.length) {
1936 y = v.eq(C)
1937 }
1938 return this._scrollToHighlight(y.data("annotation").highlights)
1939 };
1940 t.prototype._onNextClick = function (u) {
1941 return this._findNextHighlight()
1942 };
1943 t.prototype._onPreviousClick = function (u) {
1944 return this._findNextHighlight(true)
1945 };
1946 t.prototype._scrollToHighlight = function (u) {
1947 u = h(u);
1948 this.highlights.removeClass(this.classes.hl.active);
1949 u.addClass(this.classes.hl.active);
1950 return h("html, body").animate({
1951 scrollTop: u.offset().top - (this.element.height() + 20)
1952 }, 150)
1953 };
1954 t.prototype._onClearClick = function (u) {
1955 return h(u.target).prev("input").val("").keyup().blur()
1956 };
1957 return t
1958 })();
1959 o.Plugin.Markdown = (function () {
1960 q(t, o.Plugin);
1961 t.prototype.events = {
1962 annotationViewerTextField: "updateTextField"
1963 };
1964
1965 function t(v, u) {
1966 this.updateTextField = g(this.updateTextField, this);
1967 if ((typeof Showdown !== "undefined" && Showdown !== null ? Showdown.converter : void 0) != null) {
1968 t.__super__.constructor.apply(this, arguments);
1969 this.converter = new Showdown.converter()
1970 } else {
1971 console.error("To use the Markdown plugin, you must include Showdown into the page first.")
1972 }
1973 }
1974 t.prototype.updateTextField = function (v, u) {
1975 var w;
1976 w = o.$.escape(u.text || "");
1977 return h(v).html(this.convert(w))
1978 };
1979 t.prototype.convert = function (u) {
1980 return this.converter.makeHtml(u)
1981 };
1982 return t
1983 })();
1984 o.Plugin.Unsupported = (function () {
1985 q(t, o.Plugin);
1986
1987 function t() {
1988 t.__super__.constructor.apply(this, arguments)
1989 }
1990 t.prototype.options = {
1991 message: "Sorry your current browser does not support the Annotator"
1992 };
1993 t.prototype.pluginInit = function () {
1994 if (!o.supported()) {
1995 return h(g(function () {
1996 o.showNotification(this.options.message);
1997 if ((window.XMLHttpRequest === void 0) && (ActiveXObject !== void 0)) {
1998 return h("html").addClass("ie6")
1999 }
2000 }, this))
2001 }
2002 };
2003 return t
2004 })();
2005 o.Plugin.Permissions = (function () {
2006 q(t, o.Plugin);
2007 t.prototype.events = {
2008 beforeAnnotationCreated: "addFieldsToAnnotation"
2009 };
2010 t.prototype.options = {
2011 showViewPermissionsCheckbox: true,
2012 showEditPermissionsCheckbox: true,
2013 userId: function (u) {
2014 return u
2015 },
2016 userString: function (u) {
2017 return u
2018 },
2019 userAuthorize: function (u, v) {
2020 return this.userId(u) === v
2021 },
2022 user: "",
2023 permissions: {
2024 read: [],
2025 update: [],
2026 "delete": [],
2027 admin: []
2028 }
2029 };
2030
2031 function t(v, u) {
2032 this.updateViewer = g(this.updateViewer, this);
2033 this.updateAnnotationPermissions = g(this.updateAnnotationPermissions, this);
2034 this.updatePermissionsField = g(this.updatePermissionsField, this);
2035 this.addFieldsToAnnotation = g(this.addFieldsToAnnotation, this);
2036 t.__super__.constructor.apply(this, arguments);
2037 if (this.options.user) {
2038 this.setUser(this.options.user);
2039 delete this.options.user
2040 }
2041 }
2042 t.prototype.pluginInit = function () {
2043 var u, v;
2044 if (!o.supported()) {
2045 return
2046 }
2047 v = this;
2048 u = function (x, w) {
2049 return function (z, y) {
2050 return v[x].call(v, w, z, y)
2051 }
2052 };
2053 if (this.options.showViewPermissionsCheckbox === true) {
2054 this.annotator.editor.addField({
2055 type: "checkbox",
2056 label: "Allow anyone to <strong>view</strong> this annotation",
2057 load: u("updatePermissionsField", "read"),
2058 submit: u("updateAnnotationPermissions", "read")
2059 })
2060 }
2061 if (this.options.showEditPermissionsCheckbox === true) {
2062 this.annotator.editor.addField({
2063 type: "checkbox",
2064 label: "Allow anyone to <strong>edit</strong> this annotation",
2065 load: u("updatePermissionsField", "update"),
2066 submit: u("updateAnnotationPermissions", "update")
2067 })
2068 }
2069 this.annotator.viewer.addField({
2070 load: this.updateViewer
2071 });
2072 if (this.annotator.plugins.Filter) {
2073 return this.annotator.plugins.Filter.addFilter({
2074 label: "User",
2075 property: "user",
2076 isFiltered: g(function (y, x) {
2077 var w, z, B, A;
2078 x = this.options.userString(x);
2079 if (!(y && x)) {
2080 return false
2081 }
2082 A = y.split(/\s*/);
2083 for (z = 0, B = A.length; z < B; z++) {
2084 w = A[z];
2085 if (x.indexOf(w) === -1) {
2086 return false
2087 }
2088 }
2089 return true
2090 }, this)
2091 })
2092 }
2093 };
2094 t.prototype.setUser = function (u) {
2095 return this.user = u
2096 };
2097 t.prototype.addFieldsToAnnotation = function (u) {
2098 if (u) {
2099 u.permissions = this.options.permissions;
2100 if (this.user) {
2101 return u.user = this.user
2102 }
2103 }
2104 };
2105 t.prototype.authorize = function (y, u, v) {
2106 var w, z, x, A;
2107 if (v === void 0) {
2108 v = this.user
2109 }
2110 if (u.permissions) {
2111 z = u.permissions[y] || [];
2112 if (z.length === 0) {
2113 return true
2114 }
2115 for (x = 0, A = z.length; x < A; x++) {
2116 w = z[x];
2117 if (this.options.userAuthorize.call(this.options, v, w)) {
2118 return true
2119 }
2120 }
2121 return false
2122 } else {
2123 if (u.user) {
2124 return v && this.options.userId(v) === u.user
2125 }
2126 }
2127 return true
2128 };
2129 t.prototype.updatePermissionsField = function (w, y, u) {
2130 var x, v;
2131 y = h(y).show();
2132 v = y.find("input").removeAttr("disabled");
2133 if (!this.authorize("admin", u)) {
2134 y.hide()
2135 }
2136 if (this.authorize(w, u || {}, null)) {
2137 v.attr("checked", "checked");
2138 x = {
2139 permissions: this.options.permissions
2140 };
2141 if (this.authorize(w, x, null)) {
2142 return v.attr("disabled", "disabled")
2143 }
2144 } else {
2145 return v.removeAttr("checked")
2146 }
2147 };
2148 t.prototype.updateAnnotationPermissions = function (w, x, u) {
2149 var y, v;
2150 if (!u.permissions) {
2151 u.permissions = this.options.permissions
2152 }
2153 y = w + "-permissions";
2154 if (h(x).find("input").is(":checked")) {
2155 h.data(u, y, u.permissions[w]);
2156 return u.permissions[w] = []
2157 } else {
2158 v = h.data(u, y);
2159 if (v) {
2160 return u.permissions[w] = v
2161 }
2162 }
2163 };
2164 t.prototype.updateViewer = function (x, u, w) {
2165 var v, y;
2166 x = h(x);
2167 y = this.options.userString(u.user);
2168 if (u.user && y && typeof y === "string") {
2169 v = o.$.escape(this.options.userString(u.user));
2170 x.html(v).addClass("annotator-user")
2171 } else {
2172 x.remove()
2173 }
2174 if (u.permissions) {
2175 if (!this.authorize("update", u)) {
2176 w.hideEdit()
2177 }
2178 if (!this.authorize("delete", u)) {
2179 return w.hideDelete()
2180 }
2181 } else {
2182 if (u.user && !this.authorize(null, u)) {
2183 w.hideEdit();
2184 return w.hideDelete()
2185 }
2186 }
2187 };
2188 return t
2189 })();
2190 o.prototype.setupPlugins = function (w, E) {
2191 var B, D, u, t, y, v, A, C, z, x;
2192 if (w == null) {
2193 w = {}
2194 }
2195 if (E == null) {
2196 E = {}
2197 }
2198 z = a.getGlobal();
2199 y = {
2200 Tags: {},
2201 Filter: {
2202 filters: [{
2203 label: "User",
2204 property: "user"
2205 }, {
2206 label: "Tags",
2207 property: "tags"
2208 }]
2209 },
2210 Unsupported: {}
2211 };
2212 if (z.Showdown) {
2213 y.Markdown = {}
2214 }
2215 A = w.userId, C = w.userName, B = w.accountId, D = w.authToken;
2216 if (A && C && B && D) {
2217 v = z.location.href.split(/#|\?/).shift() || "";
2218 h.extend(y, {
2219 Store: {
2220 prefix: w.storeUri || "http://annotateit.org/api",
2221 annotationData: {
2222 uri: v
2223 },
2224 loadFromSearch: {
2225 uri: v,
2226 all_fields: 1
2227 }
2228 },
2229 Permissions: {
2230 user: {
2231 id: w.userId,
2232 name: w.userName
2233 },
2234 permissions: {
2235 read: [w.userId],
2236 update: [w.userId],
2237 "delete": [w.userId],
2238 admin: [w.userId]
2239 },
2240 userId: function (F) {
2241 if (F != null ? F.id : void 0) {
2242 return F.id
2243 } else {
2244 return ""
2245 }
2246 },
2247 userString: function (F) {
2248 if (F != null ? F.name : void 0) {
2249 return F.name
2250 } else {
2251 return ""
2252 }
2253 }
2254 }
2255 });
2256 this.element.data({
2257 "annotator:headers": {
2258 "X-Annotator-User-Id": w.userId,
2259 "X-Annotator-Account-Id": w.accountId,
2260 "X-Annotator-Auth-Token": w.authToken
2261 }
2262 })
2263 }
2264 h.extend(y, E);
2265 x = [];
2266 for (u in y) {
2267 if (!k.call(y, u)) {
2268 continue
2269 }
2270 t = y[u];
2271 if (t !== null && t !== false) {
2272 x.push(this.addPlugin(u, t))
2273 }
2274 }
2275 return x
2276 }
2277}).call(this);
Note: See TracBrowser for help on using the repository browser.