diff --git a/lib/ace/layer/gutter.js b/lib/ace/layer/gutter.js index d5d64acc..40dc71a1 100644 --- a/lib/ace/layer/gutter.js +++ b/lib/ace/layer/gutter.js @@ -46,6 +46,8 @@ var Gutter = function(parentEl) { this.$annotations = []; this.$updateAnnotations = this.$updateAnnotations.bind(this); + + this.$cells = []; }; (function() { @@ -117,11 +119,9 @@ var Gutter = function(parentEl) { }; this.update = function(config) { - var emptyAnno = {className: ""}; - var html = []; - var i = config.firstRow; + var firstRow = config.firstRow; var lastRow = config.lastRow; - var fold = this.session.getNextFoldLine(i); + var fold = this.session.getNextFoldLine(firstRow); var foldStart = fold ? fold.start.row : Infinity; var foldWidgets = this.$showFoldWidgets && this.session.foldWidgets; var breakpoints = this.session.$breakpoints; @@ -129,49 +129,90 @@ var Gutter = function(parentEl) { var firstLineNumber = this.session.$firstLineNumber; var lastLineNumber = 0; + var cell = null; + var index = -1; + var row = firstRow; while (true) { - if(i > foldStart) { - i = fold.end.row + 1; - fold = this.session.getNextFoldLine(i, fold); - foldStart = fold ?fold.start.row :Infinity; + if (row > foldStart) { + row = fold.end.row + 1; + fold = this.session.getNextFoldLine(row, fold); + foldStart = fold ? fold.start.row : Infinity; } - if(i > lastRow) + if (row > lastRow) { + while (this.$cells.length > index + 1) { + cell = this.$cells.pop(); + this.element.removeChild(cell.element); + } break; + } - var annotation = this.$annotations[i] || emptyAnno; - html.push( - "
", - lastLineNumber = i + firstLineNumber - ); + cell = this.$cells[++index]; + if (!cell) { + cell = {element: null, textNode: null, foldWidget: null}; + cell.element = dom.createElement("div"); + cell.textNode = document.createTextNode(''); + cell.element.appendChild(cell.textNode); + this.element.appendChild(cell.element); + this.$cells[index] = cell; + } + + var className = "ace_gutter-cell"; + if (breakpoints[row]) + className += breakpoints[row]; + if (decorations[row]) + className += decorations[row]; + if (this.$annotations[row]) + className += this.$annotations[row].className; + if (cell.element.className != className) + cell.element.className = className; + + var height = this.session.getRowLength(row) * config.lineHeight + "px"; + if (height != cell.element.style.height) + cell.element.style.height = height; + + var text = lastLineNumber = row + firstLineNumber; + if (text != cell.textNode.data) + cell.textNode.data = text; if (foldWidgets) { - var c = foldWidgets[i]; + var c = foldWidgets[row]; // 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( - "" - ); + c = foldWidgets[row] = this.session.getFoldWidget(row); } - html.push("
"); + if (c) { + if (!cell.foldWidget) { + cell.foldWidget = dom.createElement("span"); + cell.element.appendChild(cell.foldWidget); + } + var className = "ace_fold-widget ace_" + c; + if (c == "start" && row == foldStart && row < fold.end.row) + className += " ace_closed"; + else + className += " ace_open"; + if (cell.foldWidget.className != className) + cell.foldWidget.className = className; - i++; + var height = config.lineHeight + "px"; + if (cell.foldWidget.style.height != height) + cell.foldWidget.style.height = height; + } else { + if (cell.foldWidget != null) { + cell.element.removeChild(cell.foldWidget); + cell.foldWidget = null; + } + } + + row++; } - this.element = dom.setInnerHtml(this.element, html.join("")); this.element.style.height = config.minHeight + "px"; - + if (this.$fixedWidth || this.session.$useWrapMode) lastLineNumber = this.session.getLength(); - - var gutterWidth = ("" + lastLineNumber).length * config.characterWidth; + + var gutterWidth = lastLineNumber.toString().length * config.characterWidth; var padding = this.$padding || this.$computePadding(); gutterWidth += padding.left + padding.right; if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) {