store position as row column fields directly on
the anchor and always clip position to document
This commit is contained in:
parent
5589c44225
commit
30923b0b1e
2 changed files with 79 additions and 49 deletions
|
|
@ -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);
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
},
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue