lib/gollum/public/gollum/livepreview/js/ace/lib/ace/layer/gutter.js in gollum-3.1.2 vs lib/gollum/public/gollum/livepreview/js/ace/lib/ace/layer/gutter.js in gollum-3.1.3

- old
+ new

@@ -44,21 +44,24 @@ this.gutterWidth = 0; this.$annotations = []; this.$updateAnnotations = this.$updateAnnotations.bind(this); + + this.$cells = []; }; (function() { oop.implement(this, EventEmitter); this.setSession = function(session) { if (this.session) this.session.removeEventListener("change", this.$updateAnnotations); this.session = session; - session.on("change", this.$updateAnnotations); + if (session) + session.on("change", this.$updateAnnotations); }; this.addGutterDecoration = function(row, className){ if (window.console) console.warn && console.warn("deprecated use session.addGutterDecoration"); @@ -71,12 +74,11 @@ this.session.removeGutterDecoration(row, className); }; this.setAnnotations = function(annotations) { // iterate over sparse array - this.$annotations = [] - var rowInfo, row; + this.$annotations = []; for (var i = 0; i < annotations.length; i++) { var annotation = annotations[i]; var row = annotation.row; var rowInfo = this.$annotations[row]; if (!rowInfo) @@ -108,80 +110,144 @@ if (len === 0) { // do nothing } else if (delta.action == "removeText" || delta.action == "removeLines") { this.$annotations.splice(firstRow, len + 1, null); } else { - var args = Array(len + 1); + var args = new Array(len + 1); args.unshift(firstRow, 1); this.$annotations.splice.apply(this.$annotations, args); } }; this.update = function(config) { - var emptyAnno = {className: ""}; - var html = []; - var i = config.firstRow; - var lastRow = config.lastRow; - var fold = this.session.getNextFoldLine(i); + var session = this.session; + var firstRow = config.firstRow; + var lastRow = Math.min(config.lastRow + config.gutterOffset, // needed to compensate for hor scollbar + session.getLength() - 1); + var fold = session.getNextFoldLine(firstRow); var foldStart = fold ? fold.start.row : Infinity; - var foldWidgets = this.$showFoldWidgets && this.session.foldWidgets; - var breakpoints = this.session.$breakpoints; - var decorations = this.session.$decorations; + var foldWidgets = this.$showFoldWidgets && session.foldWidgets; + var breakpoints = session.$breakpoints; + var decorations = session.$decorations; + var firstLineNumber = session.$firstLineNumber; var lastLineNumber = 0; + + var gutterRenderer = session.gutterRenderer || this.$renderer; + 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 = 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( - "<div class='ace_gutter-cell ", - breakpoints[i] || "", decorations[i] || "", annotation.className, - "' style='height:", this.session.getRowLength(i) * config.lineHeight, "px;'>", - lastLineNumber = i + 1 - ); + 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 = session.getRowLength(row) * config.lineHeight + "px"; + if (height != cell.element.style.height) + cell.element.style.height = height; + 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( - "<span class='ace_fold-widget ace_", c, - c == "start" && i == foldStart && i < fold.end.row ? " ace_closed" : " ace_open", - "' style='height:", config.lineHeight, "px", - "'></span>" - ); + c = foldWidgets[row] = session.getFoldWidget(row); } - html.push("</div>"); + 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) { + cell.element.removeChild(cell.foldWidget); + cell.foldWidget = null; + } + } + + var text = lastLineNumber = gutterRenderer + ? gutterRenderer.getText(session, row) + : row + firstLineNumber; + if (text != cell.textNode.data) + cell.textNode.data = text; + + row++; } - this.element = dom.setInnerHtml(this.element, html.join("")); this.element.style.height = config.minHeight + "px"; + + if (this.$fixedWidth || session.$useWrapMode) + lastLineNumber = session.getLength() + firstLineNumber; + + var gutterWidth = gutterRenderer + ? gutterRenderer.getWidth(session, lastLineNumber, config) + : lastLineNumber.toString().length * config.characterWidth; - if (this.session.$useWrapMode) - lastLineNumber = this.session.getLength(); - - var gutterWidth = ("" + lastLineNumber).length * config.characterWidth; var padding = this.$padding || this.$computePadding(); gutterWidth += padding.left + padding.right; - if (gutterWidth !== this.gutterWidth) { + if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) { this.gutterWidth = gutterWidth; this.element.style.width = Math.ceil(this.gutterWidth) + "px"; this._emit("changeGutterWidth", gutterWidth); } }; + this.$fixedWidth = false; + + this.$showLineNumbers = true; + this.$renderer = ""; + this.setShowLineNumbers = function(show) { + this.$renderer = !show && { + getWidth: function() {return ""}, + getText: function() {return ""} + }; + }; + + this.getShowLineNumbers = function() { + return this.$showLineNumbers; + }; + this.$showFoldWidgets = true; this.setShowFoldWidgets = function(show) { if (show) dom.addCssClass(this.element, "ace_folding-enabled"); else @@ -197,12 +263,12 @@ this.$computePadding = function() { if (!this.element.firstChild) return {left: 0, right: 0}; var style = dom.computedStyle(this.element.firstChild); - this.$padding = {} - this.$padding.left = parseInt(style.paddingLeft) + 1; - this.$padding.right = parseInt(style.paddingRight); + this.$padding = {}; + this.$padding.left = parseInt(style.paddingLeft) + 1 || 0; + this.$padding.right = parseInt(style.paddingRight) || 0; return this.$padding; }; this.getRegion = function(point) { var padding = this.$padding || this.$computePadding();