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

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

UserTest changes made to Annotator and PhotoNote

File size: 81.1 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 return C
620 }).call(this);
621 A = h.grep(A, function (C) {
622 return C !== null
623 });
624 u.quote = [];
625 u.ranges = [];
626 u.highlights = [];
627 for (y = 0, B = A.length; y < B; y++) {
628 v = A[y];
629 u.quote.push(h.trim(v.text()));
630 u.ranges.push(v.serialize(this.wrapper[0], ".annotator-hl"));
631 h.merge(u.highlights, this.highlightRange(v))
632 }
633 u.quote = u.quote.join(" / ");
634 h(u.highlights).data("annotation", u);
635 if (w) {
636 this.publish("annotationCreated", [u])
637 }
638 return u
639 };
640 t.prototype.updateAnnotation = function (u) {
641 this.publish("beforeAnnotationUpdated", [u]);
642 this.publish("annotationUpdated", [u]);
643 return u
644 };
645 t.prototype.deleteAnnotation = function (u) {
646 var w, v, y, x;
647 x = u.highlights;
648 for (v = 0, y = x.length; v < y; v++) {
649 w = x[v];
650 h(w).replaceWith(w.childNodes)
651 }
652 this.publish("annotationDeleted", [u]);
653 return u
654 };
655 t.prototype.loadAnnotations = function (v) {
656 var w, u;
657 if (v == null) {
658 v = []
659 }
660 u = g(function (z) {
661 var B, x, y, A;
662 if (z == null) {
663 z = []
664 }
665 x = z.splice(0, 10);
666 for (y = 0, A = x.length; y < A; y++) {
667 B = x[y];
668 this.setupAnnotation(B, false)
669 }
670 if (z.length > 0) {
671 return setTimeout((function () {
672 return u(z)
673 }), 100)
674 } else {
675 return this.publish("annotationsLoaded", [w])
676 }
677 }, this);
678 w = v.slice();
679 if (v.length) {
680 u(v)
681 }
682 return this
683 };
684 t.prototype.dumpAnnotations = function () {
685 if (this.plugins.Store) {
686 return this.plugins.Store.dumpAnnotations()
687 } else {
688 return console.warn("Can't dump annotations without Store plugin.")
689 }
690 };
691 t.prototype.highlightRange = function (v) {
692 var u, w, x;
693 return u = (function () {
694 var z, B, A, y;
695 A = v.textNodes();
696 y = [];
697 for (z = 0, B = A.length; z < B; z++) {
698 w = A[z];
699 x = this.hl.clone().show();
700 y.push(h(w).wrap(x).parent().get(0))
701 }
702 return y
703 }).call(this)
704 };
705 t.prototype.addPlugin = function (w, v) {
706 var u, x;
707 if (this.plugins[w]) {
708 console.error("You cannot have more than one instance of any plugin.")
709 } else {
710 u = t.Plugin[w];
711 if (typeof u === "function") {
712 this.plugins[w] = new u(this.element[0], v);
713 this.plugins[w].annotator = this;
714 if (typeof (x = this.plugins[w]).pluginInit === "function") {
715 x.pluginInit()
716 }
717 } else {
718 console.error("Could not load " + w + " plugin. Have you included the appropriate <script> tag?")
719 }
720 }
721 return this
722 };
723 t.prototype.showEditor = function (u, v) {
724 this.editor.element.css(v);
725 this.editor.load(u);
726 return this
727 };
728 t.prototype.onEditorHide = function () {
729 this.publish("annotationEditorHidden", [this.editor]);
730 return this.ignoreMouseup = false
731 };
732 t.prototype.onEditorSubmit = function (u) {
733 this.publish("annotationEditorSubmit", [this.editor, u]);
734 if (u.ranges === void 0) {
735 return this.setupAnnotation(u)
736 } else {
737 return this.updateAnnotation(u)
738 }
739 };
740 t.prototype.showViewer = function (v, u) {
741 this.viewer.element.css(u);
742 this.viewer.load(v);
743 return this.publish("annotationViewerShown", [this.viewer, v])
744 };
745 t.prototype.startViewerHideTimer = function () {
746 if (!this.viewerHideTimer) {
747 return this.viewerHideTimer = setTimeout(h.proxy(this.viewer.hide, this.viewer), 250)
748 }
749 };
750 t.prototype.clearViewerHideTimer = function () {
751 clearTimeout(this.viewerHideTimer);
752 return this.viewerHideTimer = false
753 };
754 t.prototype.checkForStartSelection = function (u) {
755 if (!(u && this.isAnnotator(u.target))) {
756 this.startViewerHideTimer();
757 return this.mouseIsDown = true
758 }
759 };
760 t.prototype.checkForEndSelection = function (x) {
761 var u, v, w, z, y;
762 this.mouseIsDown = false;
763 if (this.ignoreMouseup) {
764 return
765 }
766 this.selectedRanges = this.getSelectedRanges();
767 y = this.selectedRanges;
768 for (w = 0, z = y.length; w < z; w++) {
769 v = y[w];
770 u = v.commonAncestor;
771 if (this.isAnnotator(u)) {
772 return
773 }
774 }
775 if (x && this.selectedRanges.length) {
776 return this.adder.css(a.mousePosition(x, this.wrapper[0])).show()
777 } else {
778 return this.adder.hide()
779 }
780 };
781 t.prototype.isAnnotator = function (u) {
782 return !!h(u).parents().andSelf().filter("[class^=annotator-]").not(this.wrapper).length
783 };
784 t.prototype.onHighlightMouseover = function (u) {
785 var v;
786 this.clearViewerHideTimer();
787 if (this.mouseIsDown || this.viewer.isShown()) {
788 return false
789 }
790 v = h(u.target).parents(".annotator-hl").andSelf().map(function () {
791 return h(this).data("annotation")
792 });
793 return this.showViewer(h.makeArray(v), a.mousePosition(u, this.wrapper[0]))
794 };
795 t.prototype.onAdderMousedown = function (u) {
796 if (u != null) {
797 u.preventDefault()
798 }
799 return this.ignoreMouseup = true
800 };
801 t.prototype.onAdderClick = function (v) {
802 var u;
803 if (v != null) {
804 v.preventDefault()
805 }
806 u = this.adder.position();
807 this.adder.hide();
808 return this.showEditor(this.createAnnotation(), u)
809 };
810 t.prototype.onEditAnnotation = function (u) {
811 var v;
812 v = this.viewer.element.position();
813 this.viewer.hide();
814 return this.showEditor(u, v)
815 };
816 t.prototype.onDeleteAnnotation = function (u) {
817 this.viewer.hide();
818 return this.deleteAnnotation(u)
819 };
820 return t
821 })();
822 o.Plugin = (function () {
823 q(t, b);
824
825 function t(v, u) {
826 t.__super__.constructor.apply(this, arguments)
827 }
828 t.prototype.pluginInit = function () {};
829 return t
830 })();
831 o.$ = h;
832 o.supported = function () {
833 return (function () {
834 return !!this.getSelection
835 })()
836 };
837 o.noConflict = function () {
838 a.getGlobal().Annotator = e;
839 return this
840 };
841 h.plugin("annotator", o);
842 this.Annotator = o;
843 o.Widget = (function () {
844 q(t, b);
845 t.prototype.classes = {
846 hide: "annotator-hide",
847 invert: {
848 x: "annotator-invert-x",
849 y: "annotator-invert-y"
850 }
851 };
852
853 function t(v, u) {
854 t.__super__.constructor.apply(this, arguments);
855 this.classes = h.extend({}, o.Widget.prototype.classes, this.classes)
856 }
857 t.prototype.checkOrientation = function () {
858 var x, y, u, w, v;
859 this.resetOrientation();
860 v = h(a.getGlobal());
861 w = this.element.children(":first");
862 y = w.offset();
863 u = {
864 top: v.scrollTop(),
865 right: v.width() + v.scrollLeft()
866 };
867 x = {
868 top: y.top,
869 right: y.left + w.width()
870 };
871 if ((x.top - u.top) < 0) {
872 this.invertY()
873 }
874 if ((x.right - u.right) > 0) {
875 this.invertX()
876 }
877 return this
878 };
879 t.prototype.resetOrientation = function () {
880 this.element.removeClass(this.classes.invert.x).removeClass(this.classes.invert.y);
881 return this
882 };
883 t.prototype.invertX = function () {
884 this.element.addClass(this.classes.invert.x);
885 return this
886 };
887 t.prototype.invertY = function () {
888 this.element.addClass(this.classes.invert.y);
889 return this
890 };
891 return t
892 })();
893 o.Editor = (function () {
894 q(t, o.Widget);
895 t.prototype.events = {
896 "form submit": "submit",
897 ".annotator-save click": "submit",
898 ".annotator-cancel click": "hide",
899 ".annotator-cancel mouseover": "onCancelButtonMouseover",
900 "textarea keydown": "processKeypress"
901 };
902 t.prototype.classes = {
903 hide: "annotator-hide",
904 focus: "annotator-focus"
905 };
906 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>';
907 t.prototype.options = {};
908
909 function t(u) {
910 this.onCancelButtonMouseover = g(this.onCancelButtonMouseover, this);
911 this.processKeypress = g(this.processKeypress, this);
912 this.submit = g(this.submit, this);
913 this.load = g(this.load, this);
914 this.hide = g(this.hide, this);
915 this.show = g(this.show, this);
916 t.__super__.constructor.call(this, h(this.html)[0], u);
917 this.fields = [];
918 this.annotation = {};
919 this.setupDragabbles()
920 }
921 t.prototype.show = function (u) {
922 if (u != null) {
923 u.preventDefault()
924 }
925 this.element.removeClass(this.classes.hide);
926 this.element.find(".annotator-save").addClass(this.classes.focus);
927 this.element.find(":input:first").focus();
928 return this.checkOrientation().publish("show")
929 };
930 t.prototype.hide = function (u) {
931 if (u != null) {
932 u.preventDefault()
933 }
934 this.element.addClass(this.classes.hide);
935 return this.publish("hide")
936 };
937 t.prototype.load = function (u) {
938 var w, v, y, x;
939 this.annotation = u;
940 this.publish("load", [this.annotation]);
941 x = this.fields;
942 for (v = 0, y = x.length; v < y; v++) {
943 w = x[v];
944 w.load(w.element, this.annotation)
945 }
946 return this.show()
947 };
948 t.prototype.submit = function (v) {
949 var w, u, y, x;
950 if (v != null) {
951 v.preventDefault()
952 }
953 x = this.fields;
954 for (u = 0, y = x.length; u < y; u++) {
955 w = x[u];
956 w.submit(w.element, this.annotation)
957 }
958 this.publish("save", [this.annotation]);
959 return this.hide()
960 };
961 t.prototype.addField = function (v) {
962 var w, x, u;
963 x = h.extend({
964 id: "annotator-field-" + (new Date()).getTime(),
965 type: "input",
966 label: "",
967 load: function () {},
968 submit: function () {}
969 }, v);
970 u = null;
971 w = h('<li class="annotator-item" />');
972 x.element = w[0];
973 switch (x.type) {
974 case "textarea":
975 u = h("<textarea />");
976 break;
977 case "input":
978 case "checkbox":
979 u = h("<input />")
980 }
981 w.append(u);
982 u.attr({
983 id: x.id,
984 placeholder: x.label
985 });
986 if (x.type === "checkbox") {
987 u[0].type = "checkbox";
988 w.addClass("annotator-checkbox");
989 w.append(h("<label />", {
990 "for": x.id,
991 html: x.label
992 }))
993 }
994 this.element.find("ul:first").append(w);
995 this.fields.push(x);
996 return x.element
997 };
998 t.prototype.checkOrientation = function () {
999 var u, w, v;
1000 t.__super__.checkOrientation.apply(this, arguments);
1001 v = this.element.find("ul");
1002 u = this.element.find(".annotator-controls");
1003 w = function () {
1004 return v.children().each(function () {
1005 return h(this).parent().prepend(this)
1006 })
1007 };
1008 if (this.element.hasClass(this.classes.invert.y) && v.is(":first-child")) {
1009 u.insertBefore(v);
1010 w()
1011 } else {
1012 if (u.is(":first-child")) {
1013 u.insertAfter(v);
1014 w()
1015 }
1016 }
1017 return this
1018 };
1019 t.prototype.processKeypress = function (u) {
1020 if (u.keyCode === 27) {
1021 return this.hide()
1022 } else {
1023 if (u.keyCode === 13 && !u.shiftKey) {
1024 return this.submit()
1025 }
1026 }
1027 };
1028 t.prototype.onCancelButtonMouseover = function () {
1029 return this.element.find("." + this.classes.focus).removeClass(this.classes.focus)
1030 };
1031 t.prototype.setupDragabbles = function () {
1032 var w, D, z, u, y, B, x, v, A, C;
1033 u = null;
1034 w = this.classes;
1035 z = this.element;
1036 A = null;
1037 v = z.find(".annotator-resize");
1038 D = z.find(".annotator-controls");
1039 C = false;
1040 y = function (E) {
1041 if (E.target === this) {
1042 u = {
1043 element: this,
1044 top: E.pageY,
1045 left: E.pageX
1046 };
1047 A = z.find("textarea:first");
1048 h(window).bind({
1049 "mouseup.annotator-editor-resize": x,
1050 "mousemove.annotator-editor-resize": B
1051 });
1052 return E.preventDefault()
1053 }
1054 };
1055 x = function () {
1056 u = null;
1057 return h(window).unbind(".annotator-editor-resize")
1058 };
1059 B = g(function (I) {
1060 var J, G, F, E, H;
1061 if (u && C === false) {
1062 J = {
1063 top: I.pageY - u.top,
1064 left: I.pageX - u.left
1065 };
1066 if (u.element === v[0]) {
1067 E = A.outerHeight();
1068 H = A.outerWidth();
1069 G = z.hasClass(w.invert.x) ? -1 : 1;
1070 F = z.hasClass(w.invert.y) ? 1 : -1;
1071 A.height(E + (J.top * F));
1072 A.width(H + (J.left * G));
1073 if (A.outerHeight() !== E) {
1074 u.top = I.pageY
1075 }
1076 if (A.outerWidth() !== H) {
1077 u.left = I.pageX
1078 }
1079 } else {
1080 if (u.element === D[0]) {
1081 z.css({
1082 top: parseInt(z.css("top"), 10) + J.top,
1083 left: parseInt(z.css("left"), 10) + J.left
1084 });
1085 u.top = I.pageY;
1086 u.left = I.pageX
1087 }
1088 }
1089 C = true;
1090 return setTimeout(function () {
1091 return C = false
1092 }, 1000 / 60)
1093 }
1094 }, this);
1095 v.bind("mousedown", y);
1096 return D.bind("mousedown", y)
1097 };
1098 return t
1099 })();
1100 o.Viewer = (function () {
1101 q(t, o.Widget);
1102 t.prototype.events = {
1103 ".annotator-edit click": "onEditClick",
1104 ".annotator-delete click": "onDeleteClick"
1105 };
1106 t.prototype.classes = {
1107 hide: "annotator-hide",
1108 showControls: "annotator-visible"
1109 };
1110 t.prototype.html = {
1111 element: '<div class="annotator-outer annotator-viewer">\n <ul class="annotator-widget annotator-listing"></ul>\n</div>',
1112 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>'
1113 };
1114
1115 function t(u) {
1116 this.onDeleteClick = g(this.onDeleteClick, this);
1117 this.onEditClick = g(this.onEditClick, this);
1118 this.load = g(this.load, this);
1119 this.hide = g(this.hide, this);
1120 this.show = g(this.show, this);
1121 t.__super__.constructor.call(this, h(this.html.element)[0], u);
1122 this.item = h(this.html.item)[0];
1123 this.fields = [];
1124 this.annotations = []
1125 }
1126 t.prototype.show = function (v) {
1127 var u;
1128 if (v != null) {
1129 v.preventDefault()
1130 }
1131 u = this.element.find(".annotator-controls").addClass(this.classes.showControls);
1132 setTimeout((g(function () {
1133 return u.removeClass(this.classes.showControls)
1134 }, this)), 500);
1135 this.element.removeClass(this.classes.hide);
1136 return this.checkOrientation().publish("show")
1137 };
1138 t.prototype.isShown = function () {
1139 return !this.element.hasClass(this.classes.hide)
1140 };
1141 t.prototype.hide = function (u) {
1142 if (u != null) {
1143 //u.preventDefault()
1144 }
1145 this.element.addClass(this.classes.hide);
1146 return this.publish("hide")
1147 };
1148 t.prototype.load = function (C) {
1149 var z, B, G, H, F, A, E, I, D, y, w, u, J, x, v;
1150 this.annotations = C || [];
1151 D = this.element.find("ul:first").empty();
1152 x = this.annotations;
1153 for (y = 0, u = x.length; y < u; y++) {
1154 z = x[y];
1155 I = h(this.item).clone().appendTo(D).data("annotation", z);
1156 G = I.find(".annotator-controls");
1157 F = G.find(".annotator-edit");
1158 H = G.find(".annotator-delete");
1159 B = {
1160 showEdit: function () {
1161 return F.removeAttr("disabled")
1162 },
1163 hideEdit: function () {
1164 return F.attr("disabled", "disabled")
1165 },
1166 showDelete: function () {
1167 return H.removeAttr("disabled")
1168 },
1169 hideDelete: function () {
1170 return H.attr("disabled", "disabled")
1171 }
1172 };
1173 v = this.fields;
1174 for (w = 0, J = v.length; w < J; w++) {
1175 E = v[w];
1176 A = h(E.element).clone().appendTo(I)[0];
1177 E.load(A, z, B)
1178 }
1179 }
1180 this.publish("load", [this.annotations]);
1181 return this.show()
1182 };
1183 t.prototype.addField = function (u) {
1184 var v;
1185 v = h.extend({
1186 load: function () {}
1187 }, u);
1188 v.element = h("<div />")[0];
1189 this.fields.push(v);
1190 v.element;
1191 return this
1192 };
1193 t.prototype.onEditClick = function (u) {
1194 return this.onButtonClick(u, "edit")
1195 };
1196 t.prototype.onDeleteClick = function (u) {
1197 return this.onButtonClick(u, "delete")
1198 };
1199 t.prototype.onButtonClick = function (w, u) {
1200 var v;
1201 v = h(w.target).parents(".annotator-annotation");
1202 return this.publish(u, [v.data("annotation")])
1203 };
1204 return t
1205 })();
1206 o = o || {};
1207 o.Notification = (function () {
1208 q(t, b);
1209 t.prototype.events = {
1210 click: "hide"
1211 };
1212 t.prototype.options = {
1213 html: "<div class='annotator-notice'></div>",
1214 classes: {
1215 show: "annotator-notice-show",
1216 info: "annotator-notice-info",
1217 success: "annotator-notice-success",
1218 error: "annotator-notice-error"
1219 }
1220 };
1221
1222 function t(u) {
1223 this.hide = g(this.hide, this);
1224 this.show = g(this.show, this);
1225 t.__super__.constructor.call(this, h(this.options.html).appendTo(document.body)[0], u)
1226 }
1227 t.prototype.show = function (v, u) {
1228 if (u == null) {
1229 u = o.Notification.INFO
1230 }
1231 h(this.element).addClass(this.options.classes.show).addClass(this.options.classes[u]).escape(v || "");
1232 setTimeout(this.hide, 5000);
1233 return this
1234 };
1235 t.prototype.hide = function () {
1236 h(this.element).removeClass(this.options.classes.show);
1237 return this
1238 };
1239 return t
1240 })();
1241 o.Notification.INFO = "show";
1242 o.Notification.SUCCESS = "success";
1243 o.Notification.ERROR = "error";
1244 h(function () {
1245 var t;
1246 t = new o.Notification;
1247 o.showNotification = t.show;
1248 return o.hideNotification = t.hide
1249 });
1250 o.Plugin.Tags = (function () {
1251 q(t, o.Plugin);
1252
1253 function t() {
1254 this.setAnnotationTags = g(this.setAnnotationTags, this);
1255 this.updateField = g(this.updateField, this);
1256 t.__super__.constructor.apply(this, arguments)
1257 }
1258 t.prototype.field = null;
1259 t.prototype.input = null;
1260 t.prototype.pluginInit = function () {
1261 if (!o.supported()) {
1262 return
1263 }
1264 this.field = this.annotator.editor.addField({
1265 label: "Add some tags here\u2026",
1266 load: this.updateField,
1267 submit: this.setAnnotationTags
1268 });
1269 this.annotator.viewer.addField({
1270 load: this.updateViewer
1271 });
1272 if (this.annotator.plugins.Filter) {
1273 this.annotator.plugins.Filter.addFilter({
1274 label: "Tag",
1275 property: "tags",
1276 isFiltered: o.Plugin.Tags.filterCallback
1277 })
1278 }
1279 return this.input = h(this.field).find(":input")
1280 };
1281 t.prototype.parseTags = function (v) {
1282 var u;
1283 v = h.trim(v);
1284 u = [];
1285 if (v) {
1286 u = v.split(/\s+/)
1287 }
1288 return u
1289 };
1290 t.prototype.stringifyTags = function (u) {
1291 return u.join(" ")
1292 };
1293 t.prototype.updateField = function (w, u) {
1294 var v;
1295 v = "";
1296 if (u.tags) {
1297 v = this.stringifyTags(u.tags)
1298 }
1299 return this.input.val(v)
1300 };
1301 t.prototype.setAnnotationTags = function (v, u) {
1302 return u.tags = this.parseTags(this.input.val())
1303 };
1304 t.prototype.updateViewer = function (v, u) {
1305 v = h(v);
1306 if (u.tags && h.isArray(u.tags) && u.tags.length) {
1307 return v.addClass("annotator-tags").html(function () {
1308 var w;
1309 return w = h.map(u.tags, function (x) {
1310 return '<span class="annotator-tag">' + o.$.escape(x) + "</span>"
1311 }).join(" ")
1312 })
1313 } else {
1314 return v.remove()
1315 }
1316 };
1317 return t
1318 })();
1319 o.Plugin.Tags.filterCallback = function (z, B) {
1320 var y, x, w, C, v, u, t, A;
1321 if (B == null) {
1322 B = []
1323 }
1324 w = 0;
1325 x = [];
1326 if (z) {
1327 x = z.split(/\s+/g);
1328 for (v = 0, t = x.length; v < t; v++) {
1329 y = x[v];
1330 if (B.length) {
1331 for (u = 0, A = B.length; u < A; u++) {
1332 C = B[u];
1333 if (C.indexOf(y) !== -1) {
1334 w += 1
1335 }
1336 }
1337 }
1338 }
1339 }
1340 return w === x.length
1341 };
1342 n = function (u) {
1343 var y, t, x, v, w, z;
1344 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})))?)?)?)?";
1345 y = u.match(new RegExp(v));
1346 x = 0;
1347 t = new Date(y[1], 0, 1);
1348 if (y[3]) {
1349 t.setMonth(y[3] - 1)
1350 }
1351 if (y[5]) {
1352 t.setDate(y[5])
1353 }
1354 if (y[7]) {
1355 t.setHours(y[7])
1356 }
1357 if (y[8]) {
1358 t.setMinutes(y[8])
1359 }
1360 if (y[10]) {
1361 t.setSeconds(y[10])
1362 }
1363 if (y[12]) {
1364 t.setMilliseconds(Number("0." + y[12]) * 1000)
1365 }
1366 if (y[14]) {
1367 x = (Number(y[16]) * 60) + Number(y[17]);
1368 x *= (z = y[15] === "-") != null ? z : {
1369 1: -1
1370 }
1371 }
1372 x -= t.getTimezoneOffset();
1373 w = Number(t) + (x * 60 * 1000);
1374 t.setTime(Number(w));
1375 return t
1376 };
1377 o.Plugin.Auth = (function () {
1378 q(t, o.Plugin);
1379 t.prototype.options = {
1380 token: null,
1381 tokenUrl: "/auth/token",
1382 autoFetch: true
1383 };
1384
1385 function t(v, u) {
1386 this.haveValidToken = g(this.haveValidToken, this);
1387 t.__super__.constructor.apply(this, arguments);
1388 this.element.data("annotator:auth", this);
1389 this.waitingForToken = [];
1390 if (this.options.token) {
1391 this.setToken(this.options.token)
1392 } else {
1393 this.requestToken()
1394 }
1395 }
1396 t.prototype.requestToken = function () {
1397 this.requestInProgress = true;
1398 return h.getJSON(this.options.tokenUrl, g(function (v, u, w) {
1399 if (u !== "success") {
1400 return console.error("Couldn't get auth token: " + u, w)
1401 } else {
1402 this.setToken(v);
1403 return this.requestInProgress = false
1404 }
1405 }, this))
1406 };
1407 t.prototype.setToken = function (v) {
1408 var u;
1409 this.token = v;
1410 if (this.haveValidToken()) {
1411 if (this.options.autoFetch) {
1412 this.refreshTimeout = setTimeout((g(function () {
1413 return this.requestToken()
1414 }, this)), (this.timeToExpiry() - 2) * 1000)
1415 }
1416 this.updateHeaders();
1417 u = [];
1418 while (this.waitingForToken.length > 0) {
1419 u.push(this.waitingForToken.pop().apply())
1420 }
1421 return u
1422 } else {
1423 console.warn("Didn't get a valid token.");
1424 if (this.options.autoFetch) {
1425 console.warn("Getting a new token in 10s.");
1426 return setTimeout((g(function () {
1427 return this.requestToken()
1428 }, this)), 10 * 1000)
1429 }
1430 }
1431 };
1432 t.prototype.haveValidToken = function () {
1433 var u;
1434 u = this.token && this.token.authToken && this.token.authTokenIssueTime && this.token.authTokenTTL && this.token.accountId && this.token.userId;
1435 return u && this.timeToExpiry() > 0
1436 };
1437 t.prototype.timeToExpiry = function () {
1438 var w, u, v, x;
1439 v = new Date().getTime() / 1000;
1440 u = n(this.token.authTokenIssueTime).getTime() / 1000;
1441 w = u + this.token.authTokenTTL;
1442 x = w - v;
1443 if (x > 0) {
1444 return x
1445 } else {
1446 return 0
1447 }
1448 };
1449 t.prototype.updateHeaders = function () {
1450 var u;
1451 u = this.element.data("annotator:headers");
1452 return this.element.data("annotator:headers", h.extend(u, {
1453 "x-annotator-auth-token": this.token.authToken,
1454 "x-annotator-auth-token-issue-time": this.token.authTokenIssueTime,
1455 "x-annotator-auth-token-ttl": this.token.authTokenTTL,
1456 "x-annotator-account-id": this.token.accountId,
1457 "x-annotator-user-id": this.token.userId
1458 }))
1459 };
1460 t.prototype.withToken = function (u) {
1461 if (!(u != null)) {
1462 return
1463 }
1464 if (this.haveValidToken()) {
1465 return u()
1466 } else {
1467 this.waitingForToken.push(u);
1468 if (!this.requestInProgress) {
1469 return this.requestToken()
1470 }
1471 }
1472 };
1473 return t
1474 })();
1475 o.Plugin.Store = (function () {
1476 q(t, o.Plugin);
1477 t.prototype.events = {
1478 annotationCreated: "annotationCreated",
1479 annotationDeleted: "annotationDeleted",
1480 annotationUpdated: "annotationUpdated"
1481 };
1482 t.prototype.options = {
1483 prefix: "/store",
1484 autoFetch: true,
1485 annotationData: {},
1486 loadFromSearch: false,
1487 urls: {
1488 create: "/annotations",
1489 read: "/annotations/:id",
1490 update: "/annotations/:id",
1491 destroy: "/annotations/:id",
1492 search: "/search"
1493 }
1494 };
1495
1496 function t(v, u) {
1497 this._onError = g(this._onError, this);
1498 this._onBeforeSend = g(this._onBeforeSend, this);
1499 this._onLoadAnnotationsFromSearch = g(this._onLoadAnnotationsFromSearch, this);
1500 this._onLoadAnnotations = g(this._onLoadAnnotations, this);
1501 this._getAnnotations = g(this._getAnnotations, this);
1502 t.__super__.constructor.apply(this, arguments);
1503 this.annotations = []
1504 }
1505 t.prototype.pluginInit = function () {
1506 var u;
1507 if (!o.supported()) {
1508 return
1509 }
1510 u = this.element.data("annotator:auth");
1511 if (u) {
1512 return u.withToken(this._getAnnotations)
1513 } else {
1514 return this._getAnnotations()
1515 }
1516 };
1517 t.prototype._getAnnotations = function () {
1518 if (this.options.loadFromSearch) {
1519 return this.loadAnnotationsFromSearch(this.options.loadFromSearch)
1520 } else {
1521 return this.loadAnnotations()
1522 }
1523 };
1524 t.prototype.annotationCreated = function (u) {
1525 if (f.call(this.annotations, u) < 0) {
1526 this.registerAnnotation(u);
1527 return this._apiRequest("create", u, g(function (v) {
1528 if (!(v.id != null)) {
1529 console.warn("Warning: No ID returned from server for annotation ", u)
1530 }
1531 return this.updateAnnotation(u, v)
1532 }, this))
1533 } else {
1534 return this.updateAnnotation(u, {})
1535 }
1536 };
1537 t.prototype.annotationUpdated = function (u) {
1538 if (f.call(this.annotations, u) >= 0) {
1539 return this._apiRequest("update", u, (g(function (v) {
1540 return this.updateAnnotation(u, v)
1541 }, this)))
1542 }
1543 };
1544 t.prototype.annotationDeleted = function (u) {
1545 if (f.call(this.annotations, u) >= 0) {
1546 return this._apiRequest("destroy", u, (g(function () {
1547 return this.unregisterAnnotation(u)
1548 }, this)))
1549 }
1550 };
1551 t.prototype.registerAnnotation = function (u) {
1552 return this.annotations.push(u)
1553 };
1554 t.prototype.unregisterAnnotation = function (u) {
1555 return this.annotations.splice(this.annotations.indexOf(u), 1)
1556 };
1557 t.prototype.updateAnnotation = function (u, v) {
1558 if (f.call(this.annotations, u) < 0) {
1559 console.error("Trying to update unregistered annotation!")
1560 } else {
1561 h.extend(u, v)
1562 }
1563 return h(u.highlights).data("annotation", u)
1564 };
1565 t.prototype.loadAnnotations = function () {
1566 return this._apiRequest("read", null, this._onLoadAnnotations)
1567 };
1568 t.prototype._onLoadAnnotations = function (u) {
1569 if (u == null) {
1570 u = []
1571 }
1572 this.annotations = u;
1573 return this.annotator.loadAnnotations(u.slice())
1574 };
1575 t.prototype.loadAnnotationsFromSearch = function (u) {
1576 return this._apiRequest("search", u, this._onLoadAnnotationsFromSearch)
1577 };
1578 t.prototype._onLoadAnnotationsFromSearch = function (u) {
1579 if (u == null) {
1580 u = {}
1581 }
1582 return this._onLoadAnnotations(u.rows || [])
1583 };
1584 t.prototype.dumpAnnotations = function () {
1585 var w, v, y, x, u;
1586 x = this.annotations;
1587 u = [];
1588 for (v = 0, y = x.length; v < y; v++) {
1589 w = x[v];
1590 u.push(JSON.parse(this._dataFor(w)))
1591 }
1592 return u
1593 };
1594 t.prototype._apiRequest = function (x, y, z) {
1595 var A, v, w, u;
1596 A = y && y.id;
1597 u = this._urlFor(x, A);
1598 v = this._apiRequestOptions(x, y, z);
1599 w = h.ajax(u, v);
1600 w._id = A;
1601 w._action = x;
1602 return w
1603 };
1604 t.prototype._apiRequestOptions = function (v, w, x) {
1605 var u;
1606 u = {
1607 type: this._methodFor(v),
1608 beforeSend: this._onBeforeSend,
1609 dataType: "json",
1610 success: x ||
1611 function () {},
1612 error: this._onError
1613 };
1614 if (v === "search") {
1615 u = h.extend(u, {
1616 data: w
1617 })
1618 } else {
1619 u = h.extend(u, {
1620 data: w && this._dataFor(w),
1621 contentType: "application/json; charset=utf-8"
1622 })
1623 }
1624 return u
1625 };
1626 t.prototype._urlFor = function (w, x) {
1627 var u, v;
1628 u = x != null ? "/" + x : "";
1629 v = this.options.prefix || "/";
1630 v += this.options.urls[w];
1631 v = v.replace(/\/:id/, u);
1632 return v
1633 };
1634 t.prototype._methodFor = function (v) {
1635 var u;
1636 u = {
1637 create: "POST",
1638 read: "GET",
1639 update: "PUT",
1640 destroy: "DELETE",
1641 search: "GET"
1642 };
1643 return u[v]
1644 };
1645 t.prototype._dataFor = function (u) {
1646 var v, w;
1647 w = u.highlights;
1648 delete u.highlights;
1649 h.extend(u, this.options.annotationData);
1650 v = JSON.stringify(u);
1651 if (w) {
1652 u.highlights = w
1653 }
1654 return v
1655 };
1656 t.prototype._onBeforeSend = function (y) {
1657 var x, v, w, u;
1658 x = this.element.data("annotator:headers");
1659 if (x) {
1660 u = [];
1661 for (v in x) {
1662 w = x[v];
1663 u.push(y.setRequestHeader(v, w))
1664 }
1665 return u
1666 }
1667 };
1668 t.prototype._onError = function (w) {
1669 var v, u;
1670 v = w._action;
1671 u = "Sorry we could not " + v + " this annotation";
1672 if (w._action === "search") {
1673 u = "Sorry we could not search the store for annotations"
1674 } else {
1675 if (w._action === "read" && !w._id) {
1676 u = "Sorry we could not " + v + " the annotations from the store"
1677 }
1678 }
1679 switch (w.status) {
1680 case 401:
1681 u = "Sorry you are not allowed to " + v + " this annotation";
1682 break;
1683 case 404:
1684 u = "Sorry we could not connect to the annotations store";
1685 break;
1686 case 500:
1687 u = "Sorry something went wrong with the annotation store"
1688 }
1689 o.showNotification(u, o.Notification.ERROR);
1690 return console.error("API request failed: '" + w.status + "'")
1691 };
1692 return t
1693 })();
1694 o.Plugin.Filter = (function () {
1695 q(t, o.Plugin);
1696 t.prototype.events = {
1697 ".annotator-filter-property input focus": "_onFilterFocus",
1698 ".annotator-filter-property input blur": "_onFilterBlur",
1699 ".annotator-filter-property input keyup": "_onFilterKeyup",
1700 ".annotator-filter-previous click": "_onPreviousClick",
1701 ".annotator-filter-next click": "_onNextClick",
1702 ".annotator-filter-clear click": "_onClearClick"
1703 };
1704 t.prototype.classes = {
1705 active: "annotator-filter-active",
1706 hl: {
1707 hide: "annotator-hl-filtered",
1708 active: "annotator-hl-active"
1709 }
1710 };
1711 t.prototype.html = {
1712 // 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>',
1713 filter: '<span class="annotator-filter-property">\n <label></label>\n <input/>\n <button class="annotator-filter-clear">Clear</button>\n</span>'
1714 };
1715 t.prototype.options = {
1716 appendTo: "body",
1717 filters: [],
1718 addAnnotationFilter: true,
1719 isFiltered: function (v, x) {
1720 var u, w, z, y;
1721 if (!(v && x)) {
1722 return false
1723 }
1724 y = v.split(/\s*/);
1725 for (w = 0, z = y.length; w < z; w++) {
1726 u = y[w];
1727 if (x.indexOf(u) === -1) {
1728 return false
1729 }
1730 }
1731 return true
1732 }
1733 };
1734
1735 function t(v, u) {
1736 this._onPreviousClick = g(this._onPreviousClick, this);
1737 this._onNextClick = g(this._onNextClick, this);
1738 this._onFilterKeyup = g(this._onFilterKeyup, this);
1739 this._onFilterBlur = g(this._onFilterBlur, this);
1740 this._onFilterFocus = g(this._onFilterFocus, this);
1741 this.updateHighlights = g(this.updateHighlights, this);
1742 v = h(this.html.element).appendTo(this.options.appendTo);
1743 t.__super__.constructor.call(this, v, u);
1744 this.filter = h(this.html.filter);
1745 this.filters = [];
1746 this.current = 0
1747 }
1748 t.prototype.pluginInit = function () {
1749 var v, u, x, w;
1750 w = this.options.filters;
1751 for (u = 0, x = w.length; u < x; u++) {
1752 v = w[u];
1753 this.addFilter(v)
1754 }
1755 this.updateHighlights();
1756 this._setupListeners()._insertSpacer();
1757 if (this.options.addAnnotationFilter === true) {
1758 return this.addFilter({
1759 label: "Annotation",
1760 property: "text"
1761 })
1762 }
1763 };
1764 t.prototype._insertSpacer = function () {
1765 var v, u;
1766 u = h("html");
1767 v = parseInt(u.css("padding-top"), 10) || 0;
1768 u.css("padding-top", v + this.element.outerHeight());
1769 return this
1770 };
1771 t.prototype._setupListeners = function () {
1772 var w, u, v, x;
1773 u = ["annotationsLoaded", "annotationCreated", "annotationUpdated", "annotationDeleted"];
1774 for (v = 0, x = u.length; v < x; v++) {
1775 w = u[v];
1776 this.annotator.subscribe(w, this.updateHighlights)
1777 }
1778 return this
1779 };
1780 t.prototype.addFilter = function (u) {
1781 var w, v;
1782 v = h.extend({
1783 label: "",
1784 property: "",
1785 isFiltered: this.options.isFiltered
1786 }, u);
1787 if (!((function () {
1788 var y, A, z, x;
1789 z = this.filters;
1790 x = [];
1791 for (y = 0, A = z.length; y < A; y++) {
1792 w = z[y];
1793 if (w.property === v.property) {
1794 x.push(w)
1795 }
1796 }
1797 return x
1798 }).call(this)).length) {
1799 v.id = "annotator-filter-" + v.property;
1800 v.annotations = [];
1801 v.element = this.filter.clone().appendTo(this.element);
1802 v.element.find("label").html(v.label).attr("for", v.id);
1803 v.element.find("input").attr({
1804 id: v.id,
1805 placeholder: "Filter by " + v.label + "\u2026"
1806 });
1807 v.element.find("button").hide();
1808 v.element.data("filter", v);
1809 this.filters.push(v)
1810 }
1811 return this
1812 };
1813 t.prototype.updateFilter = function (x) {
1814 var u, z, v, y, w, B, A;
1815 x.annotations = [];
1816 this.updateHighlights();
1817 this.resetHighlights();
1818 v = h.trim(x.element.find("input").val());
1819 if (v) {
1820 z = this.highlights.map(function () {
1821 return h(this).data("annotation")
1822 });
1823 A = h.makeArray(z);
1824 for (w = 0, B = A.length; w < B; w++) {
1825 u = A[w];
1826 y = u[x.property];
1827 if (x.isFiltered(v, y)) {
1828 x.annotations.push(u)
1829 }
1830 }
1831 return this.filterHighlights()
1832 }
1833 };
1834 t.prototype.updateHighlights = function () {
1835 this.highlights = this.annotator.element.find(".annotator-hl:visible");
1836 return this.filtered = this.highlights.not(this.classes.hl.hide)
1837 };
1838 t.prototype.filterHighlights = function () {
1839 var v, x, y, B, z, A, C, u, w;
1840 v = h.grep(this.filters, function (D) {
1841 return !!D.annotations.length
1842 });
1843 B = ((w = v[0]) != null ? w.annotations : void 0) || [];
1844 if (v.length > 1) {
1845 y = [];
1846 h.each(v, function () {
1847 return h.merge(y, this.annotations)
1848 });
1849 C = [];
1850 B = [];
1851 h.each(y, function () {
1852 if (h.inArray(this, C) === -1) {
1853 return C.push(this)
1854 } else {
1855 return B.push(this)
1856 }
1857 })
1858 }
1859 z = this.highlights;
1860 for (A = 0, u = B.length; A < u; A++) {
1861 x = B[A];
1862 z = z.not(x.highlights)
1863 }
1864 z.addClass(this.classes.hl.hide);
1865 this.filtered = this.highlights.not(this.classes.hl.hide);
1866 return this
1867 };
1868 t.prototype.resetHighlights = function () {
1869 this.highlights.removeClass(this.classes.hl.hide);
1870 this.filtered = this.highlights;
1871 return this
1872 };
1873 t.prototype._onFilterFocus = function (v) {
1874 var u;
1875 u = h(v.target);
1876 u.parent().addClass(this.classes.active);
1877 return u.next("button").show()
1878 };
1879 t.prototype._onFilterBlur = function (v) {
1880 var u;
1881 if (!v.target.value) {
1882 u = h(v.target);
1883 u.parent().removeClass(this.classes.active);
1884 return u.next("button").hide()
1885 }
1886 };
1887 t.prototype._onFilterKeyup = function (v) {
1888 var u;
1889 u = h(v.target).parent().data("filter");
1890 if (u) {
1891 return this.updateFilter(u)
1892 }
1893 };
1894 t.prototype._findNextHighlight = function (z) {
1895 var v, w, B, A, y, x, u, C;
1896 if (!this.highlights.length) {
1897 return this
1898 }
1899 x = z ? 0 : -1;
1900 C = z ? -1 : 0;
1901 u = z ? "lt" : "gt";
1902 v = this.highlights.not("." + this.classes.hl.hide);
1903 B = v.filter("." + this.classes.hl.active);
1904 if (!B.length) {
1905 B = v.eq(x)
1906 }
1907 w = B.data("annotation");
1908 A = v.index(B[0]);
1909 y = v.filter(":" + u + "(" + A + ")").not(w.highlights).eq(C);
1910 if (!y.length) {
1911 y = v.eq(C)
1912 }
1913 return this._scrollToHighlight(y.data("annotation").highlights)
1914 };
1915 t.prototype._onNextClick = function (u) {
1916 return this._findNextHighlight()
1917 };
1918 t.prototype._onPreviousClick = function (u) {
1919 return this._findNextHighlight(true)
1920 };
1921 t.prototype._scrollToHighlight = function (u) {
1922 u = h(u);
1923 this.highlights.removeClass(this.classes.hl.active);
1924 u.addClass(this.classes.hl.active);
1925 return h("html, body").animate({
1926 scrollTop: u.offset().top - (this.element.height() + 20)
1927 }, 150)
1928 };
1929 t.prototype._onClearClick = function (u) {
1930 return h(u.target).prev("input").val("").keyup().blur()
1931 };
1932 return t
1933 })();
1934 o.Plugin.Markdown = (function () {
1935 q(t, o.Plugin);
1936 t.prototype.events = {
1937 annotationViewerTextField: "updateTextField"
1938 };
1939
1940 function t(v, u) {
1941 this.updateTextField = g(this.updateTextField, this);
1942 if ((typeof Showdown !== "undefined" && Showdown !== null ? Showdown.converter : void 0) != null) {
1943 t.__super__.constructor.apply(this, arguments);
1944 this.converter = new Showdown.converter()
1945 } else {
1946 console.error("To use the Markdown plugin, you must include Showdown into the page first.")
1947 }
1948 }
1949 t.prototype.updateTextField = function (v, u) {
1950 var w;
1951 w = o.$.escape(u.text || "");
1952 return h(v).html(this.convert(w))
1953 };
1954 t.prototype.convert = function (u) {
1955 return this.converter.makeHtml(u)
1956 };
1957 return t
1958 })();
1959 o.Plugin.Unsupported = (function () {
1960 q(t, o.Plugin);
1961
1962 function t() {
1963 t.__super__.constructor.apply(this, arguments)
1964 }
1965 t.prototype.options = {
1966 message: "Sorry your current browser does not support the Annotator"
1967 };
1968 t.prototype.pluginInit = function () {
1969 if (!o.supported()) {
1970 return h(g(function () {
1971 o.showNotification(this.options.message);
1972 if ((window.XMLHttpRequest === void 0) && (ActiveXObject !== void 0)) {
1973 return h("html").addClass("ie6")
1974 }
1975 }, this))
1976 }
1977 };
1978 return t
1979 })();
1980 o.Plugin.Permissions = (function () {
1981 q(t, o.Plugin);
1982 t.prototype.events = {
1983 beforeAnnotationCreated: "addFieldsToAnnotation"
1984 };
1985 t.prototype.options = {
1986 showViewPermissionsCheckbox: true,
1987 showEditPermissionsCheckbox: true,
1988 userId: function (u) {
1989 return u
1990 },
1991 userString: function (u) {
1992 return u
1993 },
1994 userAuthorize: function (u, v) {
1995 return this.userId(u) === v
1996 },
1997 user: "",
1998 permissions: {
1999 read: [],
2000 update: [],
2001 "delete": [],
2002 admin: []
2003 }
2004 };
2005
2006 function t(v, u) {
2007 this.updateViewer = g(this.updateViewer, this);
2008 this.updateAnnotationPermissions = g(this.updateAnnotationPermissions, this);
2009 this.updatePermissionsField = g(this.updatePermissionsField, this);
2010 this.addFieldsToAnnotation = g(this.addFieldsToAnnotation, this);
2011 t.__super__.constructor.apply(this, arguments);
2012 if (this.options.user) {
2013 this.setUser(this.options.user);
2014 delete this.options.user
2015 }
2016 }
2017 t.prototype.pluginInit = function () {
2018 var u, v;
2019 if (!o.supported()) {
2020 return
2021 }
2022 v = this;
2023 u = function (x, w) {
2024 return function (z, y) {
2025 return v[x].call(v, w, z, y)
2026 }
2027 };
2028 if (this.options.showViewPermissionsCheckbox === true) {
2029 this.annotator.editor.addField({
2030 type: "checkbox",
2031 label: "Allow anyone to <strong>view</strong> this annotation",
2032 load: u("updatePermissionsField", "read"),
2033 submit: u("updateAnnotationPermissions", "read")
2034 })
2035 }
2036 if (this.options.showEditPermissionsCheckbox === true) {
2037 this.annotator.editor.addField({
2038 type: "checkbox",
2039 label: "Allow anyone to <strong>edit</strong> this annotation",
2040 load: u("updatePermissionsField", "update"),
2041 submit: u("updateAnnotationPermissions", "update")
2042 })
2043 }
2044 this.annotator.viewer.addField({
2045 load: this.updateViewer
2046 });
2047 if (this.annotator.plugins.Filter) {
2048 return this.annotator.plugins.Filter.addFilter({
2049 label: "User",
2050 property: "user",
2051 isFiltered: g(function (y, x) {
2052 var w, z, B, A;
2053 x = this.options.userString(x);
2054 if (!(y && x)) {
2055 return false
2056 }
2057 A = y.split(/\s*/);
2058 for (z = 0, B = A.length; z < B; z++) {
2059 w = A[z];
2060 if (x.indexOf(w) === -1) {
2061 return false
2062 }
2063 }
2064 return true
2065 }, this)
2066 })
2067 }
2068 };
2069 t.prototype.setUser = function (u) {
2070 return this.user = u
2071 };
2072 t.prototype.addFieldsToAnnotation = function (u) {
2073 if (u) {
2074 u.permissions = this.options.permissions;
2075 if (this.user) {
2076 return u.user = this.user
2077 }
2078 }
2079 };
2080 t.prototype.authorize = function (y, u, v) {
2081 var w, z, x, A;
2082 if (v === void 0) {
2083 v = this.user
2084 }
2085 if (u.permissions) {
2086 z = u.permissions[y] || [];
2087 if (z.length === 0) {
2088 return true
2089 }
2090 for (x = 0, A = z.length; x < A; x++) {
2091 w = z[x];
2092 if (this.options.userAuthorize.call(this.options, v, w)) {
2093 return true
2094 }
2095 }
2096 return false
2097 } else {
2098 if (u.user) {
2099 return v && this.options.userId(v) === u.user
2100 }
2101 }
2102 return true
2103 };
2104 t.prototype.updatePermissionsField = function (w, y, u) {
2105 var x, v;
2106 y = h(y).show();
2107 v = y.find("input").removeAttr("disabled");
2108 if (!this.authorize("admin", u)) {
2109 y.hide()
2110 }
2111 if (this.authorize(w, u || {}, null)) {
2112 v.attr("checked", "checked");
2113 x = {
2114 permissions: this.options.permissions
2115 };
2116 if (this.authorize(w, x, null)) {
2117 return v.attr("disabled", "disabled")
2118 }
2119 } else {
2120 return v.removeAttr("checked")
2121 }
2122 };
2123 t.prototype.updateAnnotationPermissions = function (w, x, u) {
2124 var y, v;
2125 if (!u.permissions) {
2126 u.permissions = this.options.permissions
2127 }
2128 y = w + "-permissions";
2129 if (h(x).find("input").is(":checked")) {
2130 h.data(u, y, u.permissions[w]);
2131 return u.permissions[w] = []
2132 } else {
2133 v = h.data(u, y);
2134 if (v) {
2135 return u.permissions[w] = v
2136 }
2137 }
2138 };
2139 t.prototype.updateViewer = function (x, u, w) {
2140 var v, y;
2141 x = h(x);
2142 y = this.options.userString(u.user);
2143 if (u.user && y && typeof y === "string") {
2144 v = o.$.escape(this.options.userString(u.user));
2145 x.html(v).addClass("annotator-user")
2146 } else {
2147 x.remove()
2148 }
2149 if (u.permissions) {
2150 if (!this.authorize("update", u)) {
2151 w.hideEdit()
2152 }
2153 if (!this.authorize("delete", u)) {
2154 return w.hideDelete()
2155 }
2156 } else {
2157 if (u.user && !this.authorize(null, u)) {
2158 w.hideEdit();
2159 return w.hideDelete()
2160 }
2161 }
2162 };
2163 return t
2164 })();
2165 o.prototype.setupPlugins = function (w, E) {
2166 var B, D, u, t, y, v, A, C, z, x;
2167 if (w == null) {
2168 w = {}
2169 }
2170 if (E == null) {
2171 E = {}
2172 }
2173 z = a.getGlobal();
2174 y = {
2175 Tags: {},
2176 Filter: {
2177 filters: [{
2178 label: "User",
2179 property: "user"
2180 }, {
2181 label: "Tags",
2182 property: "tags"
2183 }]
2184 },
2185 Unsupported: {}
2186 };
2187 if (z.Showdown) {
2188 y.Markdown = {}
2189 }
2190 A = w.userId, C = w.userName, B = w.accountId, D = w.authToken;
2191 if (A && C && B && D) {
2192 v = z.location.href.split(/#|\?/).shift() || "";
2193 h.extend(y, {
2194 Store: {
2195 prefix: w.storeUri || "http://annotateit.org/api",
2196 annotationData: {
2197 uri: v
2198 },
2199 loadFromSearch: {
2200 uri: v,
2201 all_fields: 1
2202 }
2203 },
2204 Permissions: {
2205 user: {
2206 id: w.userId,
2207 name: w.userName
2208 },
2209 permissions: {
2210 read: [w.userId],
2211 update: [w.userId],
2212 "delete": [w.userId],
2213 admin: [w.userId]
2214 },
2215 userId: function (F) {
2216 if (F != null ? F.id : void 0) {
2217 return F.id
2218 } else {
2219 return ""
2220 }
2221 },
2222 userString: function (F) {
2223 if (F != null ? F.name : void 0) {
2224 return F.name
2225 } else {
2226 return ""
2227 }
2228 }
2229 }
2230 });
2231 this.element.data({
2232 "annotator:headers": {
2233 "X-Annotator-User-Id": w.userId,
2234 "X-Annotator-Account-Id": w.accountId,
2235 "X-Annotator-Auth-Token": w.authToken
2236 }
2237 })
2238 }
2239 h.extend(y, E);
2240 x = [];
2241 for (u in y) {
2242 if (!k.call(y, u)) {
2243 continue
2244 }
2245 t = y[u];
2246 if (t !== null && t !== false) {
2247 x.push(this.addPlugin(u, t))
2248 }
2249 }
2250 return x
2251 }
2252}).call(this);
Note: See TracBrowser for help on using the repository browser.