Manages tickmarks shown along the scrollbar track. NOT yet intended for use by anyone other than the FindReplace module. It is assumed that markers are always clear()ed when switching editors.
Tickmark markCurrent() last called on, or null if never called / called with -1.
var $markedTickmark;
function _getScrollbar(editor) {
// Be sure to select only the direct descendant, not also elements within nested inline editors
return $(editor.getRootElement()).children(".CodeMirror-vscrollbar");
}Measure scrollbar track
function _calcScaling() {
var $sb = _getScrollbar(editor);
trackHt = $sb[0].offsetHeight;
if (trackHt > 0) {
// Scrollbar visible: determine offset of track from top of scrollbar
if (brackets.platform === "win") {
trackOffset = 0; // Custom scrollbar CSS has no gap around the track
} else if (brackets.platform === "mac") {
trackOffset = 4; // Native scrollbar has padding around the track
} else { //(Linux)
trackOffset = 2; // Custom scrollbar CSS has assymmetrical gap; this approximates it
}
trackHt -= trackOffset * 2;
} else {
// No scrollbar: use the height of the entire code content
var codeContainer = $(editor.getRootElement()).find("> .CodeMirror-scroll > .CodeMirror-sizer > div > .CodeMirror-lines > div")[0];
trackHt = codeContainer.offsetHeight;
trackOffset = codeContainer.offsetTop;
}
}Add all the given tickmarks to the DOM in a batch
function _renderMarks(posArray) {
var html = "";
posArray.forEach(function (pos) {
var top = Math.round(pos.line / editor.lineCount() * trackHt) + trackOffset;
top--; // subtract ~1/2 the ht of a tickmark to center it on ideal pos
html += "<div class='tickmark' style='top:" + top + "px'></div>";
});
$(".tickmark-track", editor.getRootElement()).append($(html));
}Add tickmarks to the editor's tickmark track, if it's visible
function addTickmarks(curEditor, posArray) {
console.assert(editor === curEditor);
marks = marks.concat(posArray);
_renderMarks(posArray);
}Clear any markers in the editor's tickmark track, but leave it visible. Safe to call when tickmark track is not visible also.
function clear() {
if (editor) {
$(".tickmark-track", editor.getRootElement()).empty();
marks = [];
$markedTickmark = null;
}
} function markCurrent(index) {
// Remove previous highlight first
if ($markedTickmark) {
$markedTickmark.removeClass("tickmark-current");
$markedTickmark = null;
}
if (index !== -1) {
$markedTickmark = $(".tickmark-track > .tickmark", editor.getRootElement()).eq(index).addClass("tickmark-current");
}
}
// Private helper for unit tests
function _getTickmarks() {
return marks;
}
// For unit tests
exports._getTickmarks = _getTickmarks;
exports.clear = clear;
exports.setVisible = setVisible;
exports.addTickmarks = addTickmarks;
exports.markCurrent = markCurrent;
});Add or remove the tickmark track from the editor's UI
function setVisible(curEditor, visible) {
// short-circuit no-ops
if ((visible && curEditor === editor) || (!visible && !editor)) {
return;
}
if (visible) {
console.assert(!editor);
editor = curEditor;
// Don't support inline editors yet - search inside them is pretty screwy anyway (#2110)
if (editor.isTextSubset()) {
return;
}
var $sb = _getScrollbar(editor);
var $overlay = $("<div class='tickmark-track'></div>");
$sb.parent().append($overlay);
_calcScaling();
// Update tickmarks during editor resize (whenever resizing has paused/stopped for > 1/3 sec)
WorkspaceManager.on("workspaceUpdateLayout.ScrollTrackMarkers", _.debounce(function () {
if (marks.length) {
_calcScaling();
$(".tickmark-track", editor.getRootElement()).empty();
_renderMarks(marks);
}
}, 300));
} else {
console.assert(editor === curEditor);
$(".tickmark-track", curEditor.getRootElement()).remove();
editor = null;
marks = [];
WorkspaceManager.off("workspaceUpdateLayout.ScrollTrackMarkers");
}
}