# HG changeset patch # User robcast # Date 1421438240 -3600 # Node ID 7a39ed403635f64048febbbaec4d9a15afe120c1 # Parent 49d643f0d6587cad5b9d027b5ffed994c7894f4c updated to Annotator.js 1.2.9-dev. diff -r 49d643f0d658 -r 7a39ed403635 webapp/src/main/webapp/jquery/annotator-dl.js --- a/webapp/src/main/webapp/jquery/annotator-dl.js Fri Jan 16 18:20:15 2015 +0100 +++ b/webapp/src/main/webapp/jquery/annotator-dl.js Fri Jan 16 20:57:20 2015 +0100 @@ -1,23 +1,124 @@ + /* -** Annotator 1.2.5-dev-a4cd304 +** Annotator v1.2.9-dev-b091a74 ** https://github.com/okfn/annotator/ ** -** Copyright 2012 Aron Carroll, Rufus Pollock, and Nick Stenning. +** Copyright 2015, the Annotator project contributors. ** Dual licensed under the MIT and GPLv3 licenses. ** https://github.com/okfn/annotator/blob/master/LICENSE ** -** Built at: 2012-11-23 09:46:08Z -*/ - - +** Built at: 2015-01-16 17:56:43Z + */ + + +// + +// Generated by CoffeeScript 1.6.3 (function() { - var $, Annotator, Delegator, LinkParser, Range, base64Decode, base64UrlDecode, createDateFromISO8601, fn, functions, g, gettext, parseToken, util, _Annotator, _gettext, _i, _j, _len, _len1, _ref, _ref1, _t, + var $, Annotator, Delegator, LinkParser, Range, Util, base64Decode, base64UrlDecode, createDateFromISO8601, findChild, fn, functions, g, getNodeName, getNodePosition, gettext, parseToken, simpleXPathJQuery, simpleXPathPure, _Annotator, _gettext, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3, _ref4, _t, __slice = [].slice, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + simpleXPathJQuery = function(relativeRoot) { + var jq; + jq = this.map(function() { + var elem, idx, path, tagName; + path = ''; + elem = this; + while ((elem != null ? elem.nodeType : void 0) === Node.ELEMENT_NODE && elem !== relativeRoot) { + tagName = elem.tagName.replace(":", "\\:"); + idx = $(elem.parentNode).children(tagName).index(elem) + 1; + idx = "[" + idx + "]"; + path = "/" + elem.tagName.toLowerCase() + idx + path; + elem = elem.parentNode; + } + return path; + }); + return jq.get(); + }; + + simpleXPathPure = function(relativeRoot) { + var getPathSegment, getPathTo, jq, rootNode; + getPathSegment = function(node) { + var name, pos; + name = getNodeName(node); + pos = getNodePosition(node); + return "" + name + "[" + pos + "]"; + }; + rootNode = relativeRoot; + getPathTo = function(node) { + var xpath; + xpath = ''; + while (node !== rootNode) { + if (node == null) { + throw new Error("Called getPathTo on a node which was not a descendant of @rootNode. " + rootNode); + } + xpath = (getPathSegment(node)) + '/' + xpath; + node = node.parentNode; + } + xpath = '/' + xpath; + xpath = xpath.replace(/\/$/, ''); + return xpath; + }; + jq = this.map(function() { + var path; + path = getPathTo(this); + return path; + }); + return jq.get(); + }; + + findChild = function(node, type, index) { + var child, children, found, name, _i, _len; + if (!node.hasChildNodes()) { + throw new Error("XPath error: node has no children!"); + } + children = node.childNodes; + found = 0; + for (_i = 0, _len = children.length; _i < _len; _i++) { + child = children[_i]; + name = getNodeName(child); + if (name === type) { + found += 1; + if (found === index) { + return child; + } + } + } + throw new Error("XPath error: wanted child not found."); + }; + + getNodeName = function(node) { + var nodeName; + nodeName = node.nodeName.toLowerCase(); + switch (nodeName) { + case "#text": + return "text()"; + case "#comment": + return "comment()"; + case "#cdata-section": + return "cdata-section()"; + default: + return nodeName; + } + }; + + getNodePosition = function(node) { + var pos, tmp; + pos = 0; + tmp = node; + while (tmp) { + if (tmp.nodeName === node.nodeName) { + pos++; + } + tmp = tmp.previousSibling; + } + return pos; + }; + gettext = null; if (typeof Gettext !== "undefined" && Gettext !== null) { @@ -45,9 +146,11 @@ console.error(_t("Annotator requires a JSON implementation: have you included lib/vendor/json2.js?")); } - $ = jQuery.sub(); - - $.flatten = function(array) { + $ = jQuery; + + Util = {}; + + Util.flatten = function(array) { var flatten; flatten = function(ary) { var el, flat, _i, _len; @@ -61,30 +164,25 @@ return flatten(array); }; - $.plugin = function(name, object) { - return jQuery.fn[name] = function(options) { - var args; - args = Array.prototype.slice.call(arguments, 1); - return this.each(function() { - var instance; - instance = $.data(this, name); - if (instance) { - return options && instance[options].apply(instance, args); - } else { - instance = new object(this, options); - return $.data(this, name, instance); - } - }); - }; + Util.contains = function(parent, child) { + var node; + node = child; + while (node != null) { + if (node === parent) { + return true; + } + node = node.parentNode; + } + return false; }; - $.fn.textNodes = function() { + Util.getTextNodes = function(jq) { var getTextNodes; getTextNodes = function(node) { var nodes; - if (node && node.nodeType !== 3) { + if (node && node.nodeType !== Node.TEXT_NODE) { nodes = []; - if (node.nodeType !== 8) { + if (node.nodeType !== Node.COMMENT_NODE) { node = node.lastChild; while (node) { nodes.push(getTextNodes(node)); @@ -96,55 +194,154 @@ return node; } }; - return this.map(function() { - return $.flatten(getTextNodes(this)); + return jq.map(function() { + return Util.flatten(getTextNodes(this)); }); }; - $.fn.xpath = function(relativeRoot) { - var jq; - jq = this.map(function() { - var elem, idx, path; - path = ''; - elem = this; - while (elem && elem.nodeType === 1 && elem !== relativeRoot) { - idx = $(elem.parentNode).children(elem.tagName).index(elem) + 1; - idx = "[" + idx + "]"; - path = "/" + elem.tagName.toLowerCase() + idx + path; - elem = elem.parentNode; - } - return path; - }); - return jq.get(); + Util.getLastTextNodeUpTo = function(n) { + var result; + switch (n.nodeType) { + case Node.TEXT_NODE: + return n; + case Node.ELEMENT_NODE: + if (n.lastChild != null) { + result = Util.getLastTextNodeUpTo(n.lastChild); + if (result != null) { + return result; + } + } + break; + } + n = n.previousSibling; + if (n != null) { + return Util.getLastTextNodeUpTo(n); + } else { + return null; + } }; - $.escape = function(html) { + Util.getFirstTextNodeNotBefore = function(n) { + var result; + switch (n.nodeType) { + case Node.TEXT_NODE: + return n; + case Node.ELEMENT_NODE: + if (n.firstChild != null) { + result = Util.getFirstTextNodeNotBefore(n.firstChild); + if (result != null) { + return result; + } + } + break; + } + n = n.nextSibling; + if (n != null) { + return Util.getFirstTextNodeNotBefore(n); + } else { + return null; + } + }; + + Util.readRangeViaSelection = function(range) { + var sel; + sel = Util.getGlobal().getSelection(); + sel.removeAllRanges(); + sel.addRange(range.toRange()); + return sel.toString(); + }; + + Util.xpathFromNode = function(el, relativeRoot) { + var exception, result; + try { + result = simpleXPathJQuery.call(el, relativeRoot); + } catch (_error) { + exception = _error; + console.log("jQuery-based XPath construction failed! Falling back to manual."); + result = simpleXPathPure.call(el, relativeRoot); + } + return result; + }; + + Util.nodeFromXPath = function(xp, root) { + var idx, name, node, step, steps, _i, _len, _ref1; + steps = xp.substring(1).split("/"); + node = root; + for (_i = 0, _len = steps.length; _i < _len; _i++) { + step = steps[_i]; + _ref1 = step.split("["), name = _ref1[0], idx = _ref1[1]; + idx = idx != null ? parseInt((idx != null ? idx.split("]") : void 0)[0]) : 1; + node = findChild(node, name.toLowerCase(), idx); + } + return node; + }; + + Util.escape = function(html) { return html.replace(/&(?!\w+;)/g, '&').replace(//g, '>').replace(/"/g, '"'); }; - $.fn.escape = function(html) { - if (arguments.length) { - return this.html($.escape(html)); + Util.uuid = (function() { + var counter; + counter = 0; + return function() { + return counter++; + }; + })(); + + Util.getGlobal = function() { + return (function() { + return this; + })(); + }; + + Util.maxZIndex = function($elements) { + var all, el; + all = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = $elements.length; _i < _len; _i++) { + el = $elements[_i]; + if ($(el).css('position') === 'static') { + _results.push(-1); + } else { + _results.push(parseFloat($(el).css('z-index')) || -1); + } + } + return _results; + })(); + return Math.max.apply(Math, all); + }; + + Util.mousePosition = function(e, offsetEl) { + var offset, _ref1; + if ((_ref1 = $(offsetEl).css('position')) !== 'absolute' && _ref1 !== 'fixed' && _ref1 !== 'relative') { + offsetEl = $(offsetEl).offsetParent()[0]; } - return this.html(); + offset = $(offsetEl).offset(); + return { + top: e.pageY - offset.top, + left: e.pageX - offset.left + }; }; - $.fn.reverse = []._reverse || [].reverse; + Util.preventEventDefault = function(event) { + return event != null ? typeof event.preventDefault === "function" ? event.preventDefault() : void 0 : void 0; + }; functions = ["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) { - if (!(console.group != null)) { + if (console.group == null) { console.group = function(name) { return console.log("GROUP: ", name); }; } - if (!(console.groupCollapsed != null)) { + if (console.groupCollapsed == null) { console.groupCollapsed = console.group; } for (_i = 0, _len = functions.length; _i < _len; _i++) { fn = functions[_i]; - if (!(console[fn] != null)) { + if (console[fn] == null) { console[fn] = function() { return console.log(_t("Not implemented:") + (" console." + name)); }; @@ -169,7 +366,6 @@ } Delegator = (function() { - Delegator.prototype.events = {}; Delegator.prototype.options = {}; @@ -179,47 +375,62 @@ function Delegator(element, options) { this.options = $.extend(true, {}, this.options, options); this.element = $(element); + this._closures = {}; this.on = this.subscribe; this.addEvents(); } + Delegator.prototype.destroy = function() { + return this.removeEvents(); + }; + Delegator.prototype.addEvents = function() { - var event, functionName, sel, selector, _k, _ref1, _ref2, _results; - _ref1 = this.events; + var event, _k, _len2, _ref1, _results; + _ref1 = Delegator._parseEvents(this.events); _results = []; - for (sel in _ref1) { - functionName = _ref1[sel]; - _ref2 = sel.split(' '), selector = 2 <= _ref2.length ? __slice.call(_ref2, 0, _k = _ref2.length - 1) : (_k = 0, []), event = _ref2[_k++]; - _results.push(this.addEvent(selector.join(' '), event, functionName)); + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + event = _ref1[_k]; + _results.push(this._addEvent(event.selector, event.event, event.functionName)); } return _results; }; - Delegator.prototype.addEvent = function(bindTo, event, functionName) { - var closure, isBlankSelector, + Delegator.prototype.removeEvents = function() { + var event, _k, _len2, _ref1, _results; + _ref1 = Delegator._parseEvents(this.events); + _results = []; + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + event = _ref1[_k]; + _results.push(this._removeEvent(event.selector, event.event, event.functionName)); + } + return _results; + }; + + Delegator.prototype._addEvent = function(selector, event, functionName) { + var closure, _this = this; closure = function() { return _this[functionName].apply(_this, arguments); }; - isBlankSelector = typeof bindTo === 'string' && bindTo.replace(/\s+/g, '') === ''; - if (isBlankSelector) { - bindTo = this.element; - } - if (typeof bindTo === 'string') { - this.element.delegate(bindTo, event, closure); + if (selector === '' && Delegator._isCustomEvent(event)) { + this.subscribe(event, closure); } else { - if (this.isCustomEvent(event)) { - this.subscribe(event, closure); - } else { - $(bindTo).bind(event, closure); - } + this.element.delegate(selector, event, closure); } + this._closures["" + selector + "/" + event + "/" + functionName] = closure; return this; }; - Delegator.prototype.isCustomEvent = function(event) { - event = event.split('.')[0]; - return $.inArray(event, Delegator.natives) === -1; + Delegator.prototype._removeEvent = function(selector, event, functionName) { + var closure; + closure = this._closures["" + selector + "/" + event + "/" + functionName]; + if (selector === '' && Delegator._isCustomEvent(event)) { + this.unsubscribe(event, closure); + } else { + this.element.undelegate(selector, event, closure); + } + delete this._closures["" + selector + "/" + event + "/" + functionName]; + return this; }; Delegator.prototype.publish = function() { @@ -246,6 +457,21 @@ })(); + Delegator._parseEvents = function(eventsObj) { + var event, events, functionName, sel, selector, _k, _ref1; + events = []; + for (sel in eventsObj) { + functionName = eventsObj[sel]; + _ref1 = sel.split(' '), selector = 2 <= _ref1.length ? __slice.call(_ref1, 0, _k = _ref1.length - 1) : (_k = 0, []), event = _ref1[_k++]; + events.push({ + selector: selector.join(' '), + event: event, + functionName: functionName + }); + } + return events; + }; + Delegator.natives = (function() { var key, specials, val; specials = (function() { @@ -262,6 +488,11 @@ return "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(specials); })(); + Delegator._isCustomEvent = function(event) { + event = event.split('.')[0]; + return $.inArray(event, Delegator.natives) === -1; + }; + Range = {}; Range.sniff = function(r) { @@ -283,10 +514,18 @@ root = document; } evaluateXPath = function(xp, nsResolver) { + var exception; if (nsResolver == null) { nsResolver = null; } - return document.evaluate('.' + xp, root, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; + try { + return document.evaluate('.' + xp, root, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; + } catch (_error) { + exception = _error; + console.log("XPath evaluation failed."); + console.log("Trying fallback..."); + return Util.nodeFromXPath(xp, root); + } }; if (!$.isXMLDoc(document.documentElement)) { return evaluateXPath(xpath); @@ -323,7 +562,6 @@ }; Range.RangeError = (function(_super) { - __extends(RangeError, _super); function RangeError(type, message, parent) { @@ -338,7 +576,6 @@ })(Error); Range.BrowserRange = (function() { - function BrowserRange(obj) { this.commonAncestorContainer = obj.commonAncestorContainer; this.startContainer = obj.startContainer; @@ -348,7 +585,7 @@ } BrowserRange.prototype.normalize = function(root) { - var it, node, nr, offset, p, r, _k, _len2, _ref1; + var n, node, nr, r; if (this.tainted) { console.error(_t("You may only call normalize() once on a BrowserRange!")); return false; @@ -356,44 +593,57 @@ this.tainted = true; } r = {}; - nr = {}; - _ref1 = ['start', 'end']; - for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { - p = _ref1[_k]; - node = this[p + 'Container']; - offset = this[p + 'Offset']; - if (!((node != null) && (offset != null))) { - return false; + if (this.startContainer.nodeType === Node.ELEMENT_NODE) { + r.start = Util.getFirstTextNodeNotBefore(this.startContainer.childNodes[this.startOffset]); + r.startOffset = 0; + } else { + r.start = this.startContainer; + r.startOffset = this.startOffset; + } + if (this.endContainer.nodeType === Node.ELEMENT_NODE) { + node = this.endContainer.childNodes[this.endOffset]; + if (node != null) { + n = node; + while ((n != null) && (n.nodeType !== Node.TEXT_NODE)) { + n = n.firstChild; + } + if (n != null) { + r.end = n; + r.endOffset = 0; + } } - if (node.nodeType === 1) { - it = node.childNodes[offset]; - node = it || node.childNodes[offset - 1]; - if (node.nodeType === 1 && !node.firstChild) { - it = null; - node = node.previousSibling; - } - while (node.nodeType !== 3) { - node = node.firstChild; - } - offset = it ? 0 : node.nodeValue.length; + if (r.end == null) { + node = this.endContainer.childNodes[this.endOffset - 1]; + r.end = Util.getLastTextNodeUpTo(node); + r.endOffset = r.end.nodeValue.length; } - r[p] = node; - r[p + 'Offset'] = offset; + } else { + r.end = this.endContainer; + r.endOffset = this.endOffset; } - nr.start = r.startOffset > 0 ? r.start.splitText(r.startOffset) : r.start; + nr = {}; + if (r.startOffset > 0) { + if (r.start.nodeValue.length > r.startOffset) { + nr.start = r.start.splitText(r.startOffset); + } else { + nr.start = r.start.nextSibling; + } + } else { + nr.start = r.start; + } if (r.start === r.end) { - if ((r.endOffset - r.startOffset) < nr.start.nodeValue.length) { + if (nr.start.nodeValue.length > (r.endOffset - r.startOffset)) { nr.start.splitText(r.endOffset - r.startOffset); } nr.end = nr.start; } else { - if (r.endOffset < r.end.nodeValue.length) { + if (r.end.nodeValue.length > r.endOffset) { r.end.splitText(r.endOffset); } nr.end = r.end; } nr.commonAncestor = this.commonAncestorContainer; - while (nr.commonAncestor.nodeType !== 1) { + while (nr.commonAncestor.nodeType !== Node.ELEMENT_NODE) { nr.commonAncestor = nr.commonAncestor.parentNode; } return new Range.NormalizedRange(nr); @@ -408,7 +658,6 @@ })(); Range.NormalizedRange = (function() { - function NormalizedRange(obj) { this.commonAncestor = obj.commonAncestor; this.start = obj.start; @@ -450,8 +699,8 @@ } else { origParent = $(node).parent(); } - xpath = origParent.xpath(root)[0]; - textNodes = origParent.textNodes(); + xpath = Util.xpathFromNode(origParent, root)[0]; + textNodes = Util.getTextNodes(origParent); nodes = textNodes.slice(0, textNodes.index(node)); offset = 0; for (_k = 0, _len2 = nodes.length; _k < _len2; _k++) { @@ -490,9 +739,9 @@ NormalizedRange.prototype.textNodes = function() { var end, start, textNodes, _ref1; - textNodes = $(this.commonAncestor).textNodes(); + textNodes = Util.getTextNodes($(this.commonAncestor)); _ref1 = [textNodes.index(this.start), textNodes.index(this.end)], start = _ref1[0], end = _ref1[1]; - return $.makeArray(textNodes.slice(start, end + 1 || 9e9)); + return $.makeArray(textNodes.slice(start, +end + 1 || 9e9)); }; NormalizedRange.prototype.toRange = function() { @@ -508,7 +757,6 @@ })(); Range.SerializedRange = (function() { - function SerializedRange(obj) { this.start = obj.start; this.startOffset = obj.startOffset; @@ -517,24 +765,29 @@ } SerializedRange.prototype.normalize = function(root) { - var contains, length, node, p, range, tn, _k, _l, _len2, _len3, _ref1, _ref2; + var contains, e, length, node, p, range, targetOffset, tn, _k, _l, _len2, _len3, _ref1, _ref2; range = {}; _ref1 = ['start', 'end']; for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { p = _ref1[_k]; try { node = Range.nodeFromXPath(this[p], root); - } catch (e) { + } catch (_error) { + e = _error; throw new Range.RangeError(p, ("Error while finding " + p + " node: " + this[p] + ": ") + e, e); } if (!node) { throw new Range.RangeError(p, "Couldn't find " + p + " node: " + this[p]); } length = 0; - _ref2 = $(node).textNodes(); + targetOffset = this[p + 'Offset']; + if (p === 'end') { + targetOffset--; + } + _ref2 = Util.getTextNodes($(node)); for (_l = 0, _len3 = _ref2.length; _l < _len3; _l++) { tn = _ref2[_l]; - if (length + tn.nodeValue.length >= this[p + 'Offset']) { + if (length + tn.nodeValue.length > targetOffset) { range[p + 'Container'] = tn; range[p + 'Offset'] = this[p + 'Offset'] - length; break; @@ -542,16 +795,16 @@ length += tn.nodeValue.length; } } - if (!(range[p + 'Offset'] != null)) { + if (range[p + 'Offset'] == null) { throw new Range.RangeError("" + p + "offset", "Couldn't find offset " + this[p + 'Offset'] + " in element " + this[p]); } } - contains = !(document.compareDocumentPosition != null) ? function(a, b) { + contains = document.compareDocumentPosition == null ? function(a, b) { return a.contains(b); } : function(a, b) { return a.compareDocumentPosition(b) & 16; }; - $(range.startContainer).parents().reverse().each(function() { + $(range.startContainer).parents().each(function() { if (contains(this, range.endContainer)) { range.commonAncestorContainer = this; return false; @@ -577,53 +830,9 @@ })(); - util = { - uuid: (function() { - var counter; - counter = 0; - return function() { - return counter++; - }; - })(), - getGlobal: function() { - return (function() { - return this; - })(); - }, - maxZIndex: function($elements) { - var all, el; - all = (function() { - var _k, _len2, _results; - _results = []; - for (_k = 0, _len2 = $elements.length; _k < _len2; _k++) { - el = $elements[_k]; - if ($(el).css('position') === 'static') { - _results.push(-1); - } else { - _results.push(parseInt($(el).css('z-index'), 10) || -1); - } - } - return _results; - })(); - return Math.max.apply(Math, all); - }, - mousePosition: function(e, offsetEl) { - var offset; - offset = $(offsetEl).offset(); - return { - top: e.pageY - offset.top, - left: e.pageX - offset.left - }; - }, - preventEventDefault: function(event) { - return event != null ? typeof event.preventDefault === "function" ? event.preventDefault() : void 0 : void 0; - } - }; - _Annotator = this.Annotator; Annotator = (function(_super) { - __extends(Annotator, _super); Annotator.prototype.events = { @@ -658,29 +867,17 @@ function Annotator(element, options) { this.onDeleteAnnotation = __bind(this.onDeleteAnnotation, this); - this.onEditAnnotation = __bind(this.onEditAnnotation, this); - this.onAdderClick = __bind(this.onAdderClick, this); - this.onAdderMousedown = __bind(this.onAdderMousedown, this); - this.onHighlightMouseover = __bind(this.onHighlightMouseover, this); - this.checkForEndSelection = __bind(this.checkForEndSelection, this); - this.checkForStartSelection = __bind(this.checkForStartSelection, this); - this.clearViewerHideTimer = __bind(this.clearViewerHideTimer, this); - this.startViewerHideTimer = __bind(this.startViewerHideTimer, this); - this.showViewer = __bind(this.showViewer, this); - this.onEditorSubmit = __bind(this.onEditorSubmit, this); - this.onEditorHide = __bind(this.onEditorHide, this); - this.showEditor = __bind(this.showEditor, this); Annotator.__super__.constructor.apply(this, arguments); this.plugins = {}; @@ -693,6 +890,7 @@ this._setupWrapper()._setupViewer()._setupEditor(); this._setupDynamicStyle(); this.adder = $(this.html.adder).appendTo(this.wrapper).hide(); + Annotator._instances.push(this); } Annotator.prototype._setupWrapper = function() { @@ -711,7 +909,7 @@ this.viewer.hide().on("edit", this.onEditAnnotation).on("delete", this.onDeleteAnnotation).addField({ load: function(field, annotation) { if (annotation.text) { - $(field).escape(annotation.text); + $(field).html(Util.escape(annotation.text)); } else { $(field).html("" + (_t('No Comment')) + ""); } @@ -764,15 +962,46 @@ } return _results; })()).join(''); - max = util.maxZIndex($(document.body).find(sel)); + max = Util.maxZIndex($(document.body).find(sel)); max = Math.max(max, 1000); style.text([".annotator-adder, .annotator-outer, .annotator-notice {", " z-index: " + (max + 20) + ";", "}", ".annotator-filter {", " z-index: " + (max + 10) + ";", "}"].join("\n")); return this; }; + Annotator.prototype.destroy = function() { + var idx, name, plugin, _base, _ref1; + Annotator.__super__.destroy.apply(this, arguments); + $(document).unbind({ + "mouseup": this.checkForEndSelection, + "mousedown": this.checkForStartSelection + }); + $('#annotator-dynamic-style').remove(); + this.adder.remove(); + this.viewer.destroy(); + this.editor.destroy(); + this.wrapper.find('.annotator-hl').each(function() { + $(this).contents().insertBefore(this); + return $(this).remove(); + }); + this.wrapper.contents().insertBefore(this.wrapper); + this.wrapper.remove(); + this.element.data('annotator', null); + _ref1 = this.plugins; + for (name in _ref1) { + plugin = _ref1[name]; + if (typeof (_base = this.plugins[name]).destroy === "function") { + _base.destroy(); + } + } + idx = Annotator._instances.indexOf(this); + if (idx !== -1) { + return Annotator._instances.splice(idx, 1); + } + }; + Annotator.prototype.getSelectedRanges = function() { var browserRange, i, normedRange, r, ranges, rangesToIgnore, selection, _k, _len2; - selection = util.getGlobal().getSelection(); + selection = Util.getGlobal().getSelection(); ranges = []; rangesToIgnore = []; if (!selection.isCollapsed) { @@ -811,11 +1040,8 @@ return annotation; }; - Annotator.prototype.setupAnnotation = function(annotation, fireEvents) { - var normed, normedRanges, r, root, _k, _l, _len2, _len3, _ref1; - if (fireEvents == null) { - fireEvents = true; - } + Annotator.prototype.setupAnnotation = function(annotation) { + var e, normed, normedRanges, r, root, _k, _l, _len2, _len3, _ref1; root = this.wrapper[0]; annotation.ranges || (annotation.ranges = this.selectedRanges); normedRanges = []; @@ -824,7 +1050,8 @@ r = _ref1[_k]; try { normedRanges.push(Range.sniff(r).normalize(root)); - } catch (e) { + } catch (_error) { + e = _error; if (e instanceof Range.RangeError) { this.publish('rangeNormalizeFail', [annotation, r, e]); } else { @@ -843,24 +1070,29 @@ } annotation.quote = annotation.quote.join(' / '); $(annotation.highlights).data('annotation', annotation); - if (fireEvents) { - this.publish('annotationCreated', [annotation]); - } + $(annotation.highlights).attr('data-annotation-id', annotation.id); return annotation; }; Annotator.prototype.updateAnnotation = function(annotation) { this.publish('beforeAnnotationUpdated', [annotation]); + $(annotation.highlights).attr('data-annotation-id', annotation.id); this.publish('annotationUpdated', [annotation]); return annotation; }; Annotator.prototype.deleteAnnotation = function(annotation) { - var h, _k, _len2, _ref1; - _ref1 = annotation.highlights; - for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { - h = _ref1[_k]; - $(h).replaceWith(h.childNodes); + var child, h, _k, _len2, _ref1; + if (annotation.highlights != null) { + _ref1 = annotation.highlights; + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + h = _ref1[_k]; + if (!(h.parentNode != null)) { + continue; + } + child = h.childNodes[0]; + $(h).replaceWith(h.childNodes); + } } this.publish('annotationDeleted', [annotation]); return annotation; @@ -880,7 +1112,7 @@ now = annList.splice(0, 10); for (_k = 0, _len2 = now.length; _k < _len2; _k++) { n = now[_k]; - _this.setupAnnotation(n, false); + _this.setupAnnotation(n); } if (annList.length > 0) { return setTimeout((function() { @@ -891,9 +1123,7 @@ } }; clone = annotations.slice(); - if (annotations.length) { - loader(annotations); - } + loader(annotations); return this; }; @@ -901,7 +1131,8 @@ if (this.plugins['Store']) { return this.plugins['Store'].dumpAnnotations(); } else { - return console.warn(_t("Can't dump annotations without Store plugin.")); + console.warn(_t("Can't dump annotations without Store plugin.")); + return false; } }; @@ -968,12 +1199,7 @@ }; Annotator.prototype.onEditorSubmit = function(annotation) { - this.publish('annotationEditorSubmit', [this.editor, annotation]); - if (annotation.ranges === void 0) { - return this.setupAnnotation(annotation); - } else { - return this.updateAnnotation(annotation); - } + return this.publish('annotationEditorSubmit', [this.editor, annotation]); }; Annotator.prototype.showViewer = function(annotations, location) { @@ -996,8 +1222,8 @@ Annotator.prototype.checkForStartSelection = function(event) { if (!(event && this.isAnnotator(event.target))) { this.startViewerHideTimer(); - return this.mouseIsDown = true; } + return this.mouseIsDown = true; }; Annotator.prototype.checkForEndSelection = function(event) { @@ -1012,33 +1238,36 @@ range = _ref1[_k]; container = range.commonAncestor; if ($(container).hasClass('annotator-hl')) { - container = $(container).parents('[class^=annotator-hl]')[0]; + container = $(container).parents('[class!=annotator-hl]')[0]; } if (this.isAnnotator(container)) { return; } } if (event && this.selectedRanges.length) { - return this.adder.css(util.mousePosition(event, this.wrapper[0])).show(); + return this.adder.css(Util.mousePosition(event, this.wrapper[0])).show(); } else { return this.adder.hide(); } }; Annotator.prototype.isAnnotator = function(element) { - return !!$(element).parents().andSelf().filter('[class^=annotator-]').not(this.wrapper).length; + return !!$(element).parents().addBack().filter('[class^=annotator-]').not(this.wrapper).length; }; Annotator.prototype.onHighlightMouseover = function(event) { var annotations; this.clearViewerHideTimer(); - if (this.mouseIsDown || this.viewer.isShown()) { + if (this.mouseIsDown) { return false; } - annotations = $(event.target).parents('.annotator-hl').andSelf().map(function() { + if (this.viewer.isShown()) { + this.viewer.hide(); + } + annotations = $(event.target).parents('.annotator-hl').addBack().map(function() { return $(this).data("annotation"); - }); - return this.showViewer($.makeArray(annotations), util.mousePosition(event, this.wrapper[0])); + }).toArray(); + return this.showViewer(annotations, Util.mousePosition(event, this.wrapper[0])); }; Annotator.prototype.onAdderMousedown = function(event) { @@ -1049,40 +1278,47 @@ }; Annotator.prototype.onAdderClick = function(event) { - var highlights, position, r, ranges; + var annotation, cancel, cleanup, position, save, + _this = this; if (event != null) { event.preventDefault(); } position = this.adder.position(); this.adder.hide(); - if (this.selectedRanges && this.selectedRanges.length) { - ranges = (function() { - var _k, _len2, _ref1, _results; - _ref1 = this.selectedRanges; - _results = []; - for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { - r = _ref1[_k]; - _results.push(Range.sniff(r).normalize()); - } - return _results; - }).call(this); - highlights = this.highlightRanges(ranges, 'annotator-hl annotator-hl-temporary'); - this.editor.element.one('hide', function() { - var h, _k, _len2, _results; - _results = []; - for (_k = 0, _len2 = highlights.length; _k < _len2; _k++) { - h = highlights[_k]; - _results.push($(h).replaceWith(h.childNodes)); - } - return _results; - }); - } - return this.showEditor(this.createAnnotation(), position); + annotation = this.setupAnnotation(this.createAnnotation()); + $(annotation.highlights).addClass('annotator-hl-temporary'); + save = function() { + cleanup(); + $(annotation.highlights).removeClass('annotator-hl-temporary'); + return _this.publish('annotationCreated', [annotation]); + }; + cancel = function() { + cleanup(); + return _this.deleteAnnotation(annotation); + }; + cleanup = function() { + _this.unsubscribe('annotationEditorHidden', cancel); + return _this.unsubscribe('annotationEditorSubmit', save); + }; + this.subscribe('annotationEditorHidden', cancel); + this.subscribe('annotationEditorSubmit', save); + return this.showEditor(annotation, position); }; Annotator.prototype.onEditAnnotation = function(annotation) { - var offset; + var cleanup, offset, update, + _this = this; offset = this.viewer.element.position(); + update = function() { + cleanup(); + return _this.updateAnnotation(annotation); + }; + cleanup = function() { + _this.unsubscribe('annotationEditorHidden', cleanup); + return _this.unsubscribe('annotationEditorSubmit', update); + }; + this.subscribe('annotationEditorHidden', cleanup); + this.subscribe('annotationEditorSubmit', update); this.viewer.hide(); return this.showEditor(annotation, offset); }; @@ -1097,7 +1333,6 @@ })(Delegator); Annotator.Plugin = (function(_super) { - __extends(Plugin, _super); function Plugin(element, options) { @@ -1110,26 +1345,47 @@ })(Delegator); - g = util.getGlobal(); - - if (!(((_ref1 = g.document) != null ? _ref1.evaluate : void 0) != null)) { + g = Util.getGlobal(); + + if (((_ref1 = g.document) != null ? _ref1.evaluate : void 0) == null) { $.getScript('http://assets.annotateit.org/vendor/xpath.min.js'); } - if (!(g.getSelection != null)) { + if (g.getSelection == null) { $.getScript('http://assets.annotateit.org/vendor/ierange.min.js'); } - if (!(g.JSON != null)) { + if (g.JSON == null) { $.getScript('http://assets.annotateit.org/vendor/json2.min.js'); } + if (g.Node == null) { + g.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 + }; + } + Annotator.$ = $; Annotator.Delegator = Delegator; Annotator.Range = Range; + Annotator.Util = Util; + + Annotator._instances = []; + Annotator._t = _t; Annotator.supported = function() { @@ -1139,16 +1395,31 @@ }; Annotator.noConflict = function() { - util.getGlobal().Annotator = _Annotator; + Util.getGlobal().Annotator = _Annotator; return this; }; - $.plugin('annotator', Annotator); + $.fn.annotator = function(options) { + var args; + args = Array.prototype.slice.call(arguments, 1); + return this.each(function() { + var instance; + instance = $.data(this, 'annotator'); + if (options === 'destroy') { + $.removeData(this, 'annotator'); + return instance != null ? instance.destroy(args) : void 0; + } else if (instance) { + return options && instance[options].apply(instance, args); + } else { + instance = new Annotator(this, options); + return $.data(this, 'annotator', instance); + } + }); + }; this.Annotator = Annotator; Annotator.Widget = (function(_super) { - __extends(Widget, _super); Widget.prototype.classes = { @@ -1164,10 +1435,15 @@ this.classes = $.extend({}, Annotator.Widget.prototype.classes, this.classes); } + Widget.prototype.destroy = function() { + this.removeEvents(); + return this.element.remove(); + }; + Widget.prototype.checkOrientation = function() { var current, offset, viewport, widget, window; this.resetOrientation(); - window = $(util.getGlobal()); + window = $(Annotator.Util.getGlobal()); widget = this.element.children(":first"); offset = widget.offset(); viewport = { @@ -1215,7 +1491,6 @@ })(Delegator); Annotator.Editor = (function(_super) { - __extends(Editor, _super); Editor.prototype.events = { @@ -1237,15 +1512,10 @@ function Editor(options) { this.onCancelButtonMouseover = __bind(this.onCancelButtonMouseover, this); - this.processKeypress = __bind(this.processKeypress, this); - this.submit = __bind(this.submit, this); - this.load = __bind(this.load, this); - this.hide = __bind(this.hide, this); - this.show = __bind(this.show, this); Editor.__super__.constructor.call(this, $(this.html)[0], options); this.fields = []; @@ -1253,7 +1523,7 @@ } Editor.prototype.show = function(event) { - util.preventEventDefault(event); + Annotator.Util.preventEventDefault(event); this.element.removeClass(this.classes.hide); this.element.find('.annotator-save').addClass(this.classes.focus); this.checkOrientation(); @@ -1263,7 +1533,7 @@ }; Editor.prototype.hide = function(event) { - util.preventEventDefault(event); + Annotator.Util.preventEventDefault(event); this.element.addClass(this.classes.hide); return this.publish('hide'); }; @@ -1282,7 +1552,7 @@ Editor.prototype.submit = function(event) { var field, _k, _len2, _ref2; - util.preventEventDefault(event); + Annotator.Util.preventEventDefault(event); _ref2 = this.fields; for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { field = _ref2[_k]; @@ -1295,7 +1565,7 @@ Editor.prototype.addField = function(options) { var element, field, input; field = $.extend({ - id: 'annotator-field-' + util.uuid(), + id: 'annotator-field-' + Annotator.Util.uuid(), type: 'input', label: '', load: function() {}, @@ -1311,6 +1581,9 @@ case 'input': case 'checkbox': input = $(''); + break; + case 'select': + input = $('