update blame gutter

pull/495/head
nightwing 2018-04-12 22:33:33 +04:00
rodzic 74023713c7
commit 63b1a96b96
4 zmienionych plików z 135 dodań i 177 usunięć

Wyświetl plik

@ -7,7 +7,7 @@
position: absolute;
border-right: 1px solid black;
}
.ace_resizer_v:hover {
.ace_resizer_v:hover,.ace_resizer_v.hover {
border-right-color: darkblue;
}
.ace_closeButton {
@ -38,7 +38,9 @@
overflow: hidden !important;
padding: 0 8px;
border-top-color: rgba(230, 230, 250, 0.24);
font-family: arial
font-family: arial;
position: absolute;
width: 100%;
}
.ace_blame-cell.selected{
background: rgba(255, 237, 0, 0.31);

Wyświetl plik

@ -180,6 +180,7 @@ var BlameGutter = function(editor, blameStr) {
this.onMouseout = this.onMouseout.bind(this);
this.blameData = [];
this.$cache = [];
if (blameStr)
this.setData(blameStr);
@ -202,32 +203,24 @@ var BlameGutter = function(editor, blameStr) {
editor.blameGutter = this;
gutter.blameColumn = this;
this.element = dom.createElement("div");
this.element.className = "ace_layer ace_blame-gutter-layer";
var parentEl = editor.renderer.$gutter;
parentEl.appendChild(this.element);
this.resizer = dom.createElement("div");
this.resizer.className = "ace_resizer_v";
parentEl.appendChild(this.resizer);
this.closeButton = dom.createElement("div");
this.closeButton.className = "ace_closeButton";
this.resizer.appendChild(this.closeButton);
gutter.update = this.drawGutter;
this.editor.on("guttermousedown", this.onMousedown);
this.element = dom.buildDom(["div", {
class: "ace_layer ace_blame-gutter-layer ace_gutter"
}], editor.container);
this.resizer = dom.buildDom(["div", { class: "ace_resizer_v" },
["div", { class: "ace_closeButton" }]
], editor.container);
this.closeButton = this.resizer.firstChild;
var gutterEl = this.editor.renderer.$gutter;
event.addListener(gutterEl, "mousemove", this.onMousemove);
event.addListener(gutterEl, "mouseout", this.onMouseout);
gutter.on("afterRender", this.drawGutter);
this.element.addEventListener("mousedown", this.onMousedown);
this.resizer.addEventListener("mousedown", this.onMousedown);
gutter.element.style.width = "";
this.resizer.style.right = "40px";
this.element.style.width = "260px";
parentEl.style.width = "300px";
event.addListener(this.element, "mousemove", this.onMousemove);
event.addListener(this.element, "mouseout", this.onMouseout);
gutter.update(this.editor.renderer.layerConfig);
this.resizer.style.left =
this.element.style.width = "220px";
editor.renderer.setMargin(0, 0, 220, 0);
};
this.detachFromEditor = function() {
@ -235,26 +228,14 @@ var BlameGutter = function(editor, blameStr) {
var editor = this.editor;
var gutter = editor.renderer.$gutterLayer;
gutter.$cells.length = 0;
gutter.element.innerHTML = "";
delete gutter.update;
gutter.off("afterRender", this.drawGutter);
editor.blameGutter = gutter.blameColumn = this.editor = null;
editor.off("guttermousedown", this.onMousedown);
var gutterEl = editor.renderer.$gutter;
event.removeListener(gutterEl, "mousemove", this.onMousemove);
event.removeListener(gutterEl, "mouseout", this.onMouseout);
gutterEl.style.width = "";
editor.renderer.setMargin(0);
if (this.element.parentNode)
this.element.parentNode.removeChild(this.element);
if (this.resizer.parentNode)
this.resizer.parentNode.removeChild(this.resizer);
gutter.update(editor.renderer.layerConfig);
this.element.remove();
this.resizer.remove();
};
this.setData = function(blameStr) {
@ -279,156 +260,117 @@ var BlameGutter = function(editor, blameStr) {
this.attachToEditor(e.editor);
};
this.drawGutter = function(config) {
this.$config = config;
this.drawGutter = function(e, gutter) {
var container = gutter.blameColumn.element;
var blameData = gutter.blameColumn.blameData;
var selectedHash = gutter.blameColumn.selectedHash;
var blameEl = this.blameColumn.element;
blameEl.style.marginTop = -config.offset + "px";
var html = [];
var i = config.firstRow;
var lastRow = config.lastRow;
var fold = this.session.getNextFoldLine(i);
var foldStart = fold ? fold.start.row : Infinity;
var foldWidgets = this.$showFoldWidgets && this.session.foldWidgets;
var lineHeight = config.lineHeight;
var blameData = this.blameColumn.blameData;
var selectedText = this.selectedText;
var blameHtml = [];
var $blameIndex, lastBlameCellIndex = 0;
var blameCell;
findBlameCell(i);
if (blameCell)
addBlameCell(blameCell.text, blameCell.title);
else
addBlameCell("", "");
// adjust top margin of first cell to always keep it on screen
if (!blameData[i + 1]) {
blameHtml[$blameIndex] -= config.offset - 1;
blameHtml.splice($blameIndex + 1, 0, "px;margin-top:", config.offset - 1);
}
while (true) {
if (i > foldStart) {
i = fold.end.row + 1;
fold = this.session.getNextFoldLine(i, fold);
if (fold) {
foldStart = fold.start.row;
lastBlameCellIndex = fold.end.row;
} else {
foldStart = Infinity;
}
var cells = gutter.$lines.cells;
var cache = gutter.blameColumn.$cache;
var cacheIndex = 0;
var offset = - getTop(gutter.element) + gutter.config.offset;
var commit;
for (var i = 0; i < cells.length; i++) {
var cell = cells[i];
var row = cell.row;
var data = blameData[row];
if (!data && i == 0) {
// find first row
while (!blameData[row] && row > 0) row--;
data = blameData[row]
commit = {
row: row,
cell: cell,
data: data,
};
}
if (i > lastRow)
break;
html.push("<div class='ace_gutter-cell",
"' style='height:", lineHeight, "px;'>", (i + 1));
if (foldWidgets) {
var c = foldWidgets[i];
// check if cached value is invalidated and we need to recompute
if (c == null)
c = foldWidgets[i] = this.session.getFoldWidget(i);
if (c)
html.push(
"<span class='ace_fold-widget ace_", c,
c == "start" && i == foldStart && i < fold.end.row ? " ace_closed" : " ace_open",
"' style='height:", lineHeight, "px",
"'></span>"
);
}
var wrappedRowLength = this.session.getRowLength(i) - 1;
while (wrappedRowLength--) {
html.push("</div><div class='ace_gutter-cell' style='height:", lineHeight, "px'>\xA6");
}
html.push("</div>");
i++;
// html for blame column
findBlameCell(i);
if (blameCell)
addBlameCell(blameCell.text, blameCell.title);
else
blameHtml[$blameIndex] += this.session.getRowLength(i - 1) * lineHeight;
if (!data)
continue;
if (commit)
add(commit.data, commit.row, commit.cell, cell);
commit = {
row: row,
cell: cell,
data: data,
};
}
this.element.innerHTML = html.join("");
blameEl.innerHTML = blameHtml.join("");
this.element.style.height = config.minHeight + "px";
var gutterWidth = this.element.parentNode.offsetWidth;
if (gutterWidth !== this.gutterWidth) {
this.gutterWidth = gutterWidth;
this._emit("changeGutterWidth", gutterWidth);
if (commit.cell == cell)
add(commit.data, commit.row, commit.cell);
function add(data, row, firstCell, nextCell) {
var el = cache[cacheIndex++];
if (!el)
cache.push(el = dom.createElement("div"));
el.className = "ace_blame-cell " + (data.data.hash == selectedHash ? "selected" : "");
el.index = row;
el.textContent = data.text + " " + data.title;
var top = getTop(firstCell.element) - offset;
var next = nextCell ? getTop(nextCell.element) - offset : gutter.config.height;
el.style.top = top + "px";
el.style.height = next - top + "px";
container.appendChild(el);
}
function addBlameCell(text, title) {
blameHtml.push(
"<div class='ace_blame-cell ", text == selectedText ? "selected" : "",
"' index='", lastBlameCellIndex - 1, "'",
"style='height:", lineHeight, "px'>",
text, " ", title,
"</div>"
);
$blameIndex = blameHtml.length - 6;
}
function findBlameCell(i) {
do {
blameCell = blameData[i];
} while (!blameCell && i-- > lastBlameCellIndex);
lastBlameCellIndex = i + 1;
while (cacheIndex < cache.length) {
cache.pop().remove();
}
function getTop(element) {
return parseInt(element.style.top);
}
};
this.onMousedown = function(e) {
var target = e.domEvent.target;
var target = e.target;
if (target == this.closeButton) {
this.removeData();
return e.stop();
return event.stopEvent(e);
}
if (target == this.resizer) {
var rect = this.editor.blameGutter.element.getBoundingClientRect();
var mouseHandler = this.editor.$mouseHandler;
apf.plane.setCursor("ew-resize");
this.editor.blameGutter.resizer.classList.add("hover");
mouseHandler.resizeBlameGutter = function() {
var gutterWidth = this.x + 40 - rect.left;
this.editor.renderer.$gutter.style.width = gutterWidth + "px";
this.editor.blameGutter.element.style.width = gutterWidth - 40 + "px";
this.editor.renderer.$gutterLayer._emit("changeGutterWidth", gutterWidth);
var gutterWidth = this.x - rect.left;
this.editor.blameGutter.resizer.style.left =
this.editor.blameGutter.element.style.width = gutterWidth + "px";
this.editor.renderer.setMargin(0, 0, gutterWidth, 0);
};
mouseHandler.resizeBlameGutterEnd = function() {
apf.plane.unsetCursor();
this.editor.blameGutter.resizer.classList.remove("hover");
};
mouseHandler.setState("resizeBlameGutter");
mouseHandler.captureMouse(e, mouseHandler.resizeBlameGutter.bind(mouseHandler));
return e.stop();
return event.stopEvent(e);
}
if (dom.hasCssClass(target, "ace_blame-cell")) {
var gutter = this.editor.renderer.$gutterLayer;
var index = parseInt(target.getAttribute("index"), 10);
var blameData = gutter.blameColumn.blameData;
var blameCell = gutter.blameColumn.blameData[index];
var blameCell = blameData[target.index];
if (!blameCell)
return e.stop();
gutter.selectedText = blameCell.text;
var ch = target.parentNode.children;
for (var i = ch.length; i--;) {
var isSelected = ch[i].innerHTML.indexOf(gutter.selectedText) == 0;
ch[i].className = "ace_blame-cell" + (isSelected ? " selected" : "");
}
return e.stop();
return event.stopEvent(e);
gutter.blameColumn.selectedHash = blameCell.data.hash;
this.editor.renderer.$loop.schedule(this.editor.renderer.CHANGE_GUTTER);
return event.stopEvent(e);
}
};
this.onMousemove = function(e) {
var target = e.target;
var container = e.currentTarget;
return;
var tooltip = this.editor.tooltip;
if (this.$highlightedCell != target) {
if (dom.hasCssClass(target, "ace_blame-cell")) {
@ -439,8 +381,8 @@ var BlameGutter = function(editor, blameStr) {
}
if (this.$highlightedCell) {
// tooltip.style.top = e.clientY + 10 + "px";
// tooltip.style.left = e.clientX + 10 + "px";
tooltip.style.top = e.clientY + 10 + "px";
tooltip.style.left = e.clientX + 10 + "px";
} else {
this.onMouseout();
return;
@ -453,13 +395,6 @@ var BlameGutter = function(editor, blameStr) {
}).call(BlameGutter.prototype);
// app.vfs.execFile("git", {
// args: ["blame", "-p", "-w", "--", "server.js"]
// }, function(e, x) {
// console.log(bb=x.stdout);
// });
exports.annotate = function annotate(editor, blameStr) {
return new BlameGutter(editor, blameStr);
};

Wyświetl plik

@ -83,7 +83,7 @@ var Lines = function(element, canvasHeight) {
};
this.push = function(cell) {
if (cell.length) {
if (Array.isArray(cell)) {
this.cells.push.apply(this.cells, cell);
var fragment = dom.createFragment(this.element);
for (var i=0; i<cell.length; i++) {
@ -97,7 +97,7 @@ var Lines = function(element, canvasHeight) {
};
this.unshift = function(cell) {
if (cell.length) {
if (Array.isArray(cell)) {
this.cells.unshift.apply(this.cells, cell);
var fragment = dom.createFragment(this.element);
for (var i=0; i<cell.length; i++) {

Wyświetl plik

@ -160,6 +160,15 @@ var VirtualRenderer = function(container, theme) {
v: 0,
h: 0
};
this.margin = {
left: 0,
right: 0,
top: 0,
bottom: 0,
v: 0,
h: 0
};
this.$loop = new RenderLoop(
this.$renderChanges.bind(this),
@ -407,8 +416,8 @@ var VirtualRenderer = function(container, theme) {
this.gutterWidth = gutterWidth;
dom.setStyle(this.scrollBarH.element.style, "left", gutterWidth + "px");
dom.setStyle(this.scroller.style, "left", gutterWidth + "px");
size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBarV.getWidth());
dom.setStyle(this.scroller.style, "left", gutterWidth + this.margin.left + "px");
size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBarV.getWidth() - this.margin.h);
var right = this.scrollBarV.getWidth() + "px";
dom.setStyle(this.scrollBarH.element.style, "right", right);
@ -640,7 +649,7 @@ var VirtualRenderer = function(container, theme) {
if (posLeft > this.$size.scrollerWidth - w)
posLeft = this.$size.scrollerWidth - w;
posLeft += this.gutterWidth;
posLeft += this.gutterWidth + this.margin.left;
dom.setStyle(style, "height", h + "px");
dom.setStyle(style, "width", w + "px");
dom.translate(this.textarea, Math.min(posLeft, this.$size.scrollerWidth - w), Math.min(posTop, this.$size.height - h));
@ -715,6 +724,18 @@ var VirtualRenderer = function(container, theme) {
this.session.setScrollTop(-sm.top);
this.updateFull();
};
this.setMargin = function(top, bottom, left, right) {
var sm = this.margin;
sm.top = top|0;
sm.bottom = bottom|0;
sm.right = right|0;
sm.left = left|0;
sm.v = sm.top + sm.bottom;
sm.h = sm.left + sm.right;
this.$updateCachedSize(true, this.gutterWidth, this.$size.width, this.$size.height);
this.updateFull();
};
/**
* Returns whether the horizontal scrollbar is set to be always visible.
@ -827,7 +848,7 @@ var VirtualRenderer = function(container, theme) {
if (changes & this.CHANGE_H_SCROLL)
this.$updateScrollBarH();
dom.translate(this.$gutter, 0, -config.offset);
dom.translate(this.$gutter, this.margin.left, -config.offset);
dom.translate(this.content, -this.scrollLeft, -config.offset);
var width = config.width + 2 * this.$padding + "px";
@ -1415,7 +1436,7 @@ var VirtualRenderer = function(container, theme) {
if (this.$hasCssTransforms) {
canvasPos = {top:0, left: 0};
var p = this.$fontMetrics.transformCoordinates([x, y]);
x = p[1] - this.gutterWidth;
x = p[1] - this.gutterWidth - this.margin.left;
y = p[0];
} else {
canvasPos = this.scroller.getBoundingClientRect();
@ -1434,7 +1455,7 @@ var VirtualRenderer = function(container, theme) {
if (this.$hasCssTransforms) {
canvasPos = {top:0, left: 0};
var p = this.$fontMetrics.transformCoordinates([x, y]);
x = p[1] - this.gutterWidth;
x = p[1] - this.gutterWidth - this.margin.left;
y = p[0];
} else {
canvasPos = this.scroller.getBoundingClientRect();