Speed up single-line deltas
2e6f12725b slowed down the application of
deltas that only affect a single line. The slow-down, though trivial for
a single line, is significant for operations than separately modify
thousands of rows (such as indenting a large document).
This commit speeds up single-line deltas by avoiding unnecessary calls
to splitLine() and joinLineWithNext().
This commit is contained in:
parent
810e196cc6
commit
612478e39f
1 changed files with 47 additions and 23 deletions
|
|
@ -261,9 +261,13 @@ var Document = function(textOrLines) {
|
|||
throw errorText;
|
||||
}
|
||||
|
||||
// Validate action.
|
||||
if (delta.action != 'insert' && delta.action != 'delete')
|
||||
fnThrow('Delta action must be "insert" or "delete".');
|
||||
|
||||
// Validate lines.
|
||||
if (!delta.lines instanceof Array)
|
||||
fnThrow('Delta object lines must be an array');
|
||||
fnThrow('Delta lines must be an array');
|
||||
|
||||
// Validate range type.
|
||||
if (!delta.range instanceof Range)
|
||||
|
|
@ -567,30 +571,50 @@ var Document = function(textOrLines) {
|
|||
this.$validateDelta(delta);
|
||||
|
||||
// Apply delta.
|
||||
switch (delta.action)
|
||||
if (delta.range.start.row == delta.range.end.row)
|
||||
{
|
||||
case 'insert':
|
||||
splitLine(this.$lines, delta.range.start);
|
||||
for (var i = 0; i < delta.lines.length; i++) {
|
||||
var row = delta.range.start.row + 1 + i;
|
||||
this.$lines.splice(row, 0, delta.lines[i]);
|
||||
}
|
||||
joinLineWithNext(this.$lines, delta.range.start.row);
|
||||
joinLineWithNext(this.$lines, delta.range.end.row);
|
||||
break;
|
||||
// Apply single-line delta.
|
||||
// Note: The multi-line code below correctly handle single-line
|
||||
// deltas too, but we need to short-circuit for speed.
|
||||
var row = delta.range.start.row;
|
||||
var startColumn = delta.range.start.column;
|
||||
var endColumn = delta.range.end.column;
|
||||
var line = this.$lines[row];
|
||||
switch (delta.action) {
|
||||
|
||||
case 'insert':
|
||||
this.$lines[row] = line.substring(0, startColumn) + delta.lines[0] + line.substring(startColumn);
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
this.$lines[row] = line.substring(0, startColumn) + line.substring(endColumn);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
||||
case 'delete':
|
||||
splitLine(this.$lines, delta.range.end);
|
||||
splitLine(this.$lines, delta.range.start);
|
||||
this.$lines.splice(
|
||||
delta.range.start.row + 1, // Where to start deleting
|
||||
delta.range.end.row - delta.range.start.row + 1 // Num lines to delete.
|
||||
);
|
||||
joinLineWithNext(this.$lines, delta.range.start.row);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw 'Invalid delta type: ' + delta.action
|
||||
// Apply multi-line delta.
|
||||
switch (delta.action) {
|
||||
|
||||
case 'insert':
|
||||
splitLine(this.$lines, delta.range.start);
|
||||
for (var i = 0; i < delta.lines.length; i++) {
|
||||
var row = delta.range.start.row + 1 + i;
|
||||
this.$lines.splice(row, 0, delta.lines[i]);
|
||||
}
|
||||
joinLineWithNext(this.$lines, delta.range.start.row);
|
||||
joinLineWithNext(this.$lines, delta.range.end.row);
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
splitLine(this.$lines, delta.range.end);
|
||||
splitLine(this.$lines, delta.range.start);
|
||||
this.$lines.splice(
|
||||
delta.range.start.row + 1, // Where to start deleting
|
||||
delta.range.end.row - delta.range.start.row + 1 // Num lines to delete.
|
||||
);
|
||||
joinLineWithNext(this.$lines, delta.range.start.row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this._emit("change", { data: delta });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue