From b8c0563d6232637c7409ee11b8cf761f51e013b6 Mon Sep 17 00:00:00 2001 From: Fabian Jakobs Date: Thu, 28 Jul 2011 16:52:00 +0200 Subject: [PATCH] fix problem with the row cache --- lib/ace/edit_session.js | 39 ++++++++++++++++++++++++++++++------ lib/ace/edit_session_test.js | 11 +++++++++- lib/ace/editor.js | 2 +- lib/ace/layer/marker.js | 25 ++++++++++++++--------- lib/ace/mode/text.js | 2 +- lib/ace/test/all_browser.js | 2 +- 6 files changed, 61 insertions(+), 20 deletions(-) diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index f9e81f81..ed8c8420 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -890,6 +890,28 @@ var EditSession = function(text, mode) { this.$clipRowToDocument = function(row) { return Math.max(0, Math.min(row, this.doc.getLength()-1)); }; + + this.$clipPositionToDocument = function(row, column) { + column = Math.max(0, column); + + if (row < 0) { + row = 0; + column = 0; + } else { + var len = this.doc.getLength(); + if (row >= len) { + row = len - 1; + column = this.doc.getLine(len-1).length; + } else { + column = Math.min(this.doc.getLine(row).length, column); + } + } + + return { + row: row, + column: column + }; + }; // WRAPMODE this.$wrapLimit = 80; @@ -1476,7 +1498,7 @@ var EditSession = function(text, mode) { docColumn += this.$getStringScreenWidth(line, screenColumn)[1]; - // clip row at the end of the documen + // clip row at the end of the document if (row + splits.length < screenRow) docColumn = Number.MAX_VALUE; @@ -1495,7 +1517,7 @@ var EditSession = function(text, mode) { if (foldLine) { return foldLine.idxToPosition(docColumn); } - + return { row: docRow, column: docColumn @@ -1504,10 +1526,15 @@ var EditSession = function(text, mode) { this.documentToScreenPosition = function(docRow, docColumn) { // Normalize the passed in arguments. - if (docColumn == null) { - docColumn = docRow.column; - docRow = docRow.row; - } + if (typeof docColumn === "undefined") + var pos = this.$clipPositionToDocument(docRow.row, docRow.column); + else + pos = this.$clipPositionToDocument(docRow, docColumn); + + docRow = pos.row; + docColumn = pos.column; + + var LL = this.$rowCache.length; var wrapData; // Special case in wrapMode if the doc is at the end of the document. diff --git a/lib/ace/edit_session_test.js b/lib/ace/edit_session_test.js index 445dc746..5d232afe 100644 --- a/lib/ace/edit_session_test.js +++ b/lib/ace/edit_session_test.js @@ -234,6 +234,13 @@ module.exports = { assert.position(session.documentToScreenPosition(0, 4), 2, 1); }, + "test: documentToScreen should clip position to the document boundaries": function() { + var session = new EditSession("foo bar\njuhu kinners"); + + assert.position(session.documentToScreenPosition(-1, 4), 0, 0); + assert.position(session.documentToScreenPosition(3, 0), 1, 12); + }, + "test: convert screen to document coordinates" : function() { var session = new EditSession("01234\t567890\t1234"); session.setTabSize(4); @@ -292,6 +299,8 @@ module.exports = { assert.position(session.screenToDocumentPosition(0, 30), 0, 7); assert.position(session.screenToDocumentPosition(2, 4), 1, 12); assert.position(session.screenToDocumentPosition(1, 30), 1, 12); + assert.position(session.screenToDocumentPosition(20, 50), 1, 12); + assert.position(session.screenToDocumentPosition(20, 5), 1, 12); }, "test: wrapLine split function" : function() { @@ -894,5 +903,5 @@ module.exports = { }); if (typeof module !== "undefined" && module === require.main) { - require("asyncjs/test").testcase(module.exports).exec() + require("asyncjs").test.testcase(module.exports).exec() } \ No newline at end of file diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 96065e92..6102864b 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -254,7 +254,7 @@ var Editor =function(renderer, session) { var pos = self.session.findMatchingBracket(self.getCursorPosition()); if (pos) { var range = new Range(pos.row, pos.column, pos.row, pos.column+1); - self.session.$bracketHighlight = self.session.addMarker(range, "ace_bracket"); + self.session.$bracketHighlight = self.session.addMarker(range, "ace_bracket", "text"); } }, 10); }; diff --git a/lib/ace/layer/marker.js b/lib/ace/layer/marker.js index 480454d8..cd57d94b 100644 --- a/lib/ace/layer/marker.js +++ b/lib/ace/layer/marker.js @@ -92,14 +92,14 @@ var Marker = function(parentEl) { } else { this.drawMultiLineMarker( html, range, marker.clazz, config, - marker.type === "background" + marker.type ); } } else { this.drawSingleLineMarker( html, range, marker.clazz, config, - null, marker.type === "background" + null, marker.type ); } } @@ -121,27 +121,27 @@ var Marker = function(parentEl) { row, range.start.column, row, this.session.getScreenLastRowColumn(row) ); - this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1); + this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1, "text"); // selection end row = range.end.row; lineRange = new Range(row, 0, row, range.end.column); - this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig); + this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 0, "text"); for (row = range.start.row + 1; row < range.end.row; row++) { lineRange.start.row = row; lineRange.end.row = row; lineRange.end.column = this.session.getScreenLastRowColumn(row); - this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1); + this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1, "text"); } }; /** * Draws a multi line marker, where lines span the full width */ - this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig, ignorePadding) { + this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig, type) { // from selection start to the end of the line - var padding = ignorePadding ? 0 : this.$padding; + var padding = type === "background" ? 0 : this.$padding; var height = layerConfig.lineHeight; var width = Math.round(layerConfig.width - (range.start.column * layerConfig.characterWidth)); var top = this.$getTop(range.start.row, layerConfig); @@ -188,10 +188,15 @@ var Marker = function(parentEl) { /** * Draws a marker which covers one single full line */ - this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig, extraLength, ignorePadding) { - var padding = ignorePadding ? 0 : this.$padding; + this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig, extraLength, type) { + var padding = type === "background" ? 0 : this.$padding; var height = layerConfig.lineHeight; - var width = Math.round((range.end.column + (extraLength || 0) - range.start.column) * layerConfig.characterWidth); + + if (type === "background") + var width = layerConfig.width; + else + width = Math.round((range.end.column + (extraLength || 0) - range.start.column) * layerConfig.characterWidth); + var top = this.$getTop(range.start.row, layerConfig); var left = Math.round( padding + range.start.column * layerConfig.characterWidth diff --git a/lib/ace/mode/text.js b/lib/ace/mode/text.js index d48f7a3d..8113ac27 100644 --- a/lib/ace/mode/text.js +++ b/lib/ace/mode/text.js @@ -140,7 +140,7 @@ var Mode = function() { var ranges = editor.$search.findAll(session); ranges.forEach(function(range) { if (!range.contains(cursor.row, cursor.column)) { - var marker = session.addMarker(range, "ace_selected_word"); + var marker = session.addMarker(range, "ace_selected_word", "text"); session.$selectionOccurrences.push(marker); } }); diff --git a/lib/ace/test/all_browser.js b/lib/ace/test/all_browser.js index 9c7c0d79..75d8465c 100644 --- a/lib/ace/test/all_browser.js +++ b/lib/ace/test/all_browser.js @@ -1,7 +1,7 @@ define(function(require, exports, module) { require("pilot/fixoldbrowsers"); -var AsyncTest = require("asyncjs/test"); +var AsyncTest = require("asyncjs").test; var async = require("asyncjs"); var dom = require("pilot/dom");