var _ref; var __bind = function(fn, me) { return function() { return fn.apply(me, arguments); }; }; var __hasProp = {}.hasOwnProperty; var __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; }; Annotator.Plugin.Grouping = (function(_super) { __extends(Grouping, _super); // this plugin will have a threshold option (-1 = plugin should be removed) Grouping.prototype.options = null; // sets up the grouping structure for the plug-in function Grouping(element, options) { this.pluginInit = __bind(this.pluginInit, this); this.reloadAnnotations = __bind(this.reloadAnnotations, this); this.groupAndColor = __bind(this.groupAndColor, this); this.clearGrouping = __bind(this.clearGrouping, this); this.getPos = __bind(this.getPos, this); this.groupingButtonPressed = __bind(this.groupingButtonPressed, this); this.options = options; _ref = Grouping.__super__.constructor.apply(this, arguments); return _ref; } // instantiation of variables to be passed around below Grouping.prototype.unfilteredAnnotations = null; Grouping.prototype.groupedAnnotations = null; Grouping.prototype.groupthreshold = 0; Grouping.prototype.useGrouping = 1; /** * Gets the current position relative to the annotation wrapper * @param {HTMLElement} el Element (assumed to be within annotator-wrapper) being measured. * @return {Object} Position of element passed in using x, y coordinates */ Grouping.prototype.getPos = function(el) { // gets the offset of the element and wrapper var off = $(el).offset(); var wrapperOff = $($('.annotator-wrapper')[0]).offset(); // do height calculations from the wrapper return {x:off.left, y:off.top-wrapperOff.top}; } /** * Initializes the plugin and its attributes. */ Grouping.prototype.pluginInit = function() { // Check that annotator is working if (!Annotator.supported()) { console.log("Annotator is not supported"); return; } // makes sure that every time a change is made to annotations, the grouping is redone this.annotator.subscribe('annotationsLoaded', this.reloadAnnotations); this.annotator.subscribe('annotationUploaded', this.reloadAnnotations); this.annotator.subscribe('annotationDeleted', this.reloadAnnotations); this.annotator.subscribe('annotationCreated', this.reloadAnnotations); this.annotator.subscribe('changedTabsInCatch', this.groupingButtonPressed); // sets up the button that toggles the grouping on or off var newdiv = document.createElement('div'); var className = 'onOffGroupButton'; newdiv.setAttribute('class', className); // if the item is in public then it should default to grouping being on if (options.optionsOVA.default_tab.toLowerCase() === 'public') { newdiv.innerHTML = "Annotation Grouping: ON"; this.useGrouping = 1; // we wait for HighlightTags to complete before reloading annotations this.annotator.subscribe('colorizeCompleted', this.reloadAnnotations); } else { newdiv.innerHTML = "Annotation Grouping: OFF"; $(newdiv).addClass('buttonOff'); this.useGrouping = 0; } $($('.annotator-wrapper')[0]).prepend(newdiv); $(newdiv).click(this.groupingButtonPressed); // makes sure that if user resizes window, the annotations are regrouped var self = this; $(window).resize(function() { self.reloadAnnotations();//resize just happened, pixels changed }); }; /** * Helper function that removes all of the side buttons and sets background to yellow */ Grouping.prototype.clearGrouping = function() { $('.groupButton').remove(); $.each(this.unfilteredAnnotations, function(val) { if (val.highlights !== undefined){ $.each(val.highlights, function(high){ $(high).css("background-color", "inherit"); }); } }); } /** * Helper function that goes through and groups together annotations on the same line */ Grouping.prototype.groupAndColor = function() { annotations = this.unfilteredAnnotations; lineAnnDict = {}; var self = this; // for each annotation, if they have highlights, get the positions and add them // to a dictionary based on its initial line location annotations.forEach(function(annot) { if (annot.highlights !== undefined) { var loc = Math.round(self.getPos(annot.highlights[0]).y); if (lineAnnDict[loc] === undefined) { lineAnnDict[loc] = [annot]; return; } else { lineAnnDict[loc].push(annot); return; } } }); this.groupedAnnotations = null; this.groupedAnnotations = lineAnnDict; // Then it goes through and sets the color based on the threshold set var self = this; $.each(lineAnnDict, function(key, val) { if (val.length > self.groupthreshold) { val.forEach(function(anno){ if (anno.highlights !== undefined) { $.each(anno.highlights, function(key, anno) { $(anno).css("background-color", "inherit"); }); } }); } else { val.forEach(function(anno) { if (anno.highlights !== undefined) { $.each(anno.highlights, function(key, anno) { $(anno).css("background-color", "rgba(255, 255, 10, .3)"); }); } }); } }); } /** * Helper function that clears old groupings, regroups, and adds the side buttons. */ Grouping.prototype.reloadAnnotations = function() { var annotations = this.annotator.plugins['Store'].annotations; // clear the sidebuttons this.unfilteredAnnotations = annotations; this.clearGrouping(); if (this.useGrouping === 0) { return; } this.groupAndColor(); var self = this; // The following creates a sidebutton that is based on line location. it will // contain a number referring to the number of hidden annotations $.each(this.groupedAnnotations, function(key, val) { if (val.length > self.groupthreshold) { var newdiv = document.createElement('div'); var className = 'groupButton'; newdiv.setAttribute('class', className); $(newdiv).css('top', "" + key + "px"); newdiv.innerHTML = val.length; $(newdiv).attr('data-selected', '0'); $('.annotator-wrapper')[0].appendChild(newdiv); $(newdiv).click(function(evt){ if($(evt.srcElement).attr("data-selected") === '0') { annotations.forEach(function(annot){ if (annot.highlights !== undefined) { $.each(annot.highlights, function(key, ann) { $(ann).css("background-color", "inherit"); }); } }); self.groupedAnnotations[$(evt.srcElement).css("top").replace("px", "")].forEach(function(item) { if (item.highlights !== undefined) { $.each(item.highlights, function(key, ann) { $(ann).css("background-color", "rgba(255, 255, 10, 0.3)"); }); } }); $(evt.srcElement).attr("data-selected", '1'); } else { annotations.forEach(function(item) { $(item).css("background-color", "inherit"); }); self.groupAndColor(); $(evt.srcElement).attr("data-selected", '0'); } }); } }); var self = this; var old = self.unfilteredAnnotations.length; setTimeout(function() { if (old !== self.unfilteredAnnotations.length) { self.reloadAnnotations(); } }, 500); return; }; /** * Function activated to turn grouping on or off */ Grouping.prototype.groupingButtonPressed = function() { if(this.useGrouping === 1) { // grouping is cleared this.useGrouping = 0; this.clearGrouping(); // remove the grouping functions from being activated by events this.annotator.unsubscribe('annotationsLoaded', this.reloadAnnotations); this.annotator.unsubscribe('annotationUploaded', this.reloadAnnotations); this.annotator.unsubscribe('annotationDeleted', this.reloadAnnotations); this.annotator.unsubscribe('annotationCreated', this.reloadAnnotations); // redraw button to turn grouping on/off $(".onOffGroupButton").html("Annotation Grouping: OFF"); $(".onOffGroupButton").addClass("buttonOff"); this.annotator.plugins.Store.annotations.forEach(function(annot) { if (annot.highlights !== undefined) { $.each(annot.highlights, function(key, ann) { $(ann).css("background-color", ""); }); } }); // deals with the HighlightTags Plug-In this.annotator.publish('externalCallToHighlightTags'); this.annotator.unsubscribe('colorizeCompleted', this.reloadAnnotations); } else { // runs reload/regroup annotations this.useGrouping = 1; this.reloadAnnotations(); // subscribe again to the events triggered by annotations this.annotator.subscribe('annotationsLoaded', this.reloadAnnotations); this.annotator.subscribe('annotationUploaded', this.reloadAnnotations); this.annotator.subscribe('annotationDeleted', this.reloadAnnotations); this.annotator.subscribe('annotationCreated', this.reloadAnnotations); // redraw button to turn grouping on/off $(".onOffGroupButton").html("Annotation Grouping: ON"); $(".onOffGroupButton").removeClass("buttonOff"); this.annotator.subscribe('colorizeCompleted', this.reloadAnnotations); } } return Grouping; })(Annotator.Plugin);