diff --git a/lib/ace/document.js b/lib/ace/document.js index de9b79a8..be1563a7 100644 --- a/lib/ace/document.js +++ b/lib/ace/document.js @@ -45,14 +45,14 @@ var Selection = require("ace/selection").Selection; var TextMode = require("ace/mode/text").Mode; var Range = require("ace/range").Range; -var Document = function(text, mode) { +var NO_CHANGE_DELTAS = {}; +var Document = function(text, mode) { this.modified = true; this.lines = []; this.selection = new Selection(this); this.$breakpoints = []; this.$wrapData = []; - this.$computeWrapDataFn = this.$computeWrapData.bind(this); this.listeners = []; if (mode) { @@ -64,6 +64,9 @@ var Document = function(text, mode) { } else { this.$insert({row: 0, column: 0}, text); } + + this.$onChangeDelta = this.onChangeDelta.bind(this); + this.addEventListener("changeDelta", this.$onChangeDelta); }; @@ -511,17 +514,19 @@ var Document = function(text, mode) { args.push.apply(args, lines); this.lines.splice.apply(this.lines, args); + var nl = this.$getNewLineCharacter(); var delta = { action: "insertText", range: new Range(row, 0, row + lines.length, 0), text: lines.join(nl) + nl }; if (!fromUndo && this.$undoManager) { - var nl = this.$getNewLineCharacter(); this.$deltas.push(delta); this.$informUndoManager.schedule(); } - this._dispatchEvent("changeDelta", { data: delta }); + if (fromUndo !== NO_CHANGE_DELTAS) { + this._dispatchEvent("changeDelta", { data: delta }); + } }, this.$insert = function(position, text, fromUndo) { @@ -561,10 +566,10 @@ var Document = function(text, mode) { var lastLine = newLines[newLines.length - 1] + line.substring(position.column); this.lines[position.row] = firstLine; - this.$insertLines(position.row + 1, [lastLine], true); + this.$insertLines(position.row + 1, [lastLine], NO_CHANGE_DELTAS); if (newLines.length > 2) { - this.$insertLines(position.row + 1, newLines.slice(1, -1), true); + this.$insertLines(position.row + 1, newLines.slice(1, -1), NO_CHANGE_DELTAS); } var end = { @@ -786,14 +791,7 @@ var Document = function(text, mode) { this.setUseWrapMode = function(useWrapMode) { this.$useWrapMode = useWrapMode; - - if (useWrapMode) { - this.addEventListener("change", this.$computeWrapDataFn); - } else { - this.removeEventListener("change", this.$computeWrapDataFn); - } - - this.$computeWrapDataFn({ data: { firstRow: 0 } }); + this.$updateWrapData(0, this.lines.length - 1); this._dispatchEvent("changeWrapMode"); }; @@ -809,6 +807,44 @@ var Document = function(text, mode) { return this.$wrapLimit; }; + this.onChangeDelta = function(e) { + if (!this.$useWrapMode) { + return; + } + + var firstRow = e.data.range.start.row, + lastRow = e.data.range.end.row; + + if (firstRow != lastRow) { + var len = lastRow - firstRow; + if (e.data.action == "removeText") { + this.$wrapData.splice(firstRow, len); + lastRow = firstRow; + } else { + var args = [firstRow, 0]; + for (var i = 0; i < len; i++) args.push([]); + this.$wrapData.splice.apply(this.$wrapData, args); + } + } + + this.$updateWrapData(firstRow, lastRow); + }; + + this.$updateWrapData = function(firstRow, lastRow) { + var lines = this.lines; + var tabSize = this.getTabSize(); + var wrapData = this.$wrapData; + var wrapLimit = this.$wrapLimit; + + // Remove lines that are no longer there. + wrapData.splice(lines.length, wrapData.length - lines.length); + + for (var row = firstRow; row <= lastRow; row++) { + wrapData[row] = + this.$computeWrapSplits(lines[row], wrapLimit, tabSize); + } + }; + this.$computeWrapSplits = function(textLine, wrapLimit, tabSize) { if (textLine.length == 0) { return []; @@ -945,25 +981,6 @@ var Document = function(text, mode) { return wrapSplits; }; - this.$computeWrapData = function(e) { - var lines = this.lines; - var tabSize = this.getTabSize(); - var wrapData = this.$wrapData; - var wrapLimit = this.$wrapLimit; - - // Remove lines that are no longer there. - wrapData.splice(lines.length, wrapData.length - lines.length); - - if (!e.data.lastRow) { - e.data.lastRow = lines.length - 1; - } - - for (var row = e.data.firstRow; row <= e.data.lastRow; row++) { - wrapData[row] = - this.$computeWrapSplits(lines[row], wrapLimit, tabSize); - } - }; - this.getRowHeight = function(config, row) { var rows; if (!this.$useWrapMode) {