Merge pull request #1416 from ajaxorg/insertlines
fix insert/removeLines at the document edges
This commit is contained in:
commit
527cb626c5
2 changed files with 38 additions and 42 deletions
|
|
@ -167,6 +167,17 @@ module.exports = {
|
||||||
});
|
});
|
||||||
|
|
||||||
doc.remove(new Range(2, 0, 2, 1));
|
doc.remove(new Range(2, 0, 2, 1));
|
||||||
|
},
|
||||||
|
|
||||||
|
"test insert/remove lines at the end of the document": function() {
|
||||||
|
var doc = new Document("juhu\nkinners\n123");
|
||||||
|
var anchor = new Anchor(doc, 2, 4);
|
||||||
|
|
||||||
|
doc.removeLines(0, 3);
|
||||||
|
assert.position(anchor.getPosition(), 0, 0);
|
||||||
|
doc.insertLines(0, ["a", "b", "c"]);
|
||||||
|
assert.position(anchor.getPosition(), 3, 0);
|
||||||
|
assert.equal(doc.getValue(), "a\nb\nc\n");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ var Document = function(text) {
|
||||||
if (text.length == 0) {
|
if (text.length == 0) {
|
||||||
this.$lines = [""];
|
this.$lines = [""];
|
||||||
} else if (Array.isArray(text)) {
|
} else if (Array.isArray(text)) {
|
||||||
this.insertLines(0, text);
|
this._insertLines(0, text);
|
||||||
} else {
|
} else {
|
||||||
this.insert({row: 0, column:0}, text);
|
this.insert({row: 0, column:0}, text);
|
||||||
}
|
}
|
||||||
|
|
@ -92,7 +92,6 @@ var Document = function(text) {
|
||||||
* @param {Number} row The row number to use
|
* @param {Number} row The row number to use
|
||||||
* @param {Number} column The column number to use
|
* @param {Number} column The column number to use
|
||||||
*
|
*
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.createAnchor = function(row, column) {
|
this.createAnchor = function(row, column) {
|
||||||
return new Anchor(this, row, column);
|
return new Anchor(this, row, column);
|
||||||
|
|
@ -105,7 +104,6 @@ var Document = function(text) {
|
||||||
* @param {String} text The text to work with
|
* @param {String} text The text to work with
|
||||||
* @returns {String} A String array, with each index containing a piece of the original `text` string.
|
* @returns {String} A String array, with each index containing a piece of the original `text` string.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
// check for IE split bug
|
// check for IE split bug
|
||||||
|
|
@ -119,14 +117,9 @@ var Document = function(text) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.$detectNewLine = function(text) {
|
this.$detectNewLine = function(text) {
|
||||||
var match = text.match(/^.*?(\r\n|\r|\n)/m);
|
var match = text.match(/^.*?(\r\n|\r|\n)/m);
|
||||||
if (match) {
|
this.$autoNewLine = match ? match[1] : "\n";
|
||||||
this.$autoNewLine = match[1];
|
|
||||||
} else {
|
|
||||||
this.$autoNewLine = "\n";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -135,18 +128,13 @@ var Document = function(text) {
|
||||||
* If `newLineMode == unix`, `\n` is returned.
|
* If `newLineMode == unix`, `\n` is returned.
|
||||||
* If `newLineMode == auto`, the value of `autoNewLine` is returned.
|
* If `newLineMode == auto`, the value of `autoNewLine` is returned.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.getNewLineCharacter = function() {
|
this.getNewLineCharacter = function() {
|
||||||
switch (this.$newLineMode) {
|
switch (this.$newLineMode) {
|
||||||
case "windows":
|
case "windows":
|
||||||
return "\r\n";
|
return "\r\n";
|
||||||
|
|
||||||
case "unix":
|
case "unix":
|
||||||
return "\n";
|
return "\n";
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return this.$autoNewLine;
|
return this.$autoNewLine;
|
||||||
}
|
}
|
||||||
|
|
@ -158,7 +146,6 @@ var Document = function(text) {
|
||||||
* [Sets the new line mode.]{: #Document.setNewLineMode.desc}
|
* [Sets the new line mode.]{: #Document.setNewLineMode.desc}
|
||||||
* @param {String} newLineMode [The newline mode to use; can be either `windows`, `unix`, or `auto`]{: #Document.setNewLineMode.param}
|
* @param {String} newLineMode [The newline mode to use; can be either `windows`, `unix`, or `auto`]{: #Document.setNewLineMode.param}
|
||||||
*
|
*
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.setNewLineMode = function(newLineMode) {
|
this.setNewLineMode = function(newLineMode) {
|
||||||
if (this.$newLineMode === newLineMode)
|
if (this.$newLineMode === newLineMode)
|
||||||
|
|
@ -179,8 +166,6 @@ var Document = function(text) {
|
||||||
* Returns `true` if `text` is a newline character (either `\r\n`, `\r`, or `\n`).
|
* Returns `true` if `text` is a newline character (either `\r\n`, `\r`, or `\n`).
|
||||||
* @param {String} text The text to check
|
* @param {String} text The text to check
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.isNewLine = function(text) {
|
this.isNewLine = function(text) {
|
||||||
return (text == "\r\n" || text == "\r" || text == "\n");
|
return (text == "\r\n" || text == "\r" || text == "\n");
|
||||||
|
|
@ -190,8 +175,6 @@ var Document = function(text) {
|
||||||
* Returns a verbatim copy of the given line as it is in the document
|
* Returns a verbatim copy of the given line as it is in the document
|
||||||
* @param {Number} row The row index to retrieve
|
* @param {Number} row The row index to retrieve
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.getLine = function(row) {
|
this.getLine = function(row) {
|
||||||
return this.$lines[row] || "";
|
return this.$lines[row] || "";
|
||||||
|
|
@ -202,8 +185,6 @@ var Document = function(text) {
|
||||||
* @param {Number} firstRow The first row index to retrieve
|
* @param {Number} firstRow The first row index to retrieve
|
||||||
* @param {Number} lastRow The final row index to retrieve
|
* @param {Number} lastRow The final row index to retrieve
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.getLines = function(firstRow, lastRow) {
|
this.getLines = function(firstRow, lastRow) {
|
||||||
return this.$lines.slice(firstRow, lastRow + 1);
|
return this.$lines.slice(firstRow, lastRow + 1);
|
||||||
|
|
@ -231,15 +212,15 @@ var Document = function(text) {
|
||||||
**/
|
**/
|
||||||
this.getTextRange = function(range) {
|
this.getTextRange = function(range) {
|
||||||
if (range.start.row == range.end.row) {
|
if (range.start.row == range.end.row) {
|
||||||
return this.$lines[range.start.row].substring(range.start.column,
|
return this.$lines[range.start.row]
|
||||||
range.end.column);
|
.substring(range.start.column, range.end.column);
|
||||||
}
|
|
||||||
else {
|
|
||||||
var lines = this.getLines(range.start.row+1, range.end.row-1);
|
|
||||||
lines.unshift((this.$lines[range.start.row] || "").substring(range.start.column));
|
|
||||||
lines.push((this.$lines[range.end.row] || "").substring(0, range.end.column));
|
|
||||||
return lines.join(this.getNewLineCharacter());
|
|
||||||
}
|
}
|
||||||
|
var lines = this.getLines(range.start.row, range.end.row);
|
||||||
|
lines[0] = (lines[0] || "").substring(range.start.column);
|
||||||
|
var l = lines.length - 1;
|
||||||
|
if (range.end.row - range.start.row == l)
|
||||||
|
lines[l] = lines[l].substring(0, range.end.column);
|
||||||
|
return lines.join(this.getNewLineCharacter());
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$clipPosition = function(position) {
|
this.$clipPosition = function(position) {
|
||||||
|
|
@ -276,7 +257,7 @@ var Document = function(text) {
|
||||||
position = this.insertInLine(position, firstLine);
|
position = this.insertInLine(position, firstLine);
|
||||||
if (lastLine !== null) {
|
if (lastLine !== null) {
|
||||||
position = this.insertNewLine(position); // terminate first line
|
position = this.insertNewLine(position); // terminate first line
|
||||||
position = this.insertLines(position.row, lines);
|
position = this._insertLines(position.row, lines);
|
||||||
position = this.insertInLine(position, lastLine || "");
|
position = this.insertInLine(position, lastLine || "");
|
||||||
}
|
}
|
||||||
return position;
|
return position;
|
||||||
|
|
@ -318,18 +299,20 @@ var Document = function(text) {
|
||||||
* {row: row, column: 0}
|
* {row: row, column: 0}
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.insertLines = function(row, lines) {
|
this.insertLines = function(row, lines) {
|
||||||
|
if (row >= this.getLength())
|
||||||
|
return this.insert({row: row, column: 0}, "\n" + lines.join("\n"));
|
||||||
|
return this._insertLines(Math.max(row, 0), lines);
|
||||||
|
};
|
||||||
|
this._insertLines = function(row, lines) {
|
||||||
if (lines.length == 0)
|
if (lines.length == 0)
|
||||||
return {row: row, column: 0};
|
return {row: row, column: 0};
|
||||||
|
|
||||||
// apply doesn't work for big arrays (smallest threshold is on safari 0xFFFF)
|
// apply doesn't work for big arrays (smallest threshold is on safari 0xFFFF)
|
||||||
// to circumvent that we have to break huge inserts into smaller chunks here
|
// to circumvent that we have to break huge inserts into smaller chunks here
|
||||||
if (lines.length > 0xFFFF) {
|
if (lines.length > 0xFFFF) {
|
||||||
var end = this.insertLines(row, lines.slice(0xFFFF));
|
var end = this._insertLines(row, lines.slice(0xFFFF));
|
||||||
lines = lines.slice(0, 0xFFFF);
|
lines = lines.slice(0, 0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -417,7 +400,6 @@ var Document = function(text) {
|
||||||
* @param {Range} range A specified Range to remove
|
* @param {Range} range A specified Range to remove
|
||||||
* @returns {Object} Returns the new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.
|
* @returns {Object} Returns the new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.remove = function(range) {
|
this.remove = function(range) {
|
||||||
// clip to document
|
// clip to document
|
||||||
|
|
@ -438,7 +420,7 @@ var Document = function(text) {
|
||||||
this.removeInLine(lastRow, 0, range.end.column);
|
this.removeInLine(lastRow, 0, range.end.column);
|
||||||
|
|
||||||
if (lastFullRow >= firstFullRow)
|
if (lastFullRow >= firstFullRow)
|
||||||
this.removeLines(firstFullRow, lastFullRow);
|
this._removeLines(firstFullRow, lastFullRow);
|
||||||
|
|
||||||
if (firstFullRow != firstRow) {
|
if (firstFullRow != firstRow) {
|
||||||
this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length);
|
this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length);
|
||||||
|
|
@ -458,7 +440,6 @@ var Document = function(text) {
|
||||||
* @param {Number} endColumn The column to stop removing at
|
* @param {Number} endColumn The column to stop removing at
|
||||||
* @returns {Object} Returns an object containing `startRow` and `startColumn`, indicating the new row and column values.<br/>If `startColumn` is equal to `endColumn`, this function returns nothing.
|
* @returns {Object} Returns an object containing `startRow` and `startColumn`, indicating the new row and column values.<br/>If `startColumn` is equal to `endColumn`, this function returns nothing.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.removeInLine = function(row, startColumn, endColumn) {
|
this.removeInLine = function(row, startColumn, endColumn) {
|
||||||
if (startColumn == endColumn)
|
if (startColumn == endColumn)
|
||||||
|
|
@ -485,9 +466,14 @@ var Document = function(text) {
|
||||||
* @param {Number} lastRow The last row to be removed
|
* @param {Number} lastRow The last row to be removed
|
||||||
* @returns {[String]} Returns all the removed lines.
|
* @returns {[String]} Returns all the removed lines.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.removeLines = function(firstRow, lastRow) {
|
this.removeLines = function(firstRow, lastRow) {
|
||||||
|
if (firstRow < 0 || lastRow >= this.getLength())
|
||||||
|
return this.remove(new Range(firstRow, 0, lastRow + 1, 0));
|
||||||
|
return this._removeLines(firstRow, lastRow);
|
||||||
|
};
|
||||||
|
|
||||||
|
this._removeLines = function(firstRow, lastRow) {
|
||||||
var range = new Range(firstRow, 0, lastRow + 1, 0);
|
var range = new Range(firstRow, 0, lastRow + 1, 0);
|
||||||
var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
|
var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
|
||||||
|
|
||||||
|
|
@ -532,7 +518,6 @@ var Document = function(text) {
|
||||||
* If the text and range are empty, this function returns an object containing the current `range.start` value.
|
* If the text and range are empty, this function returns an object containing the current `range.start` value.
|
||||||
* If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.
|
* If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
this.replace = function(range, text) {
|
this.replace = function(range, text) {
|
||||||
if (text.length == 0 && range.isEmpty())
|
if (text.length == 0 && range.isEmpty())
|
||||||
|
|
@ -567,7 +552,7 @@ var Document = function(text) {
|
||||||
else if (delta.action == "insertText")
|
else if (delta.action == "insertText")
|
||||||
this.insert(range.start, delta.text);
|
this.insert(range.start, delta.text);
|
||||||
else if (delta.action == "removeLines")
|
else if (delta.action == "removeLines")
|
||||||
this.removeLines(range.start.row, range.end.row - 1);
|
this._removeLines(range.start.row, range.end.row - 1);
|
||||||
else if (delta.action == "removeText")
|
else if (delta.action == "removeText")
|
||||||
this.remove(range);
|
this.remove(range);
|
||||||
}
|
}
|
||||||
|
|
@ -583,11 +568,11 @@ var Document = function(text) {
|
||||||
var range = Range.fromPoints(delta.range.start, delta.range.end);
|
var range = Range.fromPoints(delta.range.start, delta.range.end);
|
||||||
|
|
||||||
if (delta.action == "insertLines")
|
if (delta.action == "insertLines")
|
||||||
this.removeLines(range.start.row, range.end.row - 1);
|
this._removeLines(range.start.row, range.end.row - 1);
|
||||||
else if (delta.action == "insertText")
|
else if (delta.action == "insertText")
|
||||||
this.remove(range);
|
this.remove(range);
|
||||||
else if (delta.action == "removeLines")
|
else if (delta.action == "removeLines")
|
||||||
this.insertLines(range.start.row, delta.lines);
|
this._insertLines(range.start.row, delta.lines);
|
||||||
else if (delta.action == "removeText")
|
else if (delta.action == "removeText")
|
||||||
this.insert(range.start, delta.text);
|
this.insert(range.start, delta.text);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue