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)) {