// ==UserScript==
// @name annotation
// @namespace
// @version 0.1 beta
// @require http://code.jquery.com/jquery-2.1.1.js
// @description 在网页上添加注释,文字高亮。本脚本基于‘Annotation’--一个可以轻松在网页上添加注释的公开库。我仅仅将代码整合一下,使其成为一个类似add-one的用户脚本。//To easily annotate and highlight the contents on webpage.This userscript relays on 'Annotator'--an open-source JavaScript library to easily add annotation functionality to any webpage. I just integrated some code and make it a add-one like userscript.
// @description For more imformation or copyright problems,please email me at wang0xinzhe@gmail.com.
// @include /^https?://*/
// @exclude http://pan.baidu.com/*
// @exclude http://play.baidu.com/*
// @exclude http://www.baidu.com/*
// @exclude /^https?://www\.google\./
// @exclude /^https?://\.bing\./
// @exclude http://annotatorjs.org/
// @encoding utf-8
// @license MIT license
// @run-at document-end
// @copyright 2014,7,4 __By Wang Hsin-che
// ==/UserScript==
/*
** Annotator v1.2.7
** https://github.com/okfn/annotator/
**
** Copyright 2012 Aron Carroll, Rufus Pollock, and Nick Stenning.
** Dual licensed under the MIT and GPLv3 licenses.
** https://github.com/okfn/annotator/blob/master/LICENSE
**
** Built at: 2013-06-27 21:49:35Z
*/
((function () {
var a,
b,
c,
d,
e,
f,
g,
h,
i,
j,
k,
l,
m,
n,
o,
p,
q,
r,
s,
t,
u,
v,
w,
x,
y,
z,
A,
B,
C,
D,
E,
F = [
].slice,
G = {
}.hasOwnProperty,
H = function (a, b) {
function d() {
this.constructor = a
}
for (var c in b) G.call(b, c) && (a[c] = b[c]);
return d.prototype = b.prototype,
a.prototype = new d,
a.__super__ = b.prototype,
a
},
I = function (a, b) {
return function () {
return a.apply(b, arguments)
}
},
J = [
].indexOf || function (a) {
for (var b = 0, c = this.length; b < c; b++) if (b in this && this[b] === a) return b;
return - 1
};
r = function (b) {
var c;
return c = this.map(function () {
var c,
d,
e,
f;
e = '',
c = this;
while ((c != null ? c.nodeType : void 0) === Node.ELEMENT_NODE && c !== b) f = c.tagName.replace(':', '\:'),
d = a(c.parentNode) .children(f) .index(c) + 1,
d = '[' + d + ']',
e = '/' + c.tagName.toLowerCase() + d + e,
c = c.parentNode;
return e
}),
c.get()
},
s = function (a) {
var b,
c,
d,
e;
return b = function (a) {
var b,
c;
return b = n(a),
c = o(a),
'' + b + '[' + c + ']'
},
e = a,
c = function (a) {
var c;
c = '';
while (a !== e) {
if (a == null) throw new Error('Called getPathTo on a node which was not a descendant of @rootNode. ' + e);
c = b(a) + '/' + c,
a = a.parentNode
}
return c = '/' + c,
c = c.replace(/\/$/, ''),
c
},
d = this.map(function () {
var a;
return a = c(this),
a
}),
d.get()
},
j = function (a, b, c) {
var d,
e,
f,
g,
h,
i;
if (!a.hasChildNodes()) throw new Error('XPath error: node has no children!');
e = a.childNodes,
f = 0;
for (h = 0, i = e.length; h < i; h++) {
d = e[h],
g = n(d);
if (g === b) {
f += 1;
if (f === c) return d
}
}
throw new Error('XPath error: wanted child not found.')
},
n = function (a) {
var b;
b = a.nodeName.toLowerCase();
switch (b) {
case '#text':
return 'text()';
case '#comment':
return 'comment()';
case '#cdata-section':
return 'cdata-section()';
default:
return b
}
},
o = function (a) {
var b,
c;
b = 0,
c = a;
while (c) c.nodeName === a.nodeName && b++,
c = c.previousSibling;
return b
},
p = null,
typeof Gettext != 'undefined' && Gettext !== null ? (u = new Gettext({
domain: 'annotator'
}), p = function (a) {
return u.gettext(a)
}) : p = function (a) {
return a
},
E = function (a) {
return p(a)
},
(typeof jQuery != 'undefined' && jQuery !== null ? (z = jQuery.fn) != null ? z.jquery : void 0 : void 0) || console.error(E('Annotator requires jQuery: have you included lib/vendor/jquery.js?')),
JSON && JSON.parse && JSON.stringify || console.error(E('Annotator requires a JSON implementation: have you included lib/vendor/json2.js?')),
a = jQuery,
f = {
},
f.flatten = function (b) {
var c;
return c = function (b) {
var d,
e,
f,
g;
e = [
];
for (f = 0, g = b.length; f < g; f++) d = b[f],
e = e.concat(d && a.isArray(d) ? c(d) : d);
return e
},
c(b)
},
f.getTextNodes = function (a) {
var b;
return b = function (a) {
var c;
if (a && a.nodeType !== Node.TEXT_NODE) {
c = [
];
if (a.nodeType !== Node.COMMENT_NODE) {
a = a.lastChild;
while (a) c.push(b(a)),
a = a.previousSibling
}
return c.reverse()
}
return a
},
a.map(function () {
return f.flatten(b(this))
})
},
f.xpathFromNode = function (a, b) {
var c,
d;
try {
d = r.call(a, b)
} catch (e) {
c = e,
console.log('jQuery-based XPath construction failed! Falling back to manual.'),
d = s.call(a, b)
}
return d
},
f.nodeFromXPath = function (a, b) {
var c,
d,
e,
f,
g,
h,
i,
k;
g = a.substring(1) .split('/'),
e = b;
for (h = 0, i = g.length; h < i; h++) f = g[h],
k = f.split('['),
d = k[0],
c = k[1],
c = c != null ? parseInt((c != null ? c.split(']') : void 0) [0]) : 1,
e = j(e, d.toLowerCase(), c);
return e
},
f.escape = function (a) {
return a.replace(/&(?!\w+;)/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"')
},
f.uuid = function () {
var a;
return a = 0,
function () {
return a++
}
}(),
f.getGlobal = function () {
return function () {
return this
}()
},
f.maxZIndex = function (b) {
var c,
d;
return c = function () {
var c,
e,
f;
f = [
];
for (c = 0, e = b.length; c < e; c++) d = b[c],
a(d) .css('position') === 'static' ? f.push( - 1) : f.push(parseInt(a(d) .css('z-index'), 10) || - 1);
return f
}(),
Math.max.apply(Math, c)
},
f.mousePosition = function (b, c) {
var d;
return d = a(c) .position(),
{
top: b.pageY - d.top,
left: b.pageX - d.left
}
},
f.preventEventDefault = function (a) {
return a != null ? typeof a.preventDefault == 'function' ? a.preventDefault() : void 0 : void 0
},
l = [
'log',
'debug',
'info',
'warn',
'exception',
'assert',
'dir',
'dirxml',
'trace',
'group',
'groupEnd',
'groupCollapsed',
'time',
'timeEnd',
'profile',
'profileEnd',
'count',
'clear',
'table',
'error',
'notifyFirebug',
'firebug',
'userObjects'
];
if (typeof console != 'undefined' && console !== null) {
console.group == null && (console.group = function (a) {
return console.log('GROUP: ', a)
}),
console.groupCollapsed == null && (console.groupCollapsed = console.group);
for (v = 0, x = l.length; v < x; v++) k = l[v],
console[k] == null && (console[k] = function () {
return console.log(E('Not implemented:') + (' console.' + name))
})
} else {
this.console = {
};
for (w = 0, y = l.length; w < y; w++) k = l[w],
this.console[k] = function () {
};
this.console.error = function () {
var a;
return a = 1 <= arguments.length ? F.call(arguments, 0) : [
],
alert('ERROR: ' + a.join(', '))
},
this.console.warn = function () {
var a;
return a = 1 <= arguments.length ? F.call(arguments, 0) : [
],
alert('WARNING: ' + a.join(', '))
}
}
c = function () {
function b(b, c) {
this.options = a.extend(!0, {
}, this.options, c),
this.element = a(b),
this.on = this.subscribe,
this.addEvents()
}
return b.prototype.events = {
},
b.prototype.options = {
},
b.prototype.element = null,
b.prototype.addEvents = function () {
var a,
b,
c,
d,
e,
f,
g,
h;
f = this.events,
h = [
];
for (c in f) b = f[c],
g = c.split(' '),
d = 2 <= g.length ? F.call(g, 0, e = g.length - 1) : (e = 0, [
]),
a = g[e++],
h.push(this.addEvent(d.join(' '), a, b));
return h
},
b.prototype.addEvent = function (b, c, d) {
var e,
f,
g = this;
return e = function () {
return g[d].apply(g, arguments)
},
f = typeof b == 'string' && b.replace(/\s+/g, '') === '',
f && (b = this.element),
typeof b == 'string' ? this.element.delegate(b, c, e) : this.isCustomEvent(c) ? this.subscribe(c, e) : a(b) .bind(c, e),
this
},
b.prototype.isCustomEvent = function (c) {
return c = c.split('.') [0],
a.inArray(c, b.natives) === - 1
},
b.prototype.publish = function () {
return this.element.triggerHandler.apply(this.element, arguments),
this
},
b.prototype.subscribe = function (b, c) {
var d;
return d = function () {
return c.apply(this, [
].slice.call(arguments, 1))
},
d.guid = c.guid = a.guid += 1,
this.element.bind(b, d),
this
},
b.prototype.unsubscribe = function () {
return this.element.unbind.apply(this.element, arguments),
this
},
b
}(),
c.natives = function () {
var a,
b,
c;
return b = function () {
var b,
d;
b = jQuery.event.special,
d = [
];
for (a in b) {
if (!G.call(b, a)) continue;
c = b[a],
d.push(a)
}
return d
}(),
'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]+/) .concat(b)
}(),
e = {
},
e.sniff = function (a) {
return a.commonAncestorContainer != null ? new e.BrowserRange(a) : typeof a.start == 'string' ? new e.SerializedRange(a) : a.start && typeof a.start == 'object' ? new e.NormalizedRange(a) : (console.error(E('Could not sniff range type')), !1)
},
e.nodeFromXPath = function (b, c) {
var d,
e,
g,
h,
i;
return c == null && (c = document),
e = function (a, b) {
var d;
b == null && (b = null);
try {
return document.evaluate('.' + a, c, b, XPathResult.FIRST_ORDERED_NODE_TYPE, null) .singleNodeValue
} catch (e) {
return d = e,
console.log('XPath evaluation failed.'),
console.log('Trying fallback...'),
f.nodeFromXPath(a, c)
}
},
a.isXMLDoc(document.documentElement) ? (d = document.createNSResolver(document.ownerDocument === null ? document.documentElement : document.ownerDocument.documentElement), h = e(b, d), h || (b = function () {
var a,
c,
d,
e;
d = b.split('/'),
e = [
];
for (a = 0, c = d.length; a < c; a++) i = d[a],
i && i.indexOf(':') === - 1 ? e.push(i.replace(/^([a-z]+)/, 'xhtml:$1')) : e.push(i);
return e
}() .join('/'), g = document.lookupNamespaceURI(null), d = function (a) {
return a === 'xhtml' ? g : document.documentElement.getAttribute('xmlns:' + a)
}, h = e(b, d)), h) : e(b)
},
e.RangeError = function (a) {
function b(a, c, d) {
this.type = a,
this.message = c,
this.parent = d != null ? d : null,
b.__super__.constructor.call(this, this.message)
}
return H(b, a),
b
}(Error),
e.BrowserRange = function () {
function a(a) {
this.commonAncestorContainer = a.commonAncestorContainer,
this.startContainer = a.startContainer,
this.startOffset = a.startOffset,
this.endContainer = a.endContainer,
this.endOffset = a.endOffset
}
return a.prototype.normalize = function (a) {
var b,
c,
d,
f,
g,
h,
i,
j,
k;
if (this.tainted) return console.error(E('You may only call normalize() once on a BrowserRange!')),
!1;
this.tainted = !0,
h = {
},
d = {
},
k = [
'start',
'end'
];
for (i = 0, j = k.length; i < j; i++) {
g = k[i],
c = this[g + 'Container'],
f = this[g + 'Offset'];
if (c.nodeType === Node.ELEMENT_NODE) {
b = c.childNodes[f],
c = b || c.childNodes[f - 1],
c.nodeType === Node.ELEMENT_NODE && !c.firstChild && (b = null, c = c.previousSibling);
while (c.nodeType !== Node.TEXT_NODE) c = c.firstChild;
f = b ? 0 : c.nodeValue.length
}
h[g] = c,
h[g + 'Offset'] = f
}
d.start = h.startOffset > 0 ? h.start.splitText(h.startOffset) : h.start,
h.start === h.end ? (h.endOffset - h.startOffset < d.start.nodeValue.length && d.start.splitText(h.endOffset - h.startOffset), d.end = d.start) : (h.endOffset < h.end.nodeValue.length && h.end.splitText(h.endOffset), d.end = h.end),
d.commonAncestor = this.commonAncestorContainer;
while (d.commonAncestor.nodeType !== Node.ELEMENT_NODE) d.commonAncestor = d.commonAncestor.parentNode;
return new e.NormalizedRange(d)
},
a.prototype.serialize = function (a, b) {
return this.normalize(a) .serialize(a, b)
},
a
}(),
e.NormalizedRange = function () {
function b(a) {
this.commonAncestor = a.commonAncestor,
this.start = a.start,
this.end = a.end
}
return b.prototype.normalize = function (a) {
return this
},
b.prototype.limit = function (b) {
var c,
d,
e,
f,
g,
h;
c = a.grep(this.textNodes(), function (c) {
return c.parentNode === b || a.contains(b, c.parentNode)
});
if (!c.length) return null;
this.start = c[0],
this.end = c[c.length - 1],
e = a(this.start) .parents(),
h = a(this.end) .parents();
for (f = 0, g = h.length; f < g; f++) {
d = h[f];
if (e.index(d) !== - 1) {
this.commonAncestor = d;
break
}
}
return this
},
b.prototype.serialize = function (b, c) {
var d,
g,
h;
return g = function (d, e) {
var g,
h,
i,
j,
k,
l,
m,
n;
c ? j = a(d) .parents(':not(' + c + ')') .eq(0) : j = a(d) .parent(),
l = f.xpathFromNode(j, b) [0],
k = f.getTextNodes(j),
h = k.slice(0, k.index(d)),
i = 0;
for (m = 0, n = h.length; m < n; m++) g = h[m],
i += g.nodeValue.length;
return e ? [
l,
i + d.nodeValue.length
] : [
l,
i
]
},
h = g(this.start),
d = g(this.end, !0),
new e.SerializedRange({
start: h[0],
end: d[0],
startOffset: h[1],
endOffset: d[1]
})
},
b.prototype.text = function () {
var a;
return function () {
var b,
c,
d,
e;
d = this.textNodes(),
e = [
];
for (b = 0, c = d.length; b < c; b++) a = d[b],
e.push(a.nodeValue);
return e
}.call(this) .join('')
},
b.prototype.textNodes = function () {
var b,
c,
d,
e;
return d = f.getTextNodes(a(this.commonAncestor)),
e = [
d.index(this.start),
d.index(this.end)
],
c = e[0],
b = e[1],
a.makeArray(d.slice(c, + b + 1 || 9000000000))
},
b.prototype.toRange = function () {
var a;
return a = document.createRange(),
a.setStartBefore(this.start),
a.setEndAfter(this.end),
a
},
b
}(),
e.SerializedRange = function () {
function b(a) {
this.start = a.start,
this.startOffset = a.startOffset,
this.end = a.end,
this.endOffset = a.endOffset
}
return b.prototype.normalize = function (b) {
var c,
d,
g,
h,
i,
j,
k,
l,
m,
n,
o,
p,
q;
j = {
},
p = [
'start',
'end'
];
for (l = 0, n = p.length; l < n; l++) {
i = p[l];
try {
h = e.nodeFromXPath(this[i], b)
} catch (r) {
throw d = r,
new e.RangeError(i, 'Error while finding ' + i + ' node: ' + this[i] + ': ' + d, d)
}
if (!h) throw new e.RangeError(i, 'Couldn\'t find ' + i + ' node: ' + this[i]);
g = 0,
q = f.getTextNodes(a(h));
for (m = 0, o = q.length; m < o; m++) {
k = q[m];
if (g + k.nodeValue.length >= this[i + 'Offset']) {
j[i + 'Container'] = k,
j[i + 'Offset'] = this[i + 'Offset'] - g;
break
}
g += k.nodeValue.length
}
if (j[i + 'Offset'] == null) throw new e.RangeError('' + i + 'offset', 'Couldn\'t find offset ' + this[i + 'Offset'] + ' in element ' + this[i])
}
return c = document.compareDocumentPosition == null ? function (a, b) {
return a.contains(b)
}
: function (a, b) {
return a.compareDocumentPosition(b) & 16
},
a(j.startContainer) .parents() .each(function () {
if (c(this, j.endContainer)) return j.commonAncestorContainer = this,
!1
}),
(new e.BrowserRange(j)) .normalize(b)
},
b.prototype.serialize = function (a, b) {
return this.normalize(a) .serialize(a, b)
},
b.prototype.toObject = function () {
return {
start: this.start,
startOffset: this.startOffset,
end: this.end,
endOffset: this.endOffset
}
},
b
}(),
t = this.Annotator,
b = function (b) {
function c(b, d) {
this.onDeleteAnnotation = I(this.onDeleteAnnotation, this),
this.onEditAnnotation = I(this.onEditAnnotation, this),
this.onAdderClick = I(this.onAdderClick, this),
this.onAdderMousedown = I(this.onAdderMousedown, this),
this.onHighlightMouseover = I(this.onHighlightMouseover, this),
this.checkForEndSelection = I(this.checkForEndSelection, this),
this.checkForStartSelection = I(this.checkForStartSelection, this),
this.clearViewerHideTimer = I(this.clearViewerHideTimer, this),
this.startViewerHideTimer = I(this.startViewerHideTimer, this),
this.showViewer = I(this.showViewer, this),
this.onEditorSubmit = I(this.onEditorSubmit, this),
this.onEditorHide = I(this.onEditorHide, this),
this.showEditor = I(this.showEditor, this),
c.__super__.constructor.apply(this, arguments),
this.plugins = {
};
if (!c.supported()) return this;
this.options.readOnly || this._setupDocumentEvents(),
this._setupWrapper() ._setupViewer() ._setupEditor(),
this._setupDynamicStyle(),
this.adder = a(this.html.adder) .appendTo(this.wrapper) .hide()
}
return H(c, b),
c.prototype.events = {
'.annotator-adder button click': 'onAdderClick',
'.annotator-adder button mousedown': 'onAdderMousedown',
'.annotator-hl mouseover': 'onHighlightMouseover',
'.annotator-hl mouseout': 'startViewerHideTimer'
},
c.prototype.html = {
adder: '<div class="annotator-adder"><button>' + E('Annotate') + '</button></div>',
wrapper: '<div class="annotator-wrapper"></div>'
},
c.prototype.options = {
readOnly: !1
},
c.prototype.plugins = {
},
c.prototype.editor = null,
c.prototype.viewer = null,
c.prototype.selectedRanges = null,
c.prototype.mouseIsDown = !1,
c.prototype.ignoreMouseup = !1,
c.prototype.viewerHideTimer = null,
c.prototype._setupWrapper = function () {
return this.wrapper = a(this.html.wrapper),
this.element.find('script') .remove(),
this.element.wrapInner(this.wrapper),
this.wrapper = this.element.find('.annotator-wrapper'),
this
},
c.prototype._setupViewer = function () {
var b = this;
return this.viewer = new c.Viewer({
readOnly: this.options.readOnly
}),
this.viewer.hide() .on('edit', this.onEditAnnotation) .on('delete', this.onDeleteAnnotation) .addField({
load: function (c, d) {
return d.text ? a(c) .html(f.escape(d.text)) : a(c) .html('<i>' + E('No Comment') + '</i>'),
b.publish('annotationViewerTextField', [
c,
d
])
}
}) .element.appendTo(this.wrapper) .bind({
mouseover: this.clearViewerHideTimer,
mouseout: this.startViewerHideTimer
}),
this
},
c.prototype._setupEditor = function () {
return this.editor = new c.Editor,
this.editor.hide() .on('hide', this.onEditorHide) .on('save', this.onEditorSubmit) .addField({
type: 'textarea',
label: E('Comments') + '鈥�',
load: function (b, c) {
return a(b) .find('textarea') .val(c.text || '')
},
submit: function (b, c) {
return c.text = a(b) .find('textarea') .val()
}
}),
this.editor.element.appendTo(this.wrapper),
this
},
c.prototype._setupDocumentEvents = function () {
return a(document) .bind({
mouseup: this.checkForEndSelection,
mousedown: this.checkForStartSelection
}),
this
},
c.prototype._setupDynamicStyle = function () {
var b,
c,
d,
e;
return d = a('#annotator-dynamic-style'),
d.length || (d = a('<style id="annotator-dynamic-style"></style>') .appendTo(document.head)),
c = '*' + function () {
var a,
b,
c,
d;
c = [
'adder',
'outer',
'notice',
'filter'
],
d = [
];
for (a = 0, b = c.length; a < b; a++) e = c[a],
d.push(':not(.annotator-' + e + ')');
return d
}() .join(''),
b = f.maxZIndex(a(document.body) .find(c)),
b = Math.max(b, 1000),
d.text(['.annotator-adder, .annotator-outer, .annotator-notice {',
' z-index: ' + (b + 20) + ';',
'}',
'.annotator-filter {',
' z-index: ' + (b + 10) + ';',
'}'].join('\n')),
this
},
c.prototype.getSelectedRanges = function () {
var b,
c,
d,
g,
h,
i,
j,
k,
l;
j = f.getGlobal() .getSelection(),
h = [
],
i = [
],
j.isCollapsed || (h = function () {
var a,
f,
h;
h = [
];
for (c = a = 0, f = j.rangeCount; 0 <= f ? a < f : a > f; c = 0 <= f ? ++a : --a) g = j.getRangeAt(c),
b = new e.BrowserRange(g),
d = b.normalize() .limit(this.wrapper[0]),
d === null && i.push(g),
h.push(d);
return h
}.call(this), j.removeAllRanges());
for (k = 0, l = i.length; k < l; k++) g = i[k],
j.addRange(g);
return a.grep(h, function (a) {
return a && j.addRange(a.toRange()),
a
})
},
c.prototype.createAnnotation = function () {
var a;
return a = {
},
this.publish('beforeAnnotationCreated', [
a
]),
a
},
c.prototype.setupAnnotation = function (b) {
var c,
d,
f,
g,
h,
i,
j,
k,
l,
m;
h = this.wrapper[0],
b.ranges || (b.ranges = this.selectedRanges),
f = [
],
m = b.ranges;
for (i = 0, k = m.length; i < k; i++) {
g = m[i];
try {
f.push(e.sniff(g) .normalize(h))
} catch (n) {
c = n;
if (!(c instanceof e.RangeError)) throw c;
this.publish('rangeNormalizeFail', [
b,
g,
c
])
}
}
b.quote = [
],
b.ranges = [
],
b.highlights = [
];
for (j = 0, l = f.length; j < l; j++) d = f[j],
b.quote.push(a.trim(d.text())),
b.ranges.push(d.serialize(this.wrapper[0], '.annotator-hl')),
a.merge(b.highlights, this.highlightRange(d));
return b.quote = b.quote.join(' / '),
a(b.highlights) .data('annotation', b),
b
},
c.prototype.updateAnnotation = function (a) {
return this.publish('beforeAnnotationUpdated', [
a
]),
this.publish('annotationUpdated', [
a
]),
a
},
c.prototype.deleteAnnotation = function (b) {
var c,
d,
e,
f,
g;
if (b.highlights != null) {
g = b.highlights;
for (e = 0, f = g.length; e < f; e++) {
d = g[e];
if (d.parentNode == null) continue;
c = d.childNodes[0],
a(d) .replaceWith(d.childNodes)
}
}
return this.publish('annotationDeleted', [
b
]),
b
},
c.prototype.loadAnnotations = function (a) {
var b,
c,
d = this;
return a == null && (a = [
]),
c = function (a) {
var e,
f,
g,
h;
a == null && (a = [
]),
f = a.splice(0, 10);
for (g = 0, h = f.length; g < h; g++) e = f[g],
d.setupAnnotation(e);
return a.length > 0 ? setTimeout(function () {
return c(a)
}, 10) : d.publish('annotationsLoaded', [
b
])
},
b = a.slice(),
a.length && c(a),
this
},
c.prototype.dumpAnnotations = function () {
return this.plugins.Store ? this.plugins.Store.dumpAnnotations() : (console.warn(E('Can\'t dump annotations without Store plugin.')), !1)
},
c.prototype.highlightRange = function (b, c) {
var d,
e,
f,
g,
h,
i,
j;
c == null && (c = 'annotator-hl'),
f = /^\s*$/,
d = a('<span class=\'' + c + '\'></span>'),
i = b.textNodes(),
j = [
];
for (g = 0, h = i.length; g < h; g++) e = i[g],
f.test(e.nodeValue) || j.push(a(e) .wrapAll(d) .parent() .show() [0]);
return j
},
c.prototype.highlightRanges = function (b, c) {
var d,
e,
f,
g;
c == null && (c = 'annotator-hl'),
d = [
];
for (f = 0, g = b.length; f < g; f++) e = b[f],
a.merge(d, this.highlightRange(e, c));
return d
},
c.prototype.addPlugin = function (a, b) {
var d,
e;
return this.plugins[a] ? console.error(E('You cannot have more than one instance of any plugin.')) : (d = c.Plugin[a], typeof d == 'function' ? (this.plugins[a] = new d(this.element[0], b), this.plugins[a].annotator = this, typeof (e = this.plugins[a]) .pluginInit == 'function' && e.pluginInit()) : console.error(E('Could not load ') + a + E(' plugin. Have you included the appropriate <script> tag?'))),
this
},
c.prototype.showEditor = function (a, b) {
return this.editor.element.css(b),
this.editor.load(a),
this.publish('annotationEditorShown', [
this.editor,
a
]),
this
},
c.prototype.onEditorHide = function () {
return this.publish('annotationEditorHidden', [
this.editor
]),
this.ignoreMouseup = !1
},
c.prototype.onEditorSubmit = function (a) {
return this.publish('annotationEditorSubmit', [
this.editor,
a
])
},
c.prototype.showViewer = function (a, b) {
return this.viewer.element.css(b),
this.viewer.load(a),
this.publish('annotationViewerShown', [
this.viewer,
a
])
},
c.prototype.startViewerHideTimer = function () {
if (!this.viewerHideTimer) return this.viewerHideTimer = setTimeout(this.viewer.hide, 250)
},
c.prototype.clearViewerHideTimer = function () {
return clearTimeout(this.viewerHideTimer),
this.viewerHideTimer = !1
},
c.prototype.checkForStartSelection = function (a) {
return (!a || !this.isAnnotator(a.target)) && this.startViewerHideTimer(),
this.mouseIsDown = !0
},
c.prototype.checkForEndSelection = function (b) {
var c,
d,
e,
g,
h;
this.mouseIsDown = !1;
if (this.ignoreMouseup) return ;
this.selectedRanges = this.getSelectedRanges(),
h = this.selectedRanges;
for (e = 0, g = h.length; e < g; e++) {
d = h[e],
c = d.commonAncestor,
a(c) .hasClass('annotator-hl') && (c = a(c) .parents('[class!=annotator-hl]') [0]);
if (this.isAnnotator(c)) return
}
return b && this.selectedRanges.length ? this.adder.css(f.mousePosition(b, this.wrapper[0])) .show() : this.adder.hide()
},
c.prototype.isAnnotator = function (b) {
return !!a(b) .parents() .andSelf() .filter('[class^=annotator-]') .not(this.wrapper) .length
},
c.prototype.onHighlightMouseover = function (b) {
var c;
return this.clearViewerHideTimer(),
this.mouseIsDown || this.viewer.isShown() ? !1 : (c = a(b.target) .parents('.annotator-hl') .andSelf() .map(function () {
return a(this) .data('annotation')
}), this.showViewer(a.makeArray(c), f.mousePosition(b, this.wrapper[0])))
},
c.prototype.onAdderMousedown = function (a) {
return a != null && a.preventDefault(),
this.ignoreMouseup = !0
},
c.prototype.onAdderClick = function (b) {
var c,
d,
e,
f,
g,
h = this;
return b != null && b.preventDefault(),
f = this.adder.position(),
this.adder.hide(),
c = this.setupAnnotation(this.createAnnotation()),
a(c.highlights) .addClass('annotator-hl-temporary'),
g = function () {
return e(),
a(c.highlights) .removeClass('annotator-hl-temporary'),
h.publish('annotationCreated', [
c
])
},
d = function () {
return e(),
h.deleteAnnotation(c)
},
e = function () {
return h.unsubscribe('annotationEditorHidden', d),
h.unsubscribe('annotationEditorSubmit', g)
},
this.subscribe('annotationEditorHidden', d),
this.subscribe('annotationEditorSubmit', g),
this.showEditor(c, f)
},
c.prototype.onEditAnnotation = function (a) {
var b,
c,
d,
e = this;
return c = this.viewer.element.position(),
d = function () {
return b(),
e.updateAnnotation(a)
},
b = function () {
return e.unsubscribe('annotationEditorHidden', b),
e.unsubscribe('annotationEditorSubmit', d)
},
this.subscribe('annotationEditorHidden', b),
this.subscribe('annotationEditorSubmit', d),
this.viewer.hide(),
this.showEditor(a, c)
},
c.prototype.onDeleteAnnotation = function (a) {
return this.viewer.hide(),
this.deleteAnnotation(a)
},
c
}(c),
b.Plugin = function (a) {
function b(a, c) {
b.__super__.constructor.apply(this, arguments)
}
return H(b, a),
b.prototype.pluginInit = function () {
},
b
}(c),
m = f.getGlobal(),
((A = m.document) != null ? A.evaluate : void 0) == null && a.getScript('http://assets.annotateit.org/vendor/xpath.min.js'),
m.getSelection == null && a.getScript('http://assets.annotateit.org/vendor/ierange.min.js'),
m.JSON == null && a.getScript('http://assets.annotateit.org/vendor/json2.min.js'),
m.Node == null && (m.Node = {
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
TEXT_NODE: 3,
CDATA_SECTION_NODE: 4,
ENTITY_REFERENCE_NODE: 5,
ENTITY_NODE: 6,
PROCESSING_INSTRUCTION_NODE: 7,
COMMENT_NODE: 8,
DOCUMENT_NODE: 9,
DOCUMENT_TYPE_NODE: 10,
DOCUMENT_FRAGMENT_NODE: 11,
NOTATION_NODE: 12
}),
b.$ = a,
b.Delegator = c,
b.Range = e,
b.Util = f,
b._t = E,
b.supported = function () {
return function () {
return !!this.getSelection
}()
},
b.noConflict = function () {
return f.getGlobal() .Annotator = t,
this
},
a.fn.annotator = function (c) {
var d;
return d = Array.prototype.slice.call(arguments, 1),
this.each(function () {
var e;
return e = a.data(this, 'annotator'),
e ? c && e[c].apply(e, d) : (e = new b(this, c), a.data(this, 'annotator', e))
})
},
this.Annotator = b,
b.Widget = function (c) {
function d(c, e) {
d.__super__.constructor.apply(this, arguments),
this.classes = a.extend({
}, b.Widget.prototype.classes, this.classes)
}
return H(d, c),
d.prototype.classes = {
hide: 'annotator-hide',
invert: {
x: 'annotator-invert-x',
y: 'annotator-invert-y'
}
},
d.prototype.checkOrientation = function () {
var c,
d,
e,
f,
g;
return this.resetOrientation(),
g = a(b.Util.getGlobal()),
f = this.element.children(':first'),
d = f.offset(),
e = {
top: g.scrollTop(),
right: g.width() + g.scrollLeft()
},
c = {
top: d.top,
right: d.left + f.width()
},
c.top - e.top < 0 && this.invertY(),
c.right - e.right > 0 && this.invertX(),
this
},
d.prototype.resetOrientation = function () {
return this.element.removeClass(this.classes.invert.x) .removeClass(this.classes.invert.y),
this
},
d.prototype.invertX = function () {
return this.element.addClass(this.classes.invert.x),
this
},
d.prototype.invertY = function () {
return this.element.addClass(this.classes.invert.y),
this
},
d.prototype.isInvertedY = function () {
return this.element.hasClass(this.classes.invert.y)
},
d.prototype.isInvertedX = function () {
return this.element.hasClass(this.classes.invert.x)
},
d
}(c),
b.Editor = function (c) {
function d(b) {
this.onCancelButtonMouseover = I(this.onCancelButtonMouseover, this),
this.processKeypress = I(this.processKeypress, this),
this.submit = I(this.submit, this),
this.load = I(this.load, this),
this.hide = I(this.hide, this),
this.show = I(this.show, this),
d.__super__.constructor.call(this, a(this.html) [0], b),
this.fields = [
],
this.annotation = {
}
}
return H(d, c),
d.prototype.events = {
'form submit': 'submit',
'.annotator-save click': 'submit',
'.annotator-cancel click': 'hide',
'.annotator-cancel mouseover': 'onCancelButtonMouseover',
'textarea keydown': 'processKeypress'
},
d.prototype.classes = {
hide: 'annotator-hide',
focus: 'annotator-focus'
},
d.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">' + E('Cancel') + '</a>\n<a href="#save" class="annotator-save annotator-focus">' + E('Save') + '</a>\n </div>\n </form>\n</div>',
d.prototype.options = {
},
d.prototype.show = function (a) {
return b.Util.preventEventDefault(a),
this.element.removeClass(this.classes.hide),
this.element.find('.annotator-save') .addClass(this.classes.focus),
this.checkOrientation(),
this.element.find(':input:first') .focus(),
this.setupDraggables(),
this.publish('show')
},
d.prototype.hide = function (a) {
return b.Util.preventEventDefault(a),
this.element.addClass(this.classes.hide),
this.publish('hide')
},
d.prototype.load = function (a) {
var b,
c,
d,
e;
this.annotation = a,
this.publish('load', [
this.annotation
]),
e = this.fields;
for (c = 0, d = e.length; c < d; c++) b = e[c],
b.load(b.element, this.annotation);
return this.show()
},
d.prototype.submit = function (a) {
var c,
d,
e,
f;
b.Util.preventEventDefault(a),
f = this.fields;
for (d = 0, e = f.length; d < e; d++) c = f[d],
c.submit(c.element, this.annotation);
return this.publish('save', [
this.annotation
]),
this.hide()
},
d.prototype.addField = function (c) {
var d,
e,
f;
e = a.extend({
id: 'annotator-field-' + b.Util.uuid(),
type: 'input',
label: '',
load: function () {
},
submit: function () {
}
}, c),
f = null,
d = a('<li class="annotator-item" />'),
e.element = d[0];
switch (e.type) {
case 'textarea':
f = a('<textarea />');
break;
case 'input':
case 'checkbox':
f = a('<input />');
break;
case 'select':
f = a('<select />')
}
return d.append(f),
f.attr({
id: e.id,
placeholder: e.label
}),
e.type === 'checkbox' && (f[0].type = 'checkbox', d.addClass('annotator-checkbox'), d.append(a('<label />', {
'for': e.id,
html: e.label
}))),
this.element.find('ul:first') .append(d),
this.fields.push(e),
e.element
},
d.prototype.checkOrientation = function () {
var a,
b;
return d.__super__.checkOrientation.apply(this, arguments),
b = this.element.find('ul'),
a = this.element.find('.annotator-controls'),
this.element.hasClass(this.classes.invert.y) ? a.insertBefore(b) : a.is(':first-child') && a.insertAfter(b),
this
},
d.prototype.processKeypress = function (a) {
if (a.keyCode === 27) return this.hide();
if (a.keyCode === 13 && !a.shiftKey) return this.submit()
},
d.prototype.onCancelButtonMouseover = function () {
return this.element.find('.' + this.classes.focus) .removeClass(this.classes.focus)
},
d.prototype.setupDraggables = function () {
var b,
c,
d,
e,
f,
g,
h,
i,
j,
k,
l,
m = this;
return this.element.find('.annotator-resize') .remove(),
this.element.hasClass(this.classes.invert.y) ? d = this.element.find('.annotator-item:last') : d = this.element.find('.annotator-item:first'),
d && a('<span class="annotator-resize"></span>') .appendTo(d),
f = null,
b = this.classes,
e = this.element,
k = null,
j = e.find('.annotator-resize'),
c = e.find('.annotator-controls'),
l = !1,
g = function (b) {
if (b.target === this) return f = {
element: this,
top: b.pageY,
left: b.pageX
},
k = e.find('textarea:first'),
a(window) .bind({
'mouseup.annotator-editor-resize': i,
'mousemove.annotator-editor-resize': h
}),
b.preventDefault()
},
i = function () {
return f = null,
a(window) .unbind('.annotator-editor-resize')
},
h = function (a) {
var d,
g,
h,
i,
m;
if (f && l === !1) return d = {
top: a.pageY - f.top,
left: a.pageX - f.left
},
f.element === j[0] ? (i = k.outerHeight(), m = k.outerWidth(), g = e.hasClass(b.invert.x) ? - 1 : 1, h = e.hasClass(b.invert.y) ? 1 : - 1, k.height(i + d.top * h), k.width(m + d.left * g), k.outerHeight() !== i && (f.top = a.pageY), k.outerWidth() !== m && (f.left = a.pageX)) : f.element === c[0] && (e.css({
top: parseInt(e.css('top'), 10) + d.top,
left: parseInt(e.css('left'), 10) + d.left
}), f.top = a.pageY, f.left = a.pageX),
l = !0,
setTimeout(function () {
return l = !1
}, 1000 / 60)
},
j.bind('mousedown', g),
c.bind('mousedown', g)
},
d
}(b.Widget),
b.Viewer = function (c) {
function e(b) {
this.onDeleteClick = I(this.onDeleteClick, this),
this.onEditClick = I(this.onEditClick, this),
this.load = I(this.load, this),
this.hide = I(this.hide, this),
this.show = I(this.show, this),
e.__super__.constructor.call(this, a(this.html.element) [0], b),
this.item = a(this.html.item) [0],
this.fields = [
],
this.annotations = [
]
}
return H(e, c),
e.prototype.events = {
'.annotator-edit click': 'onEditClick',
'.annotator-delete click': 'onDeleteClick'
},
e.prototype.classes = {
hide: 'annotator-hide',
showControls: 'annotator-visible'
},
e.prototype.html = {
element: '<div class="annotator-outer annotator-viewer">\n <ul class="annotator-widget annotator-listing"></ul>\n</div>',
item: '<li class="annotator-annotation annotator-item">\n <span class="annotator-controls">\n <a href="#" title="View as webpage" class="annotator-link">View as webpage</a>\n <button title="Edit" class="annotator-edit">Edit</button>\n <button title="Delete" class="annotator-delete">Delete</button>\n </span>\n</li>'
},
e.prototype.options = {
readOnly: !1
},
e.prototype.show = function (a) {
var c,
d = this;
return b.Util.preventEventDefault(a),
c = this.element.find('.annotator-controls') .addClass(this.classes.showControls),
setTimeout(function () {
return c.removeClass(d.classes.showControls)
}, 500),
this.element.removeClass(this.classes.hide),
this.checkOrientation() .publish('show')
},
e.prototype.isShown = function () {
return !this.element.hasClass(this.classes.hide)
},
e.prototype.hide = function (a) {
return b.Util.preventEventDefault(a),
this.element.addClass(this.classes.hide),
this.publish('hide')
},
e.prototype.load = function (b) {
var c,
e,
f,
g,
h,
i,
j,
k,
l,
m,
n,
o,
p,
q,
r,
s,
t;
this.annotations = b || [],
n = this.element.find('ul:first') .empty(),
s = this.annotations;
for (o = 0, q = s.length; o < q; o++) {
c = s[o],
k = a(this.item) .clone() .appendTo(n) .data('annotation', c),
f = k.find('.annotator-controls'),
l = f.find('.annotator-link'),
h = f.find('.annotator-edit'),
g = f.find('.annotator-delete'),
m = (new d(c.links || [])) .get('alternate', {
type: 'text/html'
}),
m.length === 0 || m[0].href == null ? l.remove() : l.attr('href', m[0].href),
this.options.readOnly ? (h.remove(), g.remove()) : e = {
showEdit: function () {
return h.removeAttr('disabled')
},
hideEdit: function () {
return h.attr('disabled', 'disabled')
},
showDelete: function () {
return g.removeAttr('disabled')
},
hideDelete: function () {
return g.attr('disabled', 'disabled')
}
},
t = this.fields;
for (p = 0, r = t.length; p < r; p++) j = t[p],
i = a(j.element) .clone() .appendTo(k) [0],
j.load(i, c, e)
}
return this.publish('load', [
this.annotations
]),
this.show()
},
e.prototype.addField = function (b) {
var c;
return c = a.extend({
load: function () {
}
}, b),
c.element = a('<div />') [0],
this.fields.push(c),
c.element,
this
},
e.prototype.onEditClick = function (a) {
return this.onButtonClick(a, 'edit')
},
e.prototype.onDeleteClick = function (a) {
return this.onButtonClick(a, 'delete')
},
e.prototype.onButtonClick = function (b, c) {
var d;
return d = a(b.target) .parents('.annotator-annotation'),
this.publish(c, [
d.data('annotation')
])
},
e
}(b.Widget),
d = function () {
function b(a) {
this.data = a
}
return b.prototype.get = function (b, c) {
var d,
e,
f,
g,
h,
i,
j,
k,
l;
c == null && (c = {
}),
c = a.extend({
}, c, {
rel: b
}),
f = function () {
var a;
a = [
];
for (e in c) {
if (!G.call(c, e)) continue;
h = c[e],
a.push(e)
}
return a
}(),
k = this.data,
l = [
];
for (i = 0, j = k.length; i < j; i++) {
d = k[i],
g = f.reduce(function (a, b) {
return a && d[b] === c[b]
}, !0);
if (!g) continue;
l.push(d)
}
return l
},
b
}(),
b = b || {
},
b.Notification = function (c) {
function d(b) {
this.hide = I(this.hide, this),
this.show = I(this.show, this),
d.__super__.constructor.call(this, a(this.options.html) .appendTo(document.body) [0], b)
}
return H(d, c),
d.prototype.events = {
click: 'hide'
},
d.prototype.options = {
html: '<div class=\'annotator-notice\'></div>',
classes: {
show: 'annotator-notice-show',
info: 'annotator-notice-info',
success: 'annotator-notice-success',
error: 'annotator-notice-error'
}
},
d.prototype.show = function (c, d) {
return d == null && (d = b.Notification.INFO),
a(this.element) .addClass(this.options.classes.show) .addClass(this.options.classes[d]) .html(f.escape(c || '')),
setTimeout(this.hide, 5000),
this
},
d.prototype.hide = function () {
return a(this.element) .removeClass(this.options.classes.show),
this
},
d
}(c),
b.Notification.INFO = 'show',
b.Notification.SUCCESS = 'success',
b.Notification.ERROR = 'error',
a(function () {
var a;
return a = new b.Notification,
b.showNotification = a.show,
b.hideNotification = a.hide
}),
b.Plugin.Unsupported = function (c) {
function d() {
return B = d.__super__.constructor.apply(this, arguments),
B
}
return H(d, c),
d.prototype.options = {
message: b._t('Sorry your current browser does not support the Annotator')
},
d.prototype.pluginInit = function () {
var c = this;
if (!b.supported()) return a(function () {
b.showNotification(c.options.message);
if (window.XMLHttpRequest === void 0 && ActiveXObject !== void 0) return a('html') .addClass('ie6')
})
},
d
}(b.Plugin),
i = function (a) {
var b,
c,
d,
e,
f,
g;
return e = '([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})))?)?)?)?',
b = a.match(new RegExp(e)),
d = 0,
c = new Date(b[1], 0, 1),
b[3] && c.setMonth(b[3] - 1),
b[5] && c.setDate(b[5]),
b[7] && c.setHours(b[7]),
b[8] && c.setMinutes(b[8]),
b[10] && c.setSeconds(b[10]),
b[12] && c.setMilliseconds(Number('0.' + b[12]) * 1000),
b[14] && (d = Number(b[16]) * 60 + Number(b[17]), d *= (g = b[15] === '-') != null ? g : {
1: - 1
}),
d -= c.getTimezoneOffset(),
f = Number(c) + d * 60 * 1000,
c.setTime(Number(f)),
c
},
g = function (a) {
var b,
c,
d,
e,
f,
g,
h,
i,
j,
k,
l,
m,
n;
if (typeof atob != 'undefined' && atob !== null) return atob(a);
c = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
j = 0,
b = 0,
e = '',
n = [
];
if (!a) return a;
a += '';
while (j < a.length) f = c.indexOf(a.charAt(j++)),
g = c.indexOf(a.charAt(j++)),
h = c.indexOf(a.charAt(j++)),
i = c.indexOf(a.charAt(j++)),
d = f << 18 | g << 12 | h << 6 | i,
k = d >> 16 & 255,
l = d >> 8 & 255,
m = d & 255,
h === 64 ? n[b++] = String.fromCharCode(k) : i === 64 ? n[b++] = String.fromCharCode(k, l) : n[b++] = String.fromCharCode(k, l, m);
return n.join('')
},
h = function (a) {
var b,
c,
d,
e;
c = a.length % 4;
if (c !== 0) for (b = d = 0, e = 4 - c; 0 <= e ? d < e : d > e; b = 0 <= e ? ++d : --d) a += '=';
return a = a.replace(/-/g, '+'),
a = a.replace(/_/g, '/'),
g(a)
},
q = function (a) {
var b,
c,
d,
e;
return e = a.split('.'),
b = e[0],
c = e[1],
d = e[2],
JSON.parse(h(c))
},
b.Plugin.Auth = function (c) {
function d(a, b) {
d.__super__.constructor.apply(this, arguments),
this.waitingForToken = [
],
this.options.token ? this.setToken(this.options.token) : this.requestToken()
}
return H(d, c),
d.prototype.options = {
token: null,
tokenUrl: '/auth/token',
autoFetch: !0
},
d.prototype.requestToken = function () {
var c = this;
return this.requestInProgress = !0,
a.ajax({
url: this.options.tokenUrl,
dataType: 'text',
xhrFields: {
withCredentials: !0
}
}) .done(function (a, b, d) {
return c.setToken(a)
}) .fail(function (a, c, d) {
var e;
return e = b._t('Couldn\'t get auth token:'),
console.error('' + e + ' ' + d, a),
b.showNotification('' + e + ' ' + a.responseText, b.Notification.ERROR)
}) .always(function () {
return c.requestInProgress = !1
})
},
d.prototype.setToken = function (a) {
var c,
d = this;
this.token = a,
this._unsafeToken = q(a);
if (this.haveValidToken()) {
this.options.autoFetch && (this.refreshTimeout = setTimeout(function () {
return d.requestToken()
}, (this.timeToExpiry() - 2) * 1000)),
this.updateHeaders(),
c = [
];
while (this.waitingForToken.length > 0) c.push(this.waitingForToken.pop() (this._unsafeToken));
return c
}
console.warn(b._t('Didn\'t get a valid token.'));
if (this.options.autoFetch) return console.warn(b._t('Getting a new token in 10s.')),
setTimeout(function () {
return d.requestToken()
}, 10000)
},
d.prototype.haveValidToken = function () {
var a;
return a = this._unsafeToken && this._unsafeToken.issuedAt && this._unsafeToken.ttl && this._unsafeToken.consumerKey,
a && this.timeToExpiry() > 0 ? !0 : !1
},
d.prototype.timeToExpiry = function () {
var a,
b,
c,
d;
return c = (new Date) .getTime() / 1000,
b = i(this._unsafeToken.issuedAt) .getTime() / 1000,
a = b + this._unsafeToken.ttl,
d = a - c,
d > 0 ? d : 0
},
d.prototype.updateHeaders = function () {
var b;
return b = this.element.data('annotator:headers'),
this.element.data('annotator:headers', a.extend(b, {
'x-annotator-auth-token': this.token
}))
},
d.prototype.withToken = function (a) {
if (a == null) return ;
if (this.haveValidToken()) return a(this._unsafeToken);
this.waitingForToken.push(a);
if (!this.requestInProgress) return this.requestToken()
},
d
}(b.Plugin),
b.Plugin.Store = function (c) {
function d(a, b) {
this._onError = I(this._onError, this),
this._onLoadAnnotationsFromSearch = I(this._onLoadAnnotationsFromSearch, this),
this._onLoadAnnotations = I(this._onLoadAnnotations, this),
this._getAnnotations = I(this._getAnnotations, this),
d.__super__.constructor.apply(this, arguments),
this.annotations = [
]
}
return H(d, c),
d.prototype.events = {
annotationCreated: 'annotationCreated',
annotationDeleted: 'annotationDeleted',
annotationUpdated: 'annotationUpdated'
},
d.prototype.options = {
annotationData: {
},
emulateHTTP: !1,
loadFromSearch: !1,
prefix: '/store',
urls: {
create: '/annotations',
read: '/annotations/:id',
update: '/annotations/:id',
destroy: '/annotations/:id',
search: '/search'
}
},
d.prototype.pluginInit = function () {
if (!b.supported()) return ;
return this.annotator.plugins.Auth ? this.annotator.plugins.Auth.withToken(this._getAnnotations) : this._getAnnotations()
},
d.prototype._getAnnotations = function () {
return this.options.loadFromSearch ? this.loadAnnotationsFromSearch(this.options.loadFromSearch) : this.loadAnnotations()
},
d.prototype.annotationCreated = function (a) {
var c = this;
return J.call(this.annotations, a) < 0 ? (this.registerAnnotation(a), this._apiRequest('create', a, function (d) {
return d.id == null && console.warn(b._t('Warning: No ID returned from server for annotation '), a),
c.updateAnnotation(a, d)
})) : this.updateAnnotation(a, {
})
},
d.prototype.annotationUpdated = function (a) {
var b = this;
if (J.call(this.annotations, a) >= 0) return this._apiRequest('update', a, function (c) {
return b.updateAnnotation(a, c)
})
},
d.prototype.annotationDeleted = function (a) {
var b = this;
if (J.call(this.annotations, a) >= 0) return this._apiRequest('destroy', a, function () {
return b.unregisterAnnotation(a)
})
},
d.prototype.registerAnnotation = function (a) {
return this.annotations.push(a)
},
d.prototype.unregisterAnnotation = function (a) {
return this.annotations.splice(this.annotations.indexOf(a), 1)
},
d.prototype.updateAnnotation = function (c, d) {
return J.call(this.annotations, c) < 0 ? console.error(b._t('Trying to update unregistered annotation!')) : a.extend(c, d),
a(c.highlights) .data('annotation', c)
},
d.prototype.loadAnnotations = function () {
return this._apiRequest('read', null, this._onLoadAnnotations)
},
d.prototype._onLoadAnnotations = function (a) {
var b,
c,
d,
e,
f,
g,
h,
i,
j;
a == null && (a = [
]),
d = {
},
j = this.annotations;
for (f = 0, h = j.length; f < h; f++) b = j[f],
d[b.id] = b;
e = [
];
for (g = 0, i = a.length; g < i; g++) b = a[g],
d[b.id] ? (c = d[b.id], this.updateAnnotation(c, b)) : e.push(b);
return this.annotations = this.annotations.concat(e),
this.annotator.loadAnnotations(e.slice())
},
d.prototype.loadAnnotationsFromSearch = function (a) {
return this._apiRequest('search', a, this._onLoadAnnotationsFromSearch)
},
d.prototype._onLoadAnnotationsFromSearch = function (a) {
return a == null && (a = {
}),
this._onLoadAnnotations(a.rows || [])
},
d.prototype.dumpAnnotations = function () {
var a,
b,
c,
d,
e;
d = this.annotations,
e = [
];
for (b = 0, c = d.length; b < c; b++) a = d[b],
e.push(JSON.parse(this._dataFor(a)));
return e
},
d.prototype._apiRequest = function (b, c, d) {
var e,
f,
g,
h;
return e = c && c.id,
h = this._urlFor(b, e),
f = this._apiRequestOptions(b, c, d),
g = a.ajax(h, f),
g._id = e,
g._action = b,
g
},
d.prototype._apiRequestOptions = function (b, c, d) {
var e,
f,
g;
return f = this._methodFor(b),
g = {
type: f,
headers: this.element.data('annotator:headers'),
dataType: 'json',
success: d || function () {
},
error: this._onError
},
this.options.emulateHTTP && (f === 'PUT' || f === 'DELETE') && (g.headers = a.extend(g.headers, {
'X-HTTP-Method-Override': f
}), g.type = 'POST'),
b === 'search' ? (g = a.extend(g, {
data: c
}), g) : (e = c && this._dataFor(c), this.options.emulateJSON ? (g.data = {
json: e
}, this.options.emulateHTTP && (g.data._method = f), g) : (g = a.extend(g, {
data: e,
contentType: 'application/json; charset=utf-8'
}), g))
},
d.prototype._urlFor = function (a, b) {
var c;
return c = this.options.prefix != null ? this.options.prefix : '',
c += this.options.urls[a],
c = c.replace(/\/:id/, b != null ? '/' + b : ''),
c = c.replace(/:id/, b != null ? b : ''),
c
},
d.prototype._methodFor = function (a) {
var b;
return b = {
create: 'POST',
read: 'GET',
update: 'PUT',
destroy: 'DELETE',
search: 'GET'
},
b[a]
},
d.prototype._dataFor = function (b) {
var c,
d;
return d = b.highlights,
delete b.highlights,
a.extend(b, this.options.annotationData),
c = JSON.stringify(b),
d && (b.highlights = d),
c
},
d.prototype._onError = function (a) {
var c,
d;
c = a._action,
d = b._t('Sorry we could not ') + c + b._t(' this annotation'),
a._action === 'search' ? d = b._t('Sorry we could not search the store for annotations') : a._action === 'read' && !a._id && (d = b._t('Sorry we could not ') + c + b._t(' the annotations from the store'));
switch (a.status) {
case 401:
d = b._t('Sorry you are not allowed to ') + c + b._t(' this annotation');
break;
case 404:
d = b._t('Sorry we could not connect to the annotations store');
break;
case 500:
d = b._t('Sorry something went wrong with the annotation store')
}
return b.showNotification(d, b.Notification.ERROR),
console.error(b._t('API request failed:') + (' \'' + a.status + '\''))
},
d
}(b.Plugin),
b.Plugin.Permissions = function (c) {
function d(a, b) {
this._setAuthFromToken = I(this._setAuthFromToken, this),
this.updateViewer = I(this.updateViewer, this),
this.updateAnnotationPermissions = I(this.updateAnnotationPermissions, this),
this.updatePermissionsField = I(this.updatePermissionsField, this),
this.addFieldsToAnnotation = I(this.addFieldsToAnnotation, this),
d.__super__.constructor.apply(this, arguments),
this.options.user && (this.setUser(this.options.user), delete this.options.user)
}
return H(d, c),
d.prototype.events = {
beforeAnnotationCreated: 'addFieldsToAnnotation'
},
d.prototype.options = {
showViewPermissionsCheckbox: !0,
showEditPermissionsCheckbox: !0,
userId: function (a) {
return a
},
userString: function (a) {
return a
},
userAuthorize: function (a, b, c) {
var d,
e,
f,
g;
if (b.permissions) {
e = b.permissions[a] || [];
if (e.length === 0) return !0;
for (f = 0, g = e.length; f < g; f++) {
d = e[f];
if (this.userId(c) === d) return !0
}
return !1
}
return b.user ? c ? this.userId(c) === this.userId(b.user) : !1 : !0
},
user: '',
permissions: {
read: [
],
update: [
],
'delete': [
],
admin: [
]
}
},
d.prototype.pluginInit = function () {
var a,
c,
d = this;
if (!b.supported()) return ;
c = this,
a = function (a, b) {
return function (d, e) {
return c[a].call(c, b, d, e)
}
},
!this.user && this.annotator.plugins.Auth && this.annotator.plugins.Auth.withToken(this._setAuthFromToken),
this.options.showViewPermissionsCheckbox === !0 && this.annotator.editor.addField({
type: 'checkbox',
label: b._t('Allow anyone to <strong>view</strong> this annotation'),
load: a('updatePermissionsField', 'read'),
submit: a('updateAnnotationPermissions', 'read')
}),
this.options.showEditPermissionsCheckbox === !0 && this.annotator.editor.addField({
type: 'checkbox',
label: b._t('Allow anyone to <strong>edit</strong> this annotation'),
load: a('updatePermissionsField', 'update'),
submit: a('updateAnnotationPermissions', 'update')
}),
this.annotator.viewer.addField({
load: this.updateViewer
});
if (this.annotator.plugins.Filter) return this.annotator.plugins.Filter.addFilter({
label: b._t('User'),
property: 'user',
isFiltered: function (a, b) {
var c,
e,
f,
g;
b = d.options.userString(b);
if (!a || !b) return !1;
g = a.split(/\s*/);
for (e = 0, f = g.length; e < f; e++) {
c = g[e];
if (b.indexOf(c) === - 1) return !1
}
return !0
}
})
},
d.prototype.setUser = function (a) {
return this.user = a
},
d.prototype.addFieldsToAnnotation = function (a) {
if (a) {
a.permissions = this.options.permissions;
if (this.user) return a.user = this.user
}
},
d.prototype.authorize = function (a, b, c) {
return c === void 0 && (c = this.user),
this.options.userAuthorize ? this.options.userAuthorize.call(this.options, a, b, c) : !0
},
d.prototype.updatePermissionsField = function (b, c, d) {
var e;
return c = a(c) .show(),
e = c.find('input') .removeAttr('disabled'),
this.authorize('admin', d) || c.hide(),
this.authorize(b, d || {
}, null) ? e.attr('checked', 'checked') : e.removeAttr('checked')
},
d.prototype.updateAnnotationPermissions = function (b, c, d) {
var e;
return d.permissions || (d.permissions = this.options.permissions),
e = b + '-permissions',
a(c) .find('input') .is(':checked') ? d.permissions[b] = [
] : d.permissions[b] = [
this.user
]
},
d.prototype.updateViewer = function (c, d, e) {
var f,
g;
c = a(c),
g = this.options.userString(d.user),
d.user && g && typeof g == 'string' ? (f = b.Util.escape(this.options.userString(d.user)), c.html(f) .addClass('annotator-user')) : c.remove();
if (e) {
this.authorize('update', d) || e.hideEdit();
if (!this.authorize('delete', d)) return e.hideDelete()
}
},
d.prototype._setAuthFromToken = function (a) {
return this.setUser(a.userId)
},
d
}(b.Plugin),
b.Plugin.AnnotateItPermissions = function (b) {
function c() {
return this._setAuthFromToken = I(this._setAuthFromToken, this),
this.updateAnnotationPermissions = I(this.updateAnnotationPermissions, this),
this.updatePermissionsField = I(this.updatePermissionsField, this),
this.addFieldsToAnnotation = I(this.addFieldsToAnnotation, this),
C = c.__super__.constructor.apply(this, arguments),
C
}
return H(c, b),
c.prototype.options = {
showViewPermissionsCheckbox: !0,
showEditPermissionsCheckbox: !0,
groups: {
world: 'group:__world__',
authenticated: 'group:__authenticated__',
consumer: 'group:__consumer__'
},
userId: function (a) {
return a.userId
},
userString: function (a) {
return a.userId
},
userAuthorize: function (a, b, c) {
var d,
e,
f,
g,
h,
i;
return e = b.permissions || {
},
d = e[a] || [],
(f = this.groups.world, J.call(d, f) >= 0) ? !0 : c != null && c.userId != null && c.consumerKey != null ? c.userId === b.user && c.consumerKey === b.consumer ? !0 : (g = this.groups.authenticated, J.call(d, g) >= 0) ? !0 : c.consumerKey === b.consumer && (h = this.groups.consumer, J.call(d, h) >= 0) ? !0 : c.consumerKey === b.consumer && (i = c.userId, J.call(d, i) >= 0) ? !0 : c.consumerKey === b.consumer && c.admin ? !0 : !1 : !1
},
permissions: {
read: [
'group:__world__'
],
update: [
],
'delete': [
],
admin: [
]
}
},
c.prototype.addFieldsToAnnotation = function (a) {
if (a) {
a.permissions = this.options.permissions;
if (this.user) return a.user = this.user.userId,
a.consumer = this.user.consumerKey
}
},
c.prototype.updatePermissionsField = function (b, c, d) {
var e;
return c = a(c) .show(),
e = c.find('input') .removeAttr('disabled'),
this.authorize('admin', d) || c.hide(),
this.user && this.authorize(b, d || {
}, {
userId: '__nonexistentuser__',
consumerKey: this.user.consumerKey
}) ? e.attr('checked', 'checked') : e.removeAttr('checked')
},
c.prototype.updateAnnotationPermissions = function (b, c, d) {
var e;
return d.permissions || (d.permissions = this.options.permissions),
e = b + '-permissions',
a(c) .find('input') .is(':checked') ? d.permissions[b] = [
b === 'read' ? this.options.groups.world : this.options.groups.consumer
] : d.permissions[b] = [
]
},
c.prototype._setAuthFromToken = function (a) {
return this.setUser(a)
},
c
}(b.Plugin.Permissions),
b.Plugin.Filter = function (c) {
function d(b, c) {
this._onPreviousClick = I(this._onPreviousClick, this),
this._onNextClick = I(this._onNextClick, this),
this._onFilterKeyup = I(this._onFilterKeyup, this),
this._onFilterBlur = I(this._onFilterBlur, this),
this._onFilterFocus = I(this._onFilterFocus, this),
this.updateHighlights = I(this.updateHighlights, this);
var e;
b = a(this.html.element) .appendTo((c != null ? c.appendTo : void 0) || this.options.appendTo),
d.__super__.constructor.call(this, b, c),
(e = this.options) .filters || (e.filters = [
]),
this.filter = a(this.html.filter),
this.filters = [
],
this.current = 0
}
return H(d, c),
d.prototype.events = {
'.annotator-filter-property input focus': '_onFilterFocus',
'.annotator-filter-property input blur': '_onFilterBlur',
'.annotator-filter-property input keyup': '_onFilterKeyup',
'.annotator-filter-previous click': '_onPreviousClick',
'.annotator-filter-next click': '_onNextClick',
'.annotator-filter-clear click': '_onClearClick'
},
d.prototype.classes = {
active: 'annotator-filter-active',
hl: {
hide: 'annotator-hl-filtered',
active: 'annotator-hl-active'
}
},
d.prototype.html = {
element: '<div class="annotator-filter">\n <strong>' + b._t('Navigate:') + '</strong>\n<span class="annotator-filter-navigation">\n <button class="annotator-filter-previous">' + b._t('Previous') + '</button>\n<button class="annotator-filter-next">' + b._t('Next') + '</button>\n</span>\n<strong>' + b._t('Filter by:') + '</strong>\n</div>',
filter: '<span class="annotator-filter-property">\n <label></label>\n <input/>\n <button class="annotator-filter-clear">' + b._t('Clear') + '</button>\n</span>'
},
d.prototype.options = {
appendTo: 'body',
filters: [
],
addAnnotationFilter: !0,
isFiltered: function (a, b) {
var c,
d,
e,
f;
if (!a || !b) return !1;
f = a.split(/\s*/);
for (d = 0, e = f.length; d < e; d++) {
c = f[d];
if (b.indexOf(c) === - 1) return !1
}
return !0
}
},
d.prototype.pluginInit = function () {
var a,
c,
d,
e;
e = this.options.filters;
for (c = 0, d = e.length; c < d; c++) a = e[c],
this.addFilter(a);
this.updateHighlights(),
this._setupListeners() ._insertSpacer();
if (this.options.addAnnotationFilter === !0) return this.addFilter({
label: b._t('Annotation'),
property: 'text'
})
},
d.prototype._insertSpacer = function () {
var b,
c;
return c = a('html'),
b = parseInt(c.css('padding-top'), 10) || 0,
c.css('padding-top', b + this.element.outerHeight()),
this
},
d.prototype._setupListeners = function () {
var a,
b,
c,
d;
b = [
'annotationsLoaded',
'annotationCreated',
'annotationUpdated',
'annotationDeleted'
];
for (c = 0, d = b.length; c < d; c++) a = b[c],
this.annotator.subscribe(a, this.updateHighlights);
return this
},
d.prototype.addFilter = function (c) {
var d,
e;
e = a.extend({
label: '',
property: '',
isFiltered: this.options.isFiltered
}, c);
if (!function () {
var a,
b,
c,
f;
c = this.filters,
f = [
];
for (a = 0, b = c.length; a < b; a++) d = c[a],
d.property === e.property && f.push(d);
return f
}.call(this) .length) e.id = 'annotator-filter-' + e.property,
e.annotations = [
],
e.element = this.filter.clone() .appendTo(this.element),
e.element.find('label') .html(e.label) .attr('for', e.id),
e.element.find('input') .attr({
id: e.id,
placeholder: b._t('Filter by ') + e.label + '鈥�'
}),
e.element.find('button') .hide(),
e.element.data('filter', e),
this.filters.push(e);
return this
},
d.prototype.updateFilter = function (b) {
var c,
d,
e,
f,
g,
h,
i;
b.annotations = [
],
this.updateHighlights(),
this.resetHighlights(),
e = a.trim(b.element.find('input') .val());
if (e) {
d = this.highlights.map(function () {
return a(this) .data('annotation')
}),
i = a.makeArray(d);
for (g = 0, h = i.length; g < h; g++) c = i[g],
f = c[b.property],
b.isFiltered(e, f) && b.annotations.push(c);
return this.filterHighlights()
}
},
d.prototype.updateHighlights = function () {
return this.highlights = this.annotator.element.find('.annotator-hl:visible'),
this.filtered = this.highlights.not(this.classes.hl.hide)
},
d.prototype.filterHighlights = function () {
var b,
c,
d,
e,
f,
g,
h,
i,
j,
k;
b = a.grep(this.filters, function (a) {
return !!a.annotations.length
}),
e = ((k = b[0]) != null ? k.annotations : void 0) || [],
b.length > 1 && (d = [
], a.each(b, function () {
return a.merge(d, this.annotations)
}), h = [
], e = [
], a.each(d, function () {
return a.inArray(this, h) === - 1 ? h.push(this) : e.push(this)
})),
f = this.highlights;
for (g = i = 0, j = e.length; i < j; g = ++i) c = e[g],
f = f.not(c.highlights);
return f.addClass(this.classes.hl.hide),
this.filtered = this.highlights.not(this.classes.hl.hide),
this
},
d.prototype.resetHighlights = function () {
return this.highlights.removeClass(this.classes.hl.hide),
this.filtered = this.highlights,
this
},
d.prototype._onFilterFocus = function (b) {
var c;
return c = a(b.target),
c.parent() .addClass(this.classes.active),
c.next('button') .show()
},
d.prototype._onFilterBlur = function (b) {
var c;
if (!b.target.value) return c = a(b.target),
c.parent() .removeClass(this.classes.active),
c.next('button') .hide()
},
d.prototype._onFilterKeyup = function (b) {
var c;
c = a(b.target) .parent() .data('filter');
if (c) return this.updateFilter(c)
},
d.prototype._findNextHighlight = function (a) {
var b,
c,
d,
e,
f,
g,
h,
i;
return this.highlights.length ? (g = a ? 0 : - 1, i = a ? - 1 : 0, h = a ? 'lt' : 'gt', b = this.highlights.not('.' + this.classes.hl.hide), d = b.filter('.' + this.classes.hl.active), d.length || (d = b.eq(g)), c = d.data('annotation'), e = b.index(d[0]), f = b.filter(':' + h + '(' + e + ')') .not(c.highlights) .eq(i), f.length || (f = b.eq(i)), this._scrollToHighlight(f.data('annotation') .highlights)) : this
},
d.prototype._onNextClick = function (a) {
return this._findNextHighlight()
},
d.prototype._onPreviousClick = function (a) {
return this._findNextHighlight(!0)
},
d.prototype._scrollToHighlight = function (b) {
return b = a(b),
this.highlights.removeClass(this.classes.hl.active),
b.addClass(this.classes.hl.active),
a('html, body') .animate({
scrollTop: b.offset() .top - (this.element.height() + 20)
}, 150)
},
d.prototype._onClearClick = function (b) {
return a(b.target) .prev('input') .val('') .keyup() .blur()
},
d
}(b.Plugin),
b.Plugin.Markdown = function (c) {
function d(a, c) {
this.updateTextField = I(this.updateTextField, this),
(typeof Showdown !== 'undefined' && Showdown !== null ? Showdown.converter : void 0) != null ? (d.__super__.constructor.apply(this, arguments), this.converter = new Showdown.converter) : console.error(b._t('To use the Markdown plugin, you must include Showdown into the page first.'))
}
return H(d, c),
d.prototype.events = {
annotationViewerTextField: 'updateTextField'
},
d.prototype.updateTextField = function (c, d) {
var e;
return e = b.Util.escape(d.text || ''),
a(c) .html(this.convert(e))
},
d.prototype.convert = function (a) {
return this.converter.makeHtml(a)
},
d
}(b.Plugin),
b.Plugin.Tags = function (c) {
function d() {
return this.setAnnotationTags = I(this.setAnnotationTags, this),
this.updateField = I(this.updateField, this),
D = d.__super__.constructor.apply(this, arguments),
D
}
return H(d, c),
d.prototype.options = {
parseTags: function (b) {
var c;
return b = a.trim(b),
c = [
],
b && (c = b.split(/\s+/)),
c
},
stringifyTags: function (a) {
return a.join(' ')
}
},
d.prototype.field = null,
d.prototype.input = null,
d.prototype.pluginInit = function () {
if (!b.supported()) return ;
return this.field = this.annotator.editor.addField({
label: b._t('Add some tags here') + '鈥�',
load: this.updateField,
submit: this.setAnnotationTags
}),
this.annotator.viewer.addField({
load: this.updateViewer
}),
this.annotator.plugins.Filter && this.annotator.plugins.Filter.addFilter({
label: b._t('Tag'),
property: 'tags',
isFiltered: b.Plugin.Tags.filterCallback
}),
this.input = a(this.field) .find(':input')
},
d.prototype.parseTags = function (a) {
return this.options.parseTags(a)
},
d.prototype.stringifyTags = function (a) {
return this.options.stringifyTags(a)
},
d.prototype.updateField = function (a, b) {
var c;
return c = '',
b.tags && (c = this.stringifyTags(b.tags)),
this.input.val(c)
},
d.prototype.setAnnotationTags = function (a, b) {
return b.tags = this.parseTags(this.input.val())
},
d.prototype.updateViewer = function (c, d) {
return c = a(c),
d.tags && a.isArray(d.tags) && d.tags.length ? c.addClass('annotator-tags') .html(function () {
var c;
return c = a.map(d.tags, function (a) {
return '<span class="annotator-tag">' + b.Util.escape(a) + '</span>'
}) .join(' ')
}) : c.remove()
},
d
}(b.Plugin),
b.Plugin.Tags.filterCallback = function (a, b) {
var c,
d,
e,
f,
g,
h,
i,
j;
b == null && (b = [
]),
e = 0,
d = [
];
if (a) {
d = a.split(/\s+/g);
for (g = 0, i = d.length; g < i; g++) {
c = d[g];
if (b.length) for (h = 0, j = b.length; h < j; h++) f = b[h],
f.indexOf(c) !== - 1 && (e += 1)
}
}
return e === d.length
},
b.prototype.setupPlugins = function (c, d) {
var e,
f,
g,
h,
i,
j,
k,
l,
m;
c == null && (c = {
}),
d == null && (d = {
}),
j = b.Util.getGlobal(),
h = [
'Unsupported',
'Auth',
'Tags',
'Filter',
'Store',
'AnnotateItPermissions'
],
j.Showdown && h.push('Markdown'),
i = j.location.href.split(/#|\?/) .shift() || '',
g = {
Tags: {
},
Filter: {
filters: [
{
label: b._t('User'),
property: 'user'
},
{
label: b._t('Tags'),
property: 'tags'
}
]
},
Auth: {
tokenUrl: c.tokenUrl || 'http://annotateit.org/api/token'
},
Store: {
prefix: c.storeUrl || 'http://annotateit.org/api',
annotationData: {
uri: i
},
loadFromSearch: {
uri: i
}
}
};
for (e in d) {
if (!G.call(d, e)) continue;
f = d[e],
J.call(h, e) < 0 && h.push(e)
}
a.extend(!0, g, d),
m = [
];
for (k = 0, l = h.length; k < l; k++) e = h[k],
e in g && !g[e] ? m.push(void 0) : m.push(this.addPlugin(e, g[e]));
return m
}
})) .call(this);
/* Offline Annotator Plugin - v1.0.0
* Copyright 2012, Compendio <www.compendio.ch>
* Released under the MIT license
* More Information: http://github.com/aron/annotator.offline.js
*/
((function () {
var a,
b,
c = function (a, b) {
return function () {
return a.apply(b, arguments)
}
},
d = Object.prototype.hasOwnProperty,
e = function (a, b) {
function e() {
this.constructor = a
}
for (var c in b) d.call(b, c) && (a[c] = b[c]);
return e.prototype = b.prototype,
a.prototype = new e,
a.__super__ = b.prototype,
a
};
Annotator.Plugin.Offline = a = function (a) {
function g() {
this._onOffline = c(this._onOffline, this),
this._onOnline = c(this._onOnline, this);
var a,
e,
f;
g.__super__.constructor.apply(this, arguments),
this.store = new g.Store,
this.cache = {
},
f = {
online: 'online',
offline: 'offline',
beforeAnnotationLoaded: 'setAnnotationData',
beforeAnnotationCreated: 'setAnnotationData'
};
for (a in f) {
if (!d.call(f, a)) continue;
e = f[a],
typeof this.options[e] == 'function' && this.on(a, b.proxy(this.options, e))
}
}
var b,
f;
return e(g, a),
f = Annotator._t,
b = Annotator.$,
g.ANNOTATION_PREFIX = 'annotation.',
g.uuid = function () {
return ('' + Math.random() + (new Date) .getTime()) .slice(2)
},
g.prototype.events = {
annotationCreated: '_onAnnotationCreated',
annotationUpdated: '_onAnnotationUpdated',
annotationDeleted: '_onAnnotationDeleted'
},
g.prototype.options = {
getUniqueKey: function (a) {
return a.id || (a.id = g.uuid()),
a.id
},
shouldLoadAnnotation: function (a) {
return !0
}
},
g.prototype.pluginInit = function () {
if (!Annotator.supported()) return ;
return this.loadAnnotationsFromStore(),
this.isOnline() ? this.online() : this.offline(),
b(window) .bind({
online: this._onOnline,
offline: this._onOffline
})
},
g.prototype.annotations = function () {
return this.cache
},
g.prototype.online = function () {
return this.publish('online', [
this
]),
this
},
g.prototype.offline = function () {
return this.publish('offline', [
this
]),
this
},
g.prototype.isOnline = function () {
return window.navigator.onLine
},
g.prototype.loadAnnotationsFromStore = function () {
var a,
b,
c,
d,
e;
c = [
],
b = this.store.all(g.ANNOTATION_PREFIX);
for (d = 0, e = b.length; d < e; d++) {
a = b[d];
if (!this.options.shouldLoadAnnotation(a)) continue;
this.publish('beforeAnnotationLoaded', [
a,
this
]),
this.publish('annotationLoaded', [
a,
this
]),
this.cache[this.keyForAnnotation(a)] = a,
c.push(a)
}
return c.length && this.annotator.loadAnnotations(c),
this
},
g.prototype.addAnnotation = function (a, b) {
var c;
return b == null && (b = {
}),
c = this.cache[this.options.getUniqueKey(a)],
!c && this.options.shouldLoadAnnotation(a) ? this.annotator.setupAnnotation(a, b.silent) : this.updateStoredAnnotation(a),
this
},
g.prototype.removeAnnotation = function (a) {
return this.options.shouldLoadAnnotation(a) ? this.annotator.deleteAnnotation(a) : this.removeStoredAnnotation(a),
this
},
g.prototype.updateStoredAnnotation = function (a) {
var c,
d,
e,
f;
return c = this.keyForAnnotation(a),
d = this.keyForStore(a),
e = this.cache[c],
e ? b.extend(e, a) : e = this.cache[c] = a,
f = b.extend({
}, e),
delete f.highlights,
this.store.set(d, f),
this
},
g.prototype.removeStoredAnnotation = function (a) {
var b,
c;
return b = this.keyForAnnotation(a),
c = this.keyForStore(a),
this.store.remove(c),
delete this.cache[b],
this
},
g.prototype.keyForAnnotation = function (a) {
return this.options.getUniqueKey.call(this, a, this)
},
g.prototype.keyForStore = function (a) {
return g.ANNOTATION_PREFIX + this.keyForAnnotation(a)
},
g.prototype._onOnline = function (a) {
return this.online()
},
g.prototype._onOffline = function (a) {
return this.offline()
},
g.prototype._onAnnotationCreated = function (a) {
return this.updateStoredAnnotation(a)
},
g.prototype._onAnnotationUpdated = function (a) {
return this.updateStoredAnnotation(a)
},
g.prototype._onAnnotationDeleted = function (a) {
return this.removeStoredAnnotation(a)
},
g
}(Annotator.Plugin),
Annotator.Plugin.Offline.Store = b = function (a) {
function b() {
b.__super__.constructor.apply(this, arguments)
}
return e(b, a),
b.KEY_PREFIX = 'annotator.offline/',
b.CACHE_DELIMITER = '--cache--',
b.localStorage = window.localStorage,
b.isSupported = function () {
try {
return 'localStorage' in window && window.localStorage !== null
} catch (a) {
return !1
}
},
b.now = function () {
return (new Date) .getTime()
},
b.prototype.all = function (a) {
var c,
d,
e,
f;
a == null && (a = ''),
f = [
],
d = this.prefixed(a);
for (c in localStorage) {
if (c.indexOf(d) !== 0) continue;
e = this.get(c.slice(b.KEY_PREFIX.length)),
f.push(e)
}
return f
},
b.prototype.get = function (a) {
var c;
return c = b.localStorage.getItem(this.prefixed(a)),
c && (c = this.checkCache(c), c || this.remove(a)),
JSON.parse(c)
},
b.prototype.set = function (a, c, d) {
c = JSON.stringify(c),
d && (c = b.now() + d + b.CACHE_DELIMITER + c);
try {
b.localStorage.setItem(this.prefixed(a), c)
} catch (e) {
this.publish('error', [
e,
this
])
}
return this
},
b.prototype.remove = function (a) {
return b.localStorage.removeItem(this.prefixed(a)),
this
},
b.prototype.clear = function () {
var a,
c;
c = b.localStorage;
for (a in c) a.indexOf(b.KEY_PREFIX) === 0 && c.removeItem(a);
return this
},
b.prototype.prefixed = function (a) {
return b.KEY_PREFIX + a
},
b.prototype.checkCache = function (a) {
var c;
return a.indexOf(b.CACHE_DELIMITER) > - 1 && (c = a.split(b.CACHE_DELIMITER), a = b.now() > c.shift() ? null : c.join(b.CACHE_DELIMITER)),
a
},
b
}(Annotator.Delegator)
})) .call(this);
//in case of compatibility problems,replace jQuery with $wxz
var $wxz = jQuery.noConflict();
// insert css
var cssText = '<link rel="stylesheet" href="https://wxzproxy.duapp.com/css/annotator.min.css" />';
$wxz('head:first') .append(cssText);
//initialize the annotation method,and attach offline plugin
var content = $wxz('body:first') .annotator();
content.annotator('addPlugin', 'Offline');
var annotator = content.data('annotator');
//clear local storage method .just for further development
$wxz('#clear-storage') .click(function () {
if (annotator) {
annotator.plugins.Offline.store.clear()
}
});