From 63b1a96b96eaa7551448737788d76e9f5ecaf32c Mon Sep 17 00:00:00 2001 From: nightwing Date: Thu, 12 Apr 2018 22:33:33 +0400 Subject: [PATCH] update blame gutter --- plugins/c9.ide.scm/blame.css | 6 +- plugins/c9.ide.scm/blame.js | 269 +++++++----------- .../node_modules/ace/lib/ace/layer/lines.js | 4 +- .../ace/lib/ace/virtual_renderer.js | 33 ++- 4 files changed, 135 insertions(+), 177 deletions(-) diff --git a/plugins/c9.ide.scm/blame.css b/plugins/c9.ide.scm/blame.css index 891b7b9e..a4fc2485 100644 --- a/plugins/c9.ide.scm/blame.css +++ b/plugins/c9.ide.scm/blame.css @@ -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); diff --git a/plugins/c9.ide.scm/blame.js b/plugins/c9.ide.scm/blame.js index 229a0da2..15293837 100644 --- a/plugins/c9.ide.scm/blame.js +++ b/plugins/c9.ide.scm/blame.js @@ -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("
", (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( - "" - ); - } - - var wrappedRowLength = this.session.getRowLength(i) - 1; - while (wrappedRowLength--) { - html.push("
\xA6"); - } - html.push("
"); - - 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( - "
", - text, " ", title, - "
" - ); - $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); }; diff --git a/plugins/node_modules/ace/lib/ace/layer/lines.js b/plugins/node_modules/ace/lib/ace/layer/lines.js index b0b31eef..96936764 100644 --- a/plugins/node_modules/ace/lib/ace/layer/lines.js +++ b/plugins/node_modules/ace/lib/ace/layer/lines.js @@ -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 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();