Stop doing a line-by-line splicing in applyDelta

Also brings back the functionality where large deltas are split into
smaller deltas so that .splice.apply() calls will work.
This commit is contained in:
aldendaniels 2014-01-10 22:49:17 -06:00
commit 08edcdfc98
2 changed files with 31 additions and 6 deletions

View file

@ -79,9 +79,9 @@ function validateDelta(lines, delta) {
// TODO:
// - Validate that the ending column offset matches the lines.
// - Validate the deleted lines match the lines in the document.
// - Vaiidate that an insert delta does not contain more than 65001 entries.
}
exports.applyDelta = function(lines, delta) {
// Validate delta.
@ -114,10 +114,7 @@ exports.applyDelta = function(lines, delta) {
case 'insert':
splitLine(lines, delta.range.start);
for (var i = 0; i < delta.lines.length; i++) {
var row = delta.range.start.row + 1 + i;
lines.splice(row, 0, delta.lines[i]);
}
lines.splice.apply(lines, [delta.range.start.row + 1, 0].concat(delta.lines));
joinLineWithNext(lines, delta.range.start.row);
joinLineWithNext(lines, delta.range.end.row);
break;

View file

@ -568,8 +568,36 @@ var Document = function(textOrLines) {
* @param {Object} delta A delta object (can include 'insert' and 'remove' actions)
**/
this.applyDelta = function(delta) {
// Split large insert deltas. This is necessary because:
// 1. We need to support splicing delta lines into the document via $lines.splice.apply(...)
// 2. fn.apply() doesn't work for a large number of params. The mallest threshold is on safari 0xFFFF.
//
// To Do: Ideally we'd be consistent and also split 'delete' deltas. We don't do this now, because delete
// delta handling is too slow. If we make delete delta handling faster we can split all large deltas
// as shown in https://gist.github.com/aldendaniels/8367109#file-document-snippet-js
// If we do this, update validateDelta() to limit the number of lines in a delete delta.
var bIsInsert = delta.action == 'insert';
while (bIsInsert && delta.lines.length > 65001)
{
// Get split deltas.
var lines = delta.lines.splice(0, 65000);
lines.push('');
this.applyDelta({
action: delta.action,
lines: lines,
range: new Range(delta.range.start.row, delta.range.start.column,
delta.range.start.row + 65000, 0)
});
// Update remaining delta.
delta.range.start.row += 65000;
delta.range.start.column = 0;
}
// Apply.
applyDelta(this.$lines, delta);
this._emit("change", { data: delta });
this._emit("change", { data: delta });
};
/**