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) {
|
var Anchor = exports.Anchor = function(doc, row, column) {
|
||||||
this.document = doc;
|
this.document = doc;
|
||||||
this.pos = {
|
|
||||||
row: row,
|
if (typeof column == "undefined")
|
||||||
column: column
|
this.setPosition(row.row, row.column)
|
||||||
};
|
else
|
||||||
doc.on("change", this.onChange.bind(this));
|
this.setPosition(row, column);
|
||||||
|
|
||||||
|
this.$onChange = this.onChange.bind(this);
|
||||||
|
doc.on("change", this.$onChange);
|
||||||
};
|
};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
@ -58,10 +61,7 @@ var Anchor = exports.Anchor = function(doc, row, column) {
|
||||||
oop.implement(this, EventEmitter);
|
oop.implement(this, EventEmitter);
|
||||||
|
|
||||||
this.getPosition = function() {
|
this.getPosition = function() {
|
||||||
return {
|
return this.$clipPositionToDocument(this.row, this.column);
|
||||||
row: this.pos.row,
|
|
||||||
column: this.pos.column
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getDocument = function() {
|
this.getDocument = function() {
|
||||||
|
|
@ -72,80 +72,103 @@ var Anchor = exports.Anchor = function(doc, row, column) {
|
||||||
var delta = e.data;
|
var delta = e.data;
|
||||||
var range = delta.range;
|
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;
|
return;
|
||||||
|
|
||||||
if (range.start.row > this.pos.row)
|
if (range.start.row > this.row)
|
||||||
return;
|
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;
|
return;
|
||||||
|
|
||||||
var pos = this.getPosition();
|
var row = this.row;
|
||||||
|
var column = this.column;
|
||||||
|
|
||||||
if (delta.action === "insertText") {
|
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) {
|
if (range.start.row === range.end.row) {
|
||||||
pos.column += range.end.column - range.start.column;
|
column += range.end.column - range.start.column;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pos.column -= range.start.column;
|
column -= range.start.column;
|
||||||
pos.row += range.end.row - range.start.row;
|
row += range.end.row - range.start.row;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (range.start.row !== range.end.row && range.start.row < pos.row) {
|
else if (range.start.row !== range.end.row && range.start.row < row) {
|
||||||
pos.row += range.end.row - range.start.row;
|
row += range.end.row - range.start.row;
|
||||||
}
|
}
|
||||||
} else if (delta.action === "insertLines") {
|
} else if (delta.action === "insertLines") {
|
||||||
if (range.start.row <= pos.row) {
|
if (range.start.row <= row) {
|
||||||
pos.row += range.end.row - range.start.row;
|
row += range.end.row - range.start.row;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (delta.action == "removeText") {
|
else if (delta.action == "removeText") {
|
||||||
if (range.start.row == pos.row && range.start.column < pos.column) {
|
if (range.start.row == row && range.start.column < column) {
|
||||||
if (range.end.column >= pos.column)
|
if (range.end.column >= column)
|
||||||
pos.column = range.start.column;
|
column = range.start.column;
|
||||||
else
|
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) {
|
} else if (range.start.row !== range.end.row && range.start.row < row) {
|
||||||
if (range.end.row == pos.row) {
|
if (range.end.row == row) {
|
||||||
pos.column = Math.max(0, pos.column - range.end.column) + range.start.column;
|
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) {
|
else if (range.end.row == row) {
|
||||||
pos.row -= range.end.row - range.start.row;
|
row -= range.end.row - range.start.row;
|
||||||
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 (delta.action == "removeLines") {
|
} else if (delta.action == "removeLines") {
|
||||||
if (range.start.row <= pos.row) {
|
if (range.start.row <= row) {
|
||||||
if (range.end.row <= pos.row)
|
if (range.end.row <= row)
|
||||||
pos.row -= range.end.row - range.start.row;
|
row -= range.end.row - range.start.row;
|
||||||
else {
|
else {
|
||||||
pos.row = range.start.row;
|
row = range.start.row;
|
||||||
pos.column = 0;
|
column = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clip
|
this.setPosition(row, column);
|
||||||
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 = function(pos) {
|
this.setPosition = function(row, column) {
|
||||||
if (this.pos.row == pos.row && this.pos.column == pos.column)
|
pos = this.$clipPositionToDocument(row, column);
|
||||||
|
if (this.row == row && this.column == column)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.pos = pos;
|
this.row = row;
|
||||||
|
this.column = column;
|
||||||
this._dispatchEvent("change");
|
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);
|
}).call(Anchor.prototype);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,14 @@ var Test = {
|
||||||
assert.position(anchor.getPosition(), 1, 7);
|
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() {
|
"test insert lines before cursor should move anchor row": function() {
|
||||||
var doc = new Document("juhu\nkinners");
|
var doc = new Document("juhu\nkinners");
|
||||||
var anchor = new Anchor(doc, 1, 4);
|
var anchor = new Anchor(doc, 1, 4);
|
||||||
|
|
@ -104,7 +112,6 @@ var Test = {
|
||||||
var anchor = new Anchor(doc, 1, 4);
|
var anchor = new Anchor(doc, 1, 4);
|
||||||
|
|
||||||
doc.remove(new Range(1, 4, 1, 5));
|
doc.remove(new Range(1, 4, 1, 5));
|
||||||
console.log(doc.$lines);
|
|
||||||
assert.position(anchor.getPosition(), 1, 4);
|
assert.position(anchor.getPosition(), 1, 4);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue