From 30923b0b1e440bcde00b826ed14361e7e13d0eb6 Mon Sep 17 00:00:00 2001 From: Fabian Jakobs Date: Fri, 11 Feb 2011 08:09:55 +0100 Subject: [PATCH] store position as row column fields directly on the anchor and always clip position to document --- lib/ace/anchor.js | 119 +++++++++++++++++++++--------------- lib/ace/test/anchor_test.js | 9 ++- 2 files changed, 79 insertions(+), 49 deletions(-) diff --git a/lib/ace/anchor.js b/lib/ace/anchor.js index ab5946ac..ddaef873 100644 --- a/lib/ace/anchor.js +++ b/lib/ace/anchor.js @@ -46,11 +46,14 @@ var EventEmitter = require("pilot/event_emitter").EventEmitter; */ var Anchor = exports.Anchor = function(doc, row, column) { this.document = doc; - this.pos = { - row: row, - column: column - }; - doc.on("change", this.onChange.bind(this)); + + if (typeof column == "undefined") + this.setPosition(row.row, row.column) + else + this.setPosition(row, column); + + this.$onChange = this.onChange.bind(this); + doc.on("change", this.$onChange); }; (function() { @@ -58,10 +61,7 @@ var Anchor = exports.Anchor = function(doc, row, column) { oop.implement(this, EventEmitter); this.getPosition = function() { - return { - row: this.pos.row, - column: this.pos.column - }; + return this.$clipPositionToDocument(this.row, this.column); }; this.getDocument = function() { @@ -72,80 +72,103 @@ var Anchor = exports.Anchor = function(doc, row, column) { var delta = e.data; var range = delta.range; - if (range.start.row == range.end.row && range.start.row != this.pos.row) + if (range.start.row == range.end.row && range.start.row != this.row) return; - if (range.start.row > this.pos.row) + if (range.start.row > this.row) return; - if (range.start.row == this.pos.row && range.start.column > this.pos.column) + if (range.start.row == this.row && range.start.column > this.column) return; - var pos = this.getPosition(); + var row = this.row; + var column = this.column; + if (delta.action === "insertText") { - if (range.start.row === pos.row && range.start.column <= pos.column) { + if (range.start.row === row && range.start.column <= column) { if (range.start.row === range.end.row) { - pos.column += range.end.column - range.start.column; + column += range.end.column - range.start.column; } else { - pos.column -= range.start.column; - pos.row += range.end.row - range.start.row; + column -= range.start.column; + row += range.end.row - range.start.row; } } - else if (range.start.row !== range.end.row && range.start.row < pos.row) { - pos.row += range.end.row - range.start.row; + else if (range.start.row !== range.end.row && range.start.row < row) { + row += range.end.row - range.start.row; } } else if (delta.action === "insertLines") { - if (range.start.row <= pos.row) { - pos.row += range.end.row - range.start.row; + if (range.start.row <= row) { + row += range.end.row - range.start.row; } } else if (delta.action == "removeText") { - if (range.start.row == pos.row && range.start.column < pos.column) { - if (range.end.column >= pos.column) - pos.column = range.start.column; + if (range.start.row == row && range.start.column < column) { + if (range.end.column >= column) + column = range.start.column; else - pos.column = Math.max(0, pos.column - (range.end.column - range.start.column)); + column = Math.max(0, column - (range.end.column - range.start.column)); - } else if (range.start.row !== range.end.row && range.start.row < pos.row) { - if (range.end.row == pos.row) { - pos.column = Math.max(0, pos.column - range.end.column) + range.start.column; + } else if (range.start.row !== range.end.row && range.start.row < row) { + if (range.end.row == row) { + column = Math.max(0, column - range.end.column) + range.start.column; } - pos.row -= (range.end.row - range.start.row); + row -= (range.end.row - range.start.row); } - else if (range.end.row == pos.row) { - pos.row -= range.end.row - range.start.row; - pos.column = Math.max(0, pos.column - range.end.column) + range.start.column; + else if (range.end.row == row) { + row -= range.end.row - range.start.row; + column = Math.max(0, column - range.end.column) + range.start.column; } } else if (delta.action == "removeLines") { - if (range.start.row <= pos.row) { - if (range.end.row <= pos.row) - pos.row -= range.end.row - range.start.row; + if (range.start.row <= row) { + if (range.end.row <= row) + row -= range.end.row - range.start.row; else { - pos.row = range.start.row; - pos.column = 0; + row = range.start.row; + column = 0; } } } - // clip - var len = this.document.getLength(); - if (pos.row > len) { - pos.row = len - 1; - pos.column = this.document.getLine(len-1).length; - } - - this.setPosition(pos); + this.setPosition(row, column); }; - this.setPosition = function(pos) { - if (this.pos.row == pos.row && this.pos.column == pos.column) + this.setPosition = function(row, column) { + pos = this.$clipPositionToDocument(row, column); + if (this.row == row && this.column == column) return; - this.pos = pos; + this.row = row; + this.column = column; this._dispatchEvent("change"); }; + this.detach = function() { + this.document.removeEventListener("change", this.$onChange); + }; + + this.$clipPositionToDocument = function(row, column) { + var pos = {}; + + if (row >= this.document.getLength()) { + pos.row = Math.max(0, this.document.getLength() - 1); + pos.column = this.document.getLine(pos.row).length; + } + else if (row < 0) { + pos.row = 0; + pos.column = 0; + } + else { + pos.row = row; + pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column)); + } + + if (column < 0) + pos.column = 0; + + return pos; + }; + }).call(Anchor.prototype); }); diff --git a/lib/ace/test/anchor_test.js b/lib/ace/test/anchor_test.js index 1eb86287..a531fe35 100644 --- a/lib/ace/test/anchor_test.js +++ b/lib/ace/test/anchor_test.js @@ -59,6 +59,14 @@ var Test = { assert.position(anchor.getPosition(), 1, 7); }, + "test insert text at line start in same row before cursor should move anchor column": function() { + var doc = new Document("juhu\nkinners"); + var anchor = new Anchor(doc, 1, 4); + + doc.insert({row: 1, column: 0}, "//"); + assert.position(anchor.getPosition(), 1, 6); + }, + "test insert lines before cursor should move anchor row": function() { var doc = new Document("juhu\nkinners"); var anchor = new Anchor(doc, 1, 4); @@ -104,7 +112,6 @@ var Test = { var anchor = new Anchor(doc, 1, 4); doc.remove(new Range(1, 4, 1, 5)); - console.log(doc.$lines); assert.position(anchor.getPosition(), 1, 4); },