diff --git a/The Code/libraries/annotator/annotator.min.js b/The Code/libraries/annotator/annotator-full.min.js old mode 100644 new mode 100755 similarity index 58% rename from The Code/libraries/annotator/annotator.min.js rename to The Code/libraries/annotator/annotator-full.min.js index b01a1ab..1b507f6 --- a/The Code/libraries/annotator/annotator.min.js +++ b/The Code/libraries/annotator/annotator-full.min.js @@ -8,9 +8,6 @@ ** ** Built at: 2013-12-02 17:58:01Z */ - - -// ! function() { var $, @@ -19,6 +16,9 @@ function() { LinkParser, Range, Util, + base64Decode, + base64UrlDecode, + createDateFromISO8601, findChild, fn, functions, @@ -26,6 +26,7 @@ function() { getNodeName, getNodePosition, gettext, + parseToken, simpleXPathJQuery, simpleXPathPure, _Annotator, @@ -55,6 +56,13 @@ function() { 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; @@ -344,7 +352,7 @@ function() { if ($(el).css("position") === "static") { _results.push( - 1) } else { - _results.push(parseInt($(el).css("z-index"), 10) || -1) + _results.push(parseFloat($(el).css("z-index")) || -1) } } return _results @@ -413,6 +421,9 @@ function() { this.on = this.subscribe; this.addEvents() } + Delegator.prototype.destroy = function() { + return this.removeEvents() + }; Delegator.prototype.addEvents = function() { var event, _k, @@ -893,8 +904,8 @@ function() { Annotator.prototype.events = { ".annotator-adder button click": "onAdderClick", ".annotator-adder button mousedown": "onAdderMousedown", - ".annotator-hl mouseover": "onHighlightMouseover", - ".annotator-hl mouseout": "startViewerHideTimer" + ".annotator-hl click": "onHighlightClick", + //".annotator-hl mouseout": "startViewerHideTimer" }; Annotator.prototype.html = { adder: '
", @@ -915,7 +926,7 @@ function() { 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.onHighlightClick = __bind(this.onHighlightClick, this); this.checkForEndSelection = __bind(this.checkForEndSelection, this); this.checkForStartSelection = __bind(this.checkForStartSelection, this); this.clearViewerHideTimer = __bind(this.clearViewerHideTimer, this); @@ -960,8 +971,8 @@ function() { } } (this) }).element.appendTo(this.wrapper).bind({ - mouseover: this.clearViewerHideTimer, - mouseout: this.startViewerHideTimer + //mouseover: this.clearViewerHideTimer, + //mouseout: this.startViewerHideTimer }); return this }; @@ -983,7 +994,7 @@ function() { Annotator.prototype._setupDocumentEvents = function() { $(document).bind({ mouseup: this.checkForEndSelection, - mousedown: this.checkForStartSelection + click: this.checkForStartSelection }); return this }; @@ -1021,8 +1032,8 @@ function() { plugin, _ref1; $(document).unbind({ - mouseup: this.checkForEndSelection, - mousedown: this.checkForStartSelection + //mouseup: this.checkForEndSelection, + click: this.checkForStartSelection }); $("#annotator-dynamic-style").remove(); this.adder.remove(); @@ -1135,10 +1146,12 @@ function() { } annotation.quote = annotation.quote.join(" / "); $(annotation.highlights).data("annotation", 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 }; @@ -1216,7 +1229,7 @@ function() { cssClass = "annotator-hl" } white = /^\s*$/; - hl = $(""); + hl = $(""); _ref1 = normedRange.textNodes(); _results = []; for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { @@ -1281,7 +1294,7 @@ function() { }; Annotator.prototype.startViewerHideTimer = function() { if (!this.viewerHideTimer) { - return this.viewerHideTimer = setTimeout(this.viewer.hide, 250) + return this.viewerHideTimer = setTimeout(this.viewer.hide, 250) // Amanda: change timer length if annotation happens across in sidebar; was originally 250 } }; Annotator.prototype.clearViewerHideTimer = function() { @@ -1325,12 +1338,12 @@ function() { Annotator.prototype.isAnnotator = function(element) { return !! $(element).parents().addBack().filter("[class^=annotator-]").not(this.wrapper).length }; - Annotator.prototype.onHighlightMouseover = function(event) { + Annotator.prototype.onHighlightClick = function(event) { var annotations; - this.clearViewerHideTimer(); + /*this.clearViewerHideTimer(); //Amanda: removed to change highlight activation from hover to click if (this.mouseIsDown || this.viewer.isShown()) { return false - } + }*/ annotations = $(event.target).parents(".annotator-hl").addBack().map(function() { return $(this).data("annotation") }); @@ -1466,6 +1479,7 @@ function() { instance = $.data(this, "annotator"); if (instance) { return options && instance[options].apply(instance, args) + } else { instance = new Annotator(this, options); return $.data(this, "annotator", instance) @@ -1776,7 +1790,7 @@ function() { }; Viewer.prototype.html = { element: '
\n \n
', - item: '
  • \n \n View as webpage\n \n \n \n
  • ' + item: '
  • \n \n View as webpage\n \n \n \n
  • ' }; Viewer.prototype.options = { readOnly: false @@ -1830,7 +1844,15 @@ function() { _len3, _ref2, _ref3; - this.annotations = annotations || []; + this.annotations = annotations || []; //Amanda: Begin code to input annotations NIDs related to a highlight to concealed view exposed filter for annosidebar view. + var theresult = new Array(); + for(var key in annotations){ + allNIDs = annotations[key]['nid']; + theresult.push(allNIDs); + } + grabNID = theresult.join(','); + $('#edit-nid--2').val(grabNID); + $('#views-exposed-form-annosidebar-annosidebar').submit();//Amanda: autosubmit; working code ends list = this.element.find("ul:first").empty(); _ref2 = this.annotations; for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { @@ -1846,7 +1868,7 @@ function() { if (links.length === 0 || links[0].href == null) { link.remove() } else { - link.attr("href", links[0].href) + link.attr("href", links[0].href); } if (this.options.readOnly) { edit.remove(); @@ -1876,7 +1898,7 @@ function() { } this.publish("load", [this.annotations]); return this.show() - }; + }; Viewer.prototype.addField = function(options) { var field; field = $.extend({ @@ -1996,7 +2018,1278 @@ function() { notification = new Annotator.Notification; Annotator.showNotification = notification.show; return Annotator.hideNotification = notification.hide - }) + }); + Annotator.Plugin.Unsupported = function(_super) { + __extends(Unsupported, _super); + function Unsupported() { + return Unsupported.__super__.constructor.apply(this, arguments) + } + Unsupported.prototype.options = { + message: Annotator._t("Annotation is not supported by this browser, and/or you need to enable Javascript in your browser to annotate.") // Amanda: clarified unsupported message. Note this message has a character limit (127 characters?). + }; + Unsupported.prototype.pluginInit = function() { + if (!Annotator.supported()) { + return $(function(_this) { + return function() { + Annotator.showNotification(_this.options.message); + if (window.XMLHttpRequest === void 0 && ActiveXObject !== void 0) { + return $("html").addClass("ie6") + } + } + } (this)) + } + }; + return Unsupported + } (Annotator.Plugin); + createDateFromISO8601 = function(string) { + var d, + date, + offset, + regexp, + time, + _ref2; + regexp = "([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})))?)?)?)?"; + d = string.match(new RegExp(regexp)); + offset = 0; + date = new Date(d[1], 0, 1); + if (d[3]) { + date.setMonth(d[3] - 1) + } + if (d[5]) { + date.setDate(d[5]) + } + if (d[7]) { + date.setHours(d[7]) + } + if (d[8]) { + date.setMinutes(d[8]) + } + if (d[10]) { + date.setSeconds(d[10]) + } + if (d[12]) { + date.setMilliseconds(Number("0." + d[12]) * 1e3) + } + if (d[14]) { + offset = Number(d[16]) * 60 + Number(d[17]); + offset *= (_ref2 = d[15] === "-") != null ? _ref2: { + 1: -1 + } + } + offset -= date.getTimezoneOffset(); + time = Number(date) + offset * 60 * 1e3; + date.setTime(Number(time)); + return date + }; + base64Decode = function(data) { + var ac, + b64, + bits, + dec, + h1, + h2, + h3, + h4, + i, + o1, + o2, + o3, + tmp_arr; + if (typeof atob !== "undefined" && atob !== null) { + return atob(data) + } else { + b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + i = 0; + ac = 0; + dec = ""; + tmp_arr = []; + if (!data) { + return data + } + data += ""; + while (i < data.length) { + h1 = b64.indexOf(data.charAt(i++)); + h2 = b64.indexOf(data.charAt(i++)); + h3 = b64.indexOf(data.charAt(i++)); + h4 = b64.indexOf(data.charAt(i++)); + bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; + o1 = bits >> 16 & 255; + o2 = bits >> 8 & 255; + o3 = bits & 255; + if (h3 === 64) { + tmp_arr[ac++] = String.fromCharCode(o1) + } else if (h4 === 64) { + tmp_arr[ac++] = String.fromCharCode(o1, o2) + } else { + tmp_arr[ac++] = String.fromCharCode(o1, o2, o3) + } + } + return tmp_arr.join("") + } + }; + base64UrlDecode = function(data) { + var i, + m, + _k, + _ref2; + m = data.length % 4; + if (m !== 0) { + for (i = _k = 0, _ref2 = 4 - m; 0 <= _ref2 ? _k < _ref2: _k > _ref2; i = 0 <= _ref2 ? ++_k: --_k) { + data += "=" + } + } + data = data.replace(/-/g, "+"); + data = data.replace(/_/g, "/"); + return base64Decode(data) + }; + parseToken = function(token) { + var head, + payload, + sig, + _ref2; + _ref2 = token.split("."), + head = _ref2[0], + payload = _ref2[1], + sig = _ref2[2]; + return JSON.parse(base64UrlDecode(payload)) + }; + Annotator.Plugin.Auth = function(_super) { + __extends(Auth, _super); + Auth.prototype.options = { + token: null, + tokenUrl: "/auth/token", + autoFetch: true + }; + function Auth(element, options) { + Auth.__super__.constructor.apply(this, arguments); + this.waitingForToken = []; + if (this.options.token) { + this.setToken(this.options.token) + } else { + this.requestToken() + } + } + Auth.prototype.requestToken = function() { + this.requestInProgress = true; + return $.ajax({ + url: this.options.tokenUrl, + dataType: "text", + xhrFields: { + withCredentials: true + } + }).done(function(_this) { + return function(data, status, xhr) { + return _this.setToken(data) + } + } (this)).fail(function(_this) { + return function(xhr, status, err) { + var msg; + msg = Annotator._t("Couldn't get auth token:"); + console.error("" + msg + " " + err, xhr); + return Annotator.showNotification("" + msg + " " + xhr.responseText, Annotator.Notification.ERROR) + } + } (this)).always(function(_this) { + return function() { + return _this.requestInProgress = false + } + } (this)) + }; + Auth.prototype.setToken = function(token) { + var _results; + this.token = token; + this._unsafeToken = parseToken(token); + if (this.haveValidToken()) { + if (this.options.autoFetch) { + this.refreshTimeout = setTimeout(function(_this) { + return function() { + return _this.requestToken() + } + } (this), (this.timeToExpiry() - 2) * 1e3) + } + this.updateHeaders(); + _results = []; + while (this.waitingForToken.length > 0) { + _results.push(this.waitingForToken.pop()(this._unsafeToken)) + } + return _results + } else { + console.warn(Annotator._t("Didn't get a valid token.")); + if (this.options.autoFetch) { + console.warn(Annotator._t("Getting a new token in 10s.")); + return setTimeout(function(_this) { + return function() { + return _this.requestToken() + } + } (this), 10 * 1e3) + } + } + }; + Auth.prototype.haveValidToken = function() { + var allFields; + allFields = this._unsafeToken && this._unsafeToken.issuedAt && this._unsafeToken.ttl && this._unsafeToken.consumerKey; + if (allFields && this.timeToExpiry() > 0) { + return true + } else { + return false + } + }; + Auth.prototype.timeToExpiry = function() { + var expiry, + issue, + now, + timeToExpiry; + now = (new Date).getTime() / 1e3; + issue = createDateFromISO8601(this._unsafeToken.issuedAt).getTime() / 1e3; + expiry = issue + this._unsafeToken.ttl; + timeToExpiry = expiry - now; + if (timeToExpiry > 0) { + return timeToExpiry + } else { + return 0 + } + }; + Auth.prototype.updateHeaders = function() { + var current; + current = this.element.data("annotator:headers"); + return this.element.data("annotator:headers", $.extend(current, { + "x-annotator-auth-token": this.token + })) + }; + Auth.prototype.withToken = function(callback) { + if (callback == null) { + return + } + if (this.haveValidToken()) { + return callback(this._unsafeToken) + } else { + this.waitingForToken.push(callback); + if (!this.requestInProgress) { + return this.requestToken() + } + } + }; + return Auth + } (Annotator.Plugin); + Annotator.Plugin.Store = function(_super) { + __extends(Store, _super); + Store.prototype.events = { + annotationCreated: "annotationCreated", + annotationDeleted: "annotationDeleted", + annotationUpdated: "annotationUpdated" + }; + Store.prototype.options = { + annotationData: {}, + emulateHTTP: false, + loadFromSearch: false, + prefix: "/store", + urls: { + create: "/annotations", + read: "/annotations/:id", + update: "/annotations/:id", + destroy: "/annotations/:id", + search: "/search" + } + }; + function Store(element, options) { + this._onError = __bind(this._onError, this); + this._onLoadAnnotationsFromSearch = __bind(this._onLoadAnnotationsFromSearch, this); + this._onLoadAnnotations = __bind(this._onLoadAnnotations, this); + this._getAnnotations = __bind(this._getAnnotations, this); + Store.__super__.constructor.apply(this, arguments); + this.annotations = [] + } + Store.prototype.pluginInit = function() { + if (!Annotator.supported()) { + return + } + if (this.annotator.plugins.Auth) { + return this.annotator.plugins.Auth.withToken(this._getAnnotations) + } else { + return this._getAnnotations() + } + }; + Store.prototype._getAnnotations = function() { + if (this.options.loadFromSearch) { + return this.loadAnnotationsFromSearch(this.options.loadFromSearch) + } else { + return this.loadAnnotations() + } + }; + Store.prototype.annotationCreated = function(annotation) { + if (__indexOf.call(this.annotations, annotation) < 0) { + this.registerAnnotation(annotation); + return this._apiRequest("create", annotation, + function(_this) { + return function(data) { + if (data.id == null) { + console.warn(Annotator._t("Warning: No ID returned from server for annotation "), annotation) + } + return _this.updateAnnotation(annotation, data) + } + } (this)) + } else { + return this.updateAnnotation(annotation, {}) + } + }; + Store.prototype.annotationUpdated = function(annotation) { + if (__indexOf.call(this.annotations, annotation) >= 0) { + return this._apiRequest("update", annotation, + function(_this) { + return function(data) { + return _this.updateAnnotation(annotation, data) + } + } (this)) + } + }; + Store.prototype.annotationDeleted = function(annotation) { + if (__indexOf.call(this.annotations, annotation) >= 0) { + return this._apiRequest("destroy", annotation, + function(_this) { + return function() { + return _this.unregisterAnnotation(annotation) + } + } (this)) + } + }; + Store.prototype.registerAnnotation = function(annotation) { + return this.annotations.push(annotation) + }; + Store.prototype.unregisterAnnotation = function(annotation) { + return this.annotations.splice(this.annotations.indexOf(annotation), 1) + }; + Store.prototype.updateAnnotation = function(annotation, data) { + if (__indexOf.call(this.annotations, annotation) < 0) { + console.error(Annotator._t("Trying to update unregistered annotation!")) + } else { + $.extend(annotation, data) + } + return $(annotation.highlights).data("annotation", annotation) + }; + Store.prototype.loadAnnotations = function() { + return this._apiRequest("read", null, this._onLoadAnnotations) + }; + Store.prototype._onLoadAnnotations = function(data) { + var a, + annotation, + annotationMap, + newData, + _k, + _l, + _len2, + _len3, + _ref2; + if (data == null) { + data = [] + } + annotationMap = {}; + _ref2 = this.annotations; + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + a = _ref2[_k]; + annotationMap[a.id] = a + } + newData = []; + for (_l = 0, _len3 = data.length; _l < _len3; _l++) { + a = data[_l]; + if (annotationMap[a.id]) { + annotation = annotationMap[a.id]; + this.updateAnnotation(annotation, a) + } else { + newData.push(a) + } + } + this.annotations = this.annotations.concat(newData); + return this.annotator.loadAnnotations(newData.slice()) + }; + Store.prototype.loadAnnotationsFromSearch = function(searchOptions) { + return this._apiRequest("search", searchOptions, this._onLoadAnnotationsFromSearch) + }; + Store.prototype._onLoadAnnotationsFromSearch = function(data) { + if (data == null) { + data = {} + } + return this._onLoadAnnotations(data.rows || []) + }; + Store.prototype.dumpAnnotations = function() { + var ann, + _k, + _len2, + _ref2, + _results; + _ref2 = this.annotations; + _results = []; + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + ann = _ref2[_k]; + _results.push(JSON.parse(this._dataFor(ann))) + } + return _results + }; + Store.prototype._apiRequest = function(action, obj, onSuccess) { + var id, + options, + request, + url; + id = obj && obj.id; + url = this._urlFor(action, id); + options = this._apiRequestOptions(action, obj, onSuccess); + request = $.ajax(url, options); + request._id = id; + request._action = action; + return request + }; + Store.prototype._apiRequestOptions = function(action, obj, onSuccess) { + var data, + method, + opts; + method = this._methodFor(action); + opts = { + type: method, + headers: this.element.data("annotator:headers"), + dataType: "json", + success: onSuccess || + function() {}, + error: this._onError + }; + if (this.options.emulateHTTP && (method === "PUT" || method === "DELETE")) { + opts.headers = $.extend(opts.headers, { + "X-HTTP-Method-Override": method + }); + opts.type = "POST" + } + if (action === "search") { + opts = $.extend(opts, { + data: obj + }); + return opts + } + data = obj && this._dataFor(obj); + if (this.options.emulateJSON) { + opts.data = { + json: data + }; + if (this.options.emulateHTTP) { + opts.data._method = method + } + return opts + } + opts = $.extend(opts, { + data: data, + contentType: "application/json; charset=utf-8" + }); + return opts + }; + Store.prototype._urlFor = function(action, id) { + var url; + url = this.options.prefix != null ? this.options.prefix: ""; + url += this.options.urls[action]; + url = url.replace(/\/:id/, id != null ? "/" + id: ""); + url = url.replace(/:id/, id != null ? id: ""); + return url + }; + Store.prototype._methodFor = function(action) { + var table; + table = { + create: "POST", + read: "GET", + update: "PUT", + destroy: "DELETE", + search: "GET" + }; + return table[action] + }; + Store.prototype._dataFor = function(annotation) { + var data, + highlights; + highlights = annotation.highlights; + delete annotation.highlights; + $.extend(annotation, this.options.annotationData); + data = JSON.stringify(annotation); + if (highlights) { + annotation.highlights = highlights + } + return data + }; + Store.prototype._onError = function(xhr) { + var action, + message; + action = xhr._action; + message = Annotator._t("Sorry we could not ") + action + Annotator._t(" this annotation"); + if (xhr._action === "search") { + message = Annotator._t("Sorry we could not search the store for annotations") + } else if (xhr._action === "read" && !xhr._id) { + message = Annotator._t("Sorry we could not ") + action + Annotator._t(" the annotations from the store") + } + switch (xhr.status) { + case 401: + message = Annotator._t("Sorry you are not allowed to ") + action + Annotator._t(" this annotation"); + break; + case 404: + message = Annotator._t("Sorry we could not connect to the annotations store"); + break; + case 500: + message = Annotator._t("Sorry something went wrong with the annotation store") + } + Annotator.showNotification(message, Annotator.Notification.ERROR); + return console.error(Annotator._t("API request failed:") + (" '" + xhr.status + "'")) + }; + return Store + } (Annotator.Plugin); + Annotator.Plugin.Permissions = function(_super) { + __extends(Permissions, _super); + Permissions.prototype.events = { + beforeAnnotationCreated: "addFieldsToAnnotation" + }; + Permissions.prototype.options = { + showViewPermissionsCheckbox: true, + showEditPermissionsCheckbox: true, + userId: function(user) { + return user + }, + userString: function(user) { + return user + }, + userAuthorize: function(action, annotation, user) { + var token, + tokens, + _k, + _len2; + if (annotation.permissions) { + tokens = annotation.permissions[action] || []; + if (tokens.length === 0) { + return true + } + for (_k = 0, _len2 = tokens.length; _k < _len2; _k++) { + token = tokens[_k]; + if (this.userId(user) === token) { + return true + } + } + return false + } else if (annotation.user) { + if (user) { + return this.userId(user) === this.userId(annotation.user) + } else { + return false + } + } + return true + }, + user: "", + permissions: { + read: [], + update: [], + "delete": [], + admin: [] + } + }; + function Permissions(element, options) { + this._setAuthFromToken = __bind(this._setAuthFromToken, this); + this.updateViewer = __bind(this.updateViewer, this); + this.updateAnnotationPermissions = __bind(this.updateAnnotationPermissions, this); + this.updatePermissionsField = __bind(this.updatePermissionsField, this); + this.addFieldsToAnnotation = __bind(this.addFieldsToAnnotation, this); + Permissions.__super__.constructor.apply(this, arguments); + if (this.options.user) { + this.setUser(this.options.user); + delete this.options.user + } + } + Permissions.prototype.pluginInit = function() { + var createCallback, + self; + if (!Annotator.supported()) { + return + } + self = this; + createCallback = function(method, type) { + return function(field, annotation) { + return self[method].call(self, type, field, annotation) + } + }; + if (!this.user && this.annotator.plugins.Auth) { + this.annotator.plugins.Auth.withToken(this._setAuthFromToken) + } + if (this.options.showViewPermissionsCheckbox === true) { + this.annotator.editor.addField({ + type: "checkbox", + label: Annotator._t("Allow anyone to view this annotation"), + load: createCallback("updatePermissionsField", "read"), + submit: createCallback("updateAnnotationPermissions", "read") + }) + } + if (this.options.showEditPermissionsCheckbox === true) { + this.annotator.editor.addField({ + type: "checkbox", + label: Annotator._t("Allow anyone to edit this annotation"), + load: createCallback("updatePermissionsField", "update"), + submit: createCallback("updateAnnotationPermissions", "update") + }) + } + this.annotator.viewer.addField({ + load: this.updateViewer + }); + if (this.annotator.plugins.Filter) { + return this.annotator.plugins.Filter.addFilter({ + label: Annotator._t("User"), + property: "user", + isFiltered: function(_this) { + return function(input, user) { + var keyword, + _k, + _len2, + _ref2; + user = _this.options.userString(user); + if (! (input && user)) { + return false + } + _ref2 = input.split(/\s*/); + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + keyword = _ref2[_k]; + if (user.indexOf(keyword) === -1) { + return false + } + } + return true + } + } (this) + }) + } + }; + Permissions.prototype.setUser = function(user) { + return this.user = user + }; + Permissions.prototype.addFieldsToAnnotation = function(annotation) { + if (annotation) { + annotation.permissions = this.options.permissions; + if (this.user) { + return annotation.user = this.user + } + } + }; + Permissions.prototype.authorize = function(action, annotation, user) { + if (user === void 0) { + user = this.user + } + if (this.options.userAuthorize) { + return this.options.userAuthorize.call(this.options, action, annotation, user) + } else { + return true + } + }; + Permissions.prototype.updatePermissionsField = function(action, field, annotation) { + var input; + field = $(field).show(); + input = field.find("input").removeAttr("disabled"); + if (!this.authorize("admin", annotation)) { + field.hide() + } + if (this.authorize(action, annotation || {}, + null)) { + return input.attr("checked", "checked") + } else { + return input.removeAttr("checked") + } + }; + Permissions.prototype.updateAnnotationPermissions = function(type, field, annotation) { + var dataKey; + if (!annotation.permissions) { + annotation.permissions = this.options.permissions + } + dataKey = type + "-permissions"; + if ($(field).find("input").is(":checked")) { + return annotation.permissions[type] = [] + } else { + return annotation.permissions[type] = [this.options.userId(this.user)] + } + }; + Permissions.prototype.updateViewer = function(field, annotation, controls) { + var user, + username; + field = $(field); + username = this.options.userString(annotation.user); + if (annotation.user && username && typeof username === "string") { + user = Annotator.Util.escape(this.options.userString(annotation.user)); + field.html(user).addClass("annotator-user") + } else { + field.remove() + } + if (controls) { + if (!this.authorize("update", annotation)) { + controls.hideEdit() + } + if (!this.authorize("delete", annotation)) { + return controls.hideDelete() + } + } + }; + Permissions.prototype._setAuthFromToken = function(token) { + return this.setUser(token.userId) + }; + return Permissions + } (Annotator.Plugin); + Annotator.Plugin.AnnotateItPermissions = function(_super) { + __extends(AnnotateItPermissions, _super); + function AnnotateItPermissions() { + this._setAuthFromToken = __bind(this._setAuthFromToken, this); + this.updateAnnotationPermissions = __bind(this.updateAnnotationPermissions, this); + this.updatePermissionsField = __bind(this.updatePermissionsField, this); + this.addFieldsToAnnotation = __bind(this.addFieldsToAnnotation, this); + return AnnotateItPermissions.__super__.constructor.apply(this, arguments) + } + AnnotateItPermissions.prototype.options = { + showViewPermissionsCheckbox: true, + showEditPermissionsCheckbox: true, + groups: { + world: "group:__world__", + authenticated: "group:__authenticated__", + consumer: "group:__consumer__" + }, + userId: function(user) { + return user.userId + }, + userString: function(user) { + return user.userId + }, + userAuthorize: function(action, annotation, user) { + var action_field, + permissions, + _ref2, + _ref3, + _ref4, + _ref5; + permissions = annotation.permissions || {}; + action_field = permissions[action] || []; + if (_ref2 = this.groups.world, __indexOf.call(action_field, _ref2) >= 0) { + return true + } else if (user != null && user.userId != null && user.consumerKey != null) { + if (user.userId === annotation.user && user.consumerKey === annotation.consumer) { + return true + } else if (_ref3 = this.groups.authenticated, __indexOf.call(action_field, _ref3) >= 0) { + return true + } else if (user.consumerKey === annotation.consumer && (_ref4 = this.groups.consumer, __indexOf.call(action_field, _ref4) >= 0)) { + return true + } else if (user.consumerKey === annotation.consumer && (_ref5 = user.userId, __indexOf.call(action_field, _ref5) >= 0)) { + return true + } else if (user.consumerKey === annotation.consumer && user.admin) { + return true + } else { + return false + } + } else { + return false + } + }, + permissions: { + read: ["group:__world__"], + update: [], + "delete": [], + admin: [] + } + }; + AnnotateItPermissions.prototype.addFieldsToAnnotation = function(annotation) { + if (annotation) { + annotation.permissions = this.options.permissions; + if (this.user) { + annotation.user = this.user.userId; + return annotation.consumer = this.user.consumerKey + } + } + }; + AnnotateItPermissions.prototype.updatePermissionsField = function(action, field, annotation) { + var input; + field = $(field).show(); + input = field.find("input").removeAttr("disabled"); + if (!this.authorize("admin", annotation)) { + field.hide() + } + if (this.user && this.authorize(action, annotation || {}, + { + userId: "__nonexistentuser__", + consumerKey: this.user.consumerKey + })) { + return input.attr("checked", "checked") + } else { + return input.removeAttr("checked") + } + }; + AnnotateItPermissions.prototype.updateAnnotationPermissions = function(type, field, annotation) { + var dataKey; + if (!annotation.permissions) { + annotation.permissions = this.options.permissions + } + dataKey = type + "-permissions"; + if ($(field).find("input").is(":checked")) { + return annotation.permissions[type] = [type === "read" ? this.options.groups.world: this.options.groups.consumer] + } else { + return annotation.permissions[type] = [] + } + }; + AnnotateItPermissions.prototype._setAuthFromToken = function(token) { + return this.setUser(token) + }; + return AnnotateItPermissions + } (Annotator.Plugin.Permissions); + Annotator.Plugin.Filter = function(_super) { + __extends(Filter, _super); + Filter.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" + }; + Filter.prototype.classes = { + active: "annotator-filter-active", + hl: { + hide: "annotator-hl-filtered", + active: "annotator-hl-active" + } + }; + Filter.prototype.html = { //Amanda: removed navigation code, changed title text + element: '
    \n ' + "\n
    ", + filter: '\n \n \n \n" + }; + Filter.prototype.options = { + appendTo: "#theannotationfilter", + filters: [], + addAnnotationFilter: true, + isFiltered: function(input, property) { + var keyword, + _k, + _len2, + _ref2; + if (! (input && property)) { + return false + } + _ref2 = input.split(/\s+/); + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + keyword = _ref2[_k]; + if (property.indexOf(keyword) === -1) { + return false + } + } + return true + } + }; + function Filter(element, options) { + this._onPreviousClick = __bind(this._onPreviousClick, this); + this._onNextClick = __bind(this._onNextClick, this); + this._onFilterKeyup = __bind(this._onFilterKeyup, this); + this._onFilterBlur = __bind(this._onFilterBlur, this); + this._onFilterFocus = __bind(this._onFilterFocus, this); + this.updateHighlights = __bind(this.updateHighlights, this); + var _base; + element = $(this.html.element).appendTo((options != null ? options.appendTo: void 0) || this.options.appendTo); + Filter.__super__.constructor.call(this, element, options); (_base = this.options).filters || (_base.filters = []); + this.filter = $(this.html.filter); + this.filters = []; + this.current = 0 + } + Filter.prototype.pluginInit = function() { + var filter, + _k, + _len2, + _ref2; + _ref2 = this.options.filters; + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + filter = _ref2[_k]; + this.addFilter(filter) + } + this.updateHighlights(); + this._setupListeners()._insertSpacer(); + if (this.options.addAnnotationFilter === true) { + return this.addFilter({ + label: Annotator._t("Annotation"), + property: "text" + }) + } + }; + Filter.prototype.destroy = function() { + var currentMargin, + html; + Filter.__super__.destroy.apply(this, arguments); + html = $("html"); + currentMargin = parseInt(html.css("padding-top"), 10) || 0; + html.css("padding-top", currentMargin - this.element.outerHeight()); + return this.element.remove() + }; + Filter.prototype._insertSpacer = function() { + var currentMargin, + html; + html = $("html"); + currentMargin = parseInt(html.css("padding-top"), 10) || 0; + html.css("padding-top", currentMargin + this.element.outerHeight()); + return this + }; + Filter.prototype._setupListeners = function() { + var event, + events, + _k, + _len2; + events = ["annotationsLoaded", "annotationCreated", "annotationUpdated", "annotationDeleted"]; + for (_k = 0, _len2 = events.length; _k < _len2; _k++) { + event = events[_k]; + this.annotator.subscribe(event, this.updateHighlights) + } + return this + }; + Filter.prototype.addFilter = function(options) { + var f, + filter; + filter = $.extend({ + label: "", + property: "", + isFiltered: this.options.isFiltered + }, + options); + if (! + function() { + var _k, + _len2, + _ref2, + _results; + _ref2 = this.filters; + _results = []; + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + f = _ref2[_k]; + if (f.property === filter.property) { + _results.push(f) + } + } + return _results + }.call(this).length) { + filter.id = "annotator-filter-" + filter.property; + filter.annotations = []; + filter.element = this.filter.clone().appendTo(this.element); + filter.element.find("label").html(filter.label).attr("for", filter.id); + filter.element.find("input").attr({ + id: filter.id, + placeholder: Annotator._t("Filter by ") + filter.label + "…" + }); + filter.element.find("button").hide(); + filter.element.data("filter", filter); + this.filters.push(filter) + } + return this + }; + Filter.prototype.updateFilter = function(filter) { + var annotation, + annotations, + input, + property, + _k, + _len2, + _ref2; + filter.annotations = []; + this.updateHighlights(); + this.resetHighlights(); + input = $.trim(filter.element.find("input").val()); + if (input) { + annotations = this.highlights.map(function() { + return $(this).data("annotation") + }); + _ref2 = $.makeArray(annotations); + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + annotation = _ref2[_k]; + property = annotation[filter.property]; + if (filter.isFiltered(input, property)) { + filter.annotations.push(annotation) + } + } + return this.filterHighlights() + } + }; + Filter.prototype.updateHighlights = function() { + this.highlights = this.annotator.element.find(".annotator-hl:visible"); + return this.filtered = this.highlights.not(this.classes.hl.hide) + }; + Filter.prototype.filterHighlights = function() { + var activeFilters, + annotation, + annotations, + filtered, + highlights, + index, + uniques, + _k, + _len2, + _ref2; + activeFilters = $.grep(this.filters, + function(filter) { + return !! filter.annotations.length + }); + filtered = ((_ref2 = activeFilters[0]) != null ? _ref2.annotations: void 0) || []; + if (activeFilters.length > 1) { + annotations = []; + $.each(activeFilters, + function() { + return $.merge(annotations, this.annotations) + }); + uniques = []; + filtered = []; + $.each(annotations, + function() { + if ($.inArray(this, uniques) === -1) { + return uniques.push(this) + } else { + return filtered.push(this) + } + }) + } + highlights = this.highlights; + for (index = _k = 0, _len2 = filtered.length; _k < _len2; index = ++_k) { + annotation = filtered[index]; + highlights = highlights.not(annotation.highlights) + } + highlights.addClass(this.classes.hl.hide); + this.filtered = this.highlights.not(this.classes.hl.hide); + return this + }; + Filter.prototype.resetHighlights = function() { + this.highlights.removeClass(this.classes.hl.hide); + this.filtered = this.highlights; + return this + }; + Filter.prototype._onFilterFocus = function(event) { + var input; + input = $(event.target); + input.parent().addClass(this.classes.active); + return input.next("button").show() + }; + Filter.prototype._onFilterBlur = function(event) { + var input; + if (!event.target.value) { + input = $(event.target); + input.parent().removeClass(this.classes.active); + return input.next("button").hide() + } + }; + Filter.prototype._onFilterKeyup = function(event) { + var filter; + filter = $(event.target).parent().data("filter"); + if (filter) { + return this.updateFilter(filter) + } + }; + Filter.prototype._findNextHighlight = function(previous) { + var active, + annotation, + current, + index, + next, + offset, + operator, + resetOffset; + if (!this.highlights.length) { + return this + } + offset = previous ? 0: -1; + resetOffset = previous ? -1: 0; + operator = previous ? "lt": "gt"; + active = this.highlights.not("." + this.classes.hl.hide); + current = active.filter("." + this.classes.hl.active); + if (!current.length) { + current = active.eq(offset) + } + annotation = current.data("annotation"); + index = active.index(current[0]); + next = active.filter(":" + operator + "(" + index + ")").not(annotation.highlights).eq(resetOffset); + if (!next.length) { + next = active.eq(resetOffset) + } + return this._scrollToHighlight(next.data("annotation").highlights) + }; + Filter.prototype._onNextClick = function(event) { + return this._findNextHighlight() + }; + Filter.prototype._onPreviousClick = function(event) { + return this._findNextHighlight(true) + }; + Filter.prototype._scrollToHighlight = function(highlight) { + highlight = $(highlight); + this.highlights.removeClass(this.classes.hl.active); + highlight.addClass(this.classes.hl.active); + return $("html, body").animate({ + scrollTop: highlight.offset().top - (this.element.height() + 20) + }, + 150) + }; + Filter.prototype._onClearClick = function(event) { + return $(event.target).prev("input").val("").keyup().blur() + }; + return Filter + } (Annotator.Plugin); + + Annotator.Plugin.Tags = function(_super) { + __extends(Tags, _super); + function Tags() { + this.setAnnotationTags = __bind(this.setAnnotationTags, this); + this.updateField = __bind(this.updateField, this); + return Tags.__super__.constructor.apply(this, arguments) + } + Tags.prototype.options = { + parseTags: function(string) { + var tags; + string = $.trim(string); + tags = []; + if (string) { + tags = string.split(/\s+/) + } + return tags + }, + stringifyTags: function(array) { + return array.join(" ") + } + }; + Tags.prototype.field = null; + Tags.prototype.input = null; + Tags.prototype.pluginInit = function() { + if (!Annotator.supported()) { + return + } + this.field = this.annotator.editor.addField({ + label: Annotator._t("Add some tags here") + "…", + load: this.updateField, + submit: this.setAnnotationTags + }); + this.annotator.viewer.addField({ + load: this.updateViewer + }); + if (this.annotator.plugins.Filter) { + this.annotator.plugins.Filter.addFilter({ + label: Annotator._t("Tag"), + property: "tags", + isFiltered: Annotator.Plugin.Tags.filterCallback + }) + } + return this.input = $(this.field).find(":input") + }; + Tags.prototype.parseTags = function(string) { + return this.options.parseTags(string) + }; + Tags.prototype.stringifyTags = function(array) { + return this.options.stringifyTags(array) + }; + Tags.prototype.updateField = function(field, annotation) { + var value; + value = ""; + if (annotation.tags) { + value = this.stringifyTags(annotation.tags) + } + return this.input.val(value) + }; + Tags.prototype.setAnnotationTags = function(field, annotation) { + return annotation.tags = this.parseTags(this.input.val()) + }; + Tags.prototype.updateViewer = function(field, annotation) { + field = $(field); + if (annotation.tags && $.isArray(annotation.tags) && annotation.tags.length) { + return field.addClass("annotator-tags").html(function() { + var string; + return string = $.map(annotation.tags, + function(tag) { + return '' + Annotator.Util.escape(tag) + "" + }).join(" ") + }) + } else { + return field.remove() + } + }; + return Tags + } (Annotator.Plugin); + Annotator.Plugin.Tags.filterCallback = function(input, tags) { + var keyword, + keywords, + matches, + tag, + _k, + _l, + _len2, + _len3; + if (tags == null) { + tags = [] + } + matches = 0; + keywords = []; + if (input) { + keywords = input.split(/\s+/g); + for (_k = 0, _len2 = keywords.length; _k < _len2; _k++) { + keyword = keywords[_k]; + if (tags.length) { + for (_l = 0, _len3 = tags.length; _l < _len3; _l++) { + tag = tags[_l]; + if (tag.indexOf(keyword) !== -1) { + matches += 1 + } + } + } + } + } + return matches === keywords.length + }; + Annotator.prototype.setupPlugins = function(config, options) { + var name, + opts, + pluginConfig, + plugins, + uri, + win, + _k, + _len2, + _results; + if (config == null) { + config = {} + } + if (options == null) { + options = {} + } + win = Annotator.Util.getGlobal(); + plugins = ["Unsupported", "Auth", "Tags", "Filter", "Store", "AnnotateItPermissions"]; + uri = win.location.href.split(/#|\?/).shift() || ""; + pluginConfig = { + Tags: {}, + Filter: { + filters: [{ + label: Annotator._t("User"), + property: "user" + }, + { + label: Annotator._t("Tags"), + property: "tags" + }] + }, + Auth: { + tokenUrl: config.tokenUrl || "http://annotateit.org/api/token" + }, + Store: { + prefix: config.storeUrl || "http://annotateit.org/api", + annotationData: { + uri: uri + }, + loadFromSearch: { + uri: uri + } + } + }; + for (name in options) { + if (!__hasProp.call(options, name)) continue; + opts = options[name]; + if (__indexOf.call(plugins, name) < 0) { + plugins.push(name) + } + } + $.extend(true, pluginConfig, options); + _results = []; + for (_k = 0, _len2 = plugins.length; _k < _len2; _k++) { + name = plugins[_k]; + if (! (name in pluginConfig) || pluginConfig[name]) { + _results.push(this.addPlugin(name, pluginConfig[name])) + } else { + _results.push(void 0) + } + } + return _results + } }.call(this); // -//# sourceMappingURL=annotator.min.map +//# sourceMappingURL=annotator-full.min.map \ No newline at end of file diff --git a/The Code/libraries/annotator/annotator.min.css b/The Code/libraries/annotator/annotator.min.css old mode 100644 new mode 100755 index 25206f8..a654143 --- a/The Code/libraries/annotator/annotator.min.css +++ b/The Code/libraries/annotator/annotator.min.css @@ -1,10 +1,7 @@ .annotator-notice,.annotator-filter *,.annotator-widget * { - font-family: "Helvetica Neue",Arial,Helvetica,sans-serif; font-weight: normal; text-align: left; - margin: 0; - padding: 0; background: 0; -webkit-transition: none; -moz-transition: none; @@ -29,7 +26,7 @@ background-repeat: no-repeat; } -.annotator-hl { background: rgba(255,255,10,0.3); } +.annotator-hl { background: rgba(255,255,10,0.3); cursor: pointer; cursor: -webkit-grab; cursor: -moz-grab;} /*Amanda*/ .annotator-hl-temporary { background: rgba(0,124,255,0.3); } .annotator-wrapper { position: relative; } .annotator-adder,.annotator-outer,.annotator-notice { z-index: 1020; } @@ -69,7 +66,7 @@ border: 0; background: 0; text-indent: -999em; - cursor: pointer; + cursor: pointer; cursor: -webkit-grab; cursor: -moz-grab; /* Amanda */ } .annotator-outer @@ -183,7 +180,7 @@ .annotator-viewer .annotator-controls button,.annotator-viewer .annotator-controls a { - cursor: pointer; + cursor: pointer; cursor: -webkit-grab; cursor: -moz-grab; /* Amanda */ display: inline-block; width: 13px; height: 13px; @@ -207,7 +204,7 @@ { top: 0; display: inline; - cursor: pointer; + cursor: pointer; cursor: -webkit-grab; cursor: -moz-grab; /* Amanda */ font-size: 12px; } @@ -277,7 +274,7 @@ padding: 0; display: inline; margin: 0 4px 0 0; - cursor: pointer; + cursor: pointer; cursor: -webkit-grab; cursor: -moz-grab; /* Amanda */ } .annotator-editor .annotator-checkbox { padding: 8px 6px; } @@ -285,18 +282,7 @@ .annotator-filter,.annotator-filter .annotator-filter-navigation button,.annotator-editor .annotator-controls { text-align: right; - padding: 3px; - border-top: 1px solid #d4d4d4; - background-color: #d4d4d4; - background-image: linear-gradient(to bottom,#f5f5f5,#dcdcdc 60%,#d2d2d2); - -webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,0.7),inset -1px 0 0 rgba(255,255,255,0.7),inset 0 1px 0 rgba(255,255,255,0.7); - -moz-box-shadow: inset 1px 0 0 rgba(255,255,255,0.7),inset -1px 0 0 rgba(255,255,255,0.7),inset 0 1px 0 rgba(255,255,255,0.7); - -o-box-shadow: inset 1px 0 0 rgba(255,255,255,0.7),inset -1px 0 0 rgba(255,255,255,0.7),inset 0 1px 0 rgba(255,255,255,0.7); - box-shadow: inset 1px 0 0 rgba(255,255,255,0.7),inset -1px 0 0 rgba(255,255,255,0.7),inset 0 1px 0 rgba(255,255,255,0.7); - -webkit-border-radius: 0 0 5px 5px; - -moz-border-radius: 0 0 5px 5px; - -o-border-radius: 0 0 5px 5px; - border-radius: 0 0 5px 5px; + padding: 5px; } .annotator-editor.annotator-invert-y .annotator-controls @@ -317,12 +303,10 @@ color: #363636; text-shadow: 0 1px 0 rgba(255,255,255,0.75); text-decoration: none; - line-height: 24px; - font-size: 12px; + font-size: 1em; font-weight: bold; border: 1px solid #a2a2a2; background-color: #d4d4d4; - background-image: linear-gradient(to bottom,#f5f5f5,#d2d2d2 50%,#bebebe 50%,#d2d2d2); -webkit-box-shadow: inset 0 0 5px rgba(255,255,255,0.2),inset 0 0 1px rgba(255,255,255,0.8); -moz-box-shadow: inset 0 0 5px rgba(255,255,255,0.2),inset 0 0 1px rgba(255,255,255,0.8); -o-box-shadow: inset 0 0 5px rgba(255,255,255,0.2),inset 0 0 1px rgba(255,255,255,0.8); @@ -454,16 +438,12 @@ .annotator-filter { - position: fixed; + top: 0; - right: 0; - left: 0; text-align: left; - line-height: 0; border: 0; - border-bottom: 1px solid #878787; - padding-left: 10px; - padding-right: 10px; + padding-left: 0px; + padding-right: 0px; -webkit-border-radius: 0; -moz-border-radius: 0; -o-border-radius: 0; @@ -476,12 +456,10 @@ .annotator-filter strong { - font-size: 12px; font-weight: bold; color: #3c3c3c; - text-shadow: 0 1px 0 rgba(255,255,255,0.7); position: relative; - top: -9px; + top: -8px; } .annotator-filter .annotator-filter-property,.annotator-filter .annotator-filter-navigation @@ -506,7 +484,9 @@ border-radius: 10px 0 0 10px; } -.annotator-filter .annotator-filter-property label { padding-left: 8px; } +.annotator-filter .annotator-filter-property label { + padding-left: 8px; +} .annotator-filter .annotator-filter-property input { @@ -516,20 +496,15 @@ border: 1px solid #878787; border-left: none; padding: 2px 4px; - line-height: 16px; - min-height: 16px; - font-size: 12px; - width: 150px; + line-height: 1em; + min-height: 1em; + width: 170px; color: #333; background-color: #f8f8f8; -webkit-border-radius: 0 10px 10px 0; -moz-border-radius: 0 10px 10px 0; -o-border-radius: 0 10px 10px 0; border-radius: 0 10px 10px 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.2); - -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.2); - -o-box-shadow: inset 0 1px 1px rgba(0,0,0,0.2); - box-shadow: inset 0 1px 1px rgba(0,0,0,0.2); } .annotator-filter .annotator-filter-property input:focus @@ -601,4 +576,15 @@ .annotator-filter .annotator-filter-navigation .annotator-filter-next:hover::after { background-position: 0 -255px; } .annotator-hl-active { background: rgba(255,255,10,0.8); } -.annotator-hl-filtered { background-color: transparent; } \ No newline at end of file +.annotator-hl-filtered { background-color: transparent; } + +.annotator-viewer { + display: none !important; + height: 0; +} + +@media screen and (-webkit-min-device-pixel-ratio:0) { +.annotator-filter .annotator-filter-property label { +line-height: 1.45em; +} +} \ No newline at end of file