Files
edx-platform/common/static/js/vendor/ova/grouping-annotator.js

279 lines
11 KiB
JavaScript

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);