wide/static/js/lib/codemirror-5.1/addon/scroll/annotatescrollbar.js

101 lines
3.6 KiB
JavaScript
Raw Permalink Normal View History

2014-12-30 12:45:45 +03:00
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
2015-03-24 12:27:39 +03:00
CodeMirror.defineExtension("annotateScrollbar", function(options) {
if (typeof options == "string") options = {className: options};
return new Annotation(this, options);
2014-12-30 12:45:45 +03:00
});
2015-03-24 12:27:39 +03:00
CodeMirror.defineOption("scrollButtonHeight", 0);
function Annotation(cm, options) {
2014-12-30 12:45:45 +03:00
this.cm = cm;
2015-03-24 12:27:39 +03:00
this.options = options;
this.buttonHeight = options.scrollButtonHeight || cm.getOption("scrollButtonHeight");
2014-12-30 12:45:45 +03:00
this.annotations = [];
2015-03-24 12:27:39 +03:00
this.doRedraw = this.doUpdate = null;
2014-12-30 12:45:45 +03:00
this.div = cm.getWrapperElement().appendChild(document.createElement("div"));
this.div.style.cssText = "position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none";
this.computeScale();
2015-03-24 12:27:39 +03:00
function scheduleRedraw(delay) {
clearTimeout(self.doRedraw);
self.doRedraw = setTimeout(function() { self.redraw(); }, delay);
}
2014-12-30 12:45:45 +03:00
var self = this;
2015-03-24 12:27:39 +03:00
cm.on("refresh", this.resizeHandler = function() {
clearTimeout(self.doUpdate);
self.doUpdate = setTimeout(function() {
if (self.computeScale()) scheduleRedraw(20);
}, 100);
2014-12-30 12:45:45 +03:00
});
2015-03-24 12:27:39 +03:00
cm.on("markerAdded", this.resizeHandler);
cm.on("markerCleared", this.resizeHandler);
if (options.listenForChanges !== false)
cm.on("change", this.changeHandler = function() {
scheduleRedraw(250);
});
2014-12-30 12:45:45 +03:00
}
Annotation.prototype.computeScale = function() {
var cm = this.cm;
2015-03-24 12:27:39 +03:00
var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) /
2014-12-30 12:45:45 +03:00
cm.heightAtLine(cm.lastLine() + 1, "local");
if (hScale != this.hScale) {
this.hScale = hScale;
return true;
}
};
Annotation.prototype.update = function(annotations) {
this.annotations = annotations;
this.redraw();
};
2015-03-24 12:27:39 +03:00
Annotation.prototype.redraw = function(compute) {
if (compute !== false) this.computeScale();
2014-12-30 12:45:45 +03:00
var cm = this.cm, hScale = this.hScale;
var frag = document.createDocumentFragment(), anns = this.annotations;
2015-03-24 12:27:39 +03:00
if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) {
2014-12-30 12:45:45 +03:00
var ann = anns[i];
var top = nextTop || cm.charCoords(ann.from, "local").top * hScale;
var bottom = cm.charCoords(ann.to, "local").bottom * hScale;
while (i < anns.length - 1) {
nextTop = cm.charCoords(anns[i + 1].from, "local").top * hScale;
if (nextTop > bottom + .9) break;
ann = anns[++i];
bottom = cm.charCoords(ann.to, "local").bottom * hScale;
}
2015-03-24 12:27:39 +03:00
if (bottom == top) continue;
2014-12-30 12:45:45 +03:00
var height = Math.max(bottom - top, 3);
var elt = frag.appendChild(document.createElement("div"));
2015-03-24 12:27:39 +03:00
elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: "
+ (top + this.buttonHeight) + "px; height: " + height + "px";
elt.className = this.options.className;
2014-12-30 12:45:45 +03:00
}
this.div.textContent = "";
this.div.appendChild(frag);
};
Annotation.prototype.clear = function() {
this.cm.off("refresh", this.resizeHandler);
2015-03-24 12:27:39 +03:00
this.cm.off("markerAdded", this.resizeHandler);
this.cm.off("markerCleared", this.resizeHandler);
if (this.changeHandler) this.cm.off("change", this.changeHandler);
2014-12-30 12:45:45 +03:00
this.div.parentNode.removeChild(this.div);
};
});