kopia lustrzana https://github.com/c9/core
allow redoing after changing the document
rodzic
9405b78dce
commit
f04f22076c
|
@ -255,7 +255,7 @@ var EditSession = function(text, mode) {
|
|||
this.$resetRowCache(delta.start.row);
|
||||
|
||||
var removedFolds = this.$updateInternalDataOnChange(delta);
|
||||
if (!this.$fromUndo && this.$undoManager && !delta.ignore) {
|
||||
if (!this.$fromUndo && this.$undoManager) {
|
||||
if (removedFolds && removedFolds.length) {
|
||||
this.$undoManager.add({
|
||||
action: "removeFolds",
|
||||
|
@ -266,13 +266,6 @@ var EditSession = function(text, mode) {
|
|||
this.$undoManager.add(delta, this);
|
||||
this.mergeUndoDeltas = true;
|
||||
|
||||
var g = this.$undoManager.lastDeltas;
|
||||
if (g && this.curOp && !this.curOp.group) {
|
||||
this.curOp.group = g;
|
||||
if (!g.selectionBefore)
|
||||
g.selectionBefore = this.curOp.selectionBefore;
|
||||
}
|
||||
|
||||
this.$informUndoManager.schedule();
|
||||
}
|
||||
|
||||
|
@ -383,6 +376,7 @@ var EditSession = function(text, mode) {
|
|||
|
||||
if (undoManager) {
|
||||
var self = this;
|
||||
undoManager.$session = this;
|
||||
this.$syncInformUndoManager = function() {
|
||||
self.$informUndoManager.cancel();
|
||||
self.mergeUndoDeltas = false;
|
||||
|
@ -406,7 +400,8 @@ var EditSession = function(text, mode) {
|
|||
redo: function() {},
|
||||
reset: function() {},
|
||||
add: function() {},
|
||||
startGroup: function() {},
|
||||
addSelection: function() {},
|
||||
startNewGroup: function() {},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1156,15 +1151,18 @@ var EditSession = function(text, mode) {
|
|||
var delta = deltas[i];
|
||||
if (delta.action == "insert" || delta.action == "remove") {
|
||||
this.doc.revertDelta(delta);
|
||||
} else {
|
||||
} else if (delta.folds) {
|
||||
this.addFolds(delta.folds);
|
||||
}
|
||||
}
|
||||
if (!dontSelect) {
|
||||
// console.log(deltas.selectionBefore + "uuu")
|
||||
if (deltas.selectionBefore)
|
||||
this.selection.fromJSON(deltas.selectionBefore);
|
||||
else
|
||||
this.selection.setRange(this.$getUndoSelection(deltas, true));
|
||||
}
|
||||
this.$fromUndo = false;
|
||||
if (deltas.selectionBefore)
|
||||
this.selection.fromJSON(deltas.selectionBefore);
|
||||
else
|
||||
this.selection.setRange(this.$getUndoSelection(deltas, true));
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1173,7 +1171,7 @@ var EditSession = function(text, mode) {
|
|||
* @param {Boolean} dontSelect {:dontSelect}
|
||||
*
|
||||
* @returns {Range}
|
||||
**/
|
||||
**/
|
||||
this.redoChanges = function(deltas, dontSelect) {
|
||||
if (!deltas.length)
|
||||
return;
|
||||
|
@ -1195,7 +1193,7 @@ var EditSession = function(text, mode) {
|
|||
/**
|
||||
* Enables or disables highlighting of the range where an undo occured.
|
||||
* @param {Boolean} enable If `true`, selects the range of the reinserted change
|
||||
*
|
||||
*
|
||||
**/
|
||||
this.setUndoSelect = function(enable) {
|
||||
this.$undoSelect = enable;
|
||||
|
@ -1214,7 +1212,7 @@ var EditSession = function(text, mode) {
|
|||
i = deltas.length - 1;
|
||||
while (!deltas[i].end && i >= 0)
|
||||
i--;
|
||||
}
|
||||
}
|
||||
var pos = isInsert(deltas[i]) ? deltas[i].end : deltas[i].start;
|
||||
return Range.fromPoints(pos, pos);
|
||||
};
|
||||
|
|
|
@ -111,21 +111,27 @@ var Editor = function(renderer, session) {
|
|||
oop.implement(this, EventEmitter);
|
||||
|
||||
this.$initOperationListeners = function() {
|
||||
function last(a) {return a[a.length - 1]}
|
||||
|
||||
this.selections = [];
|
||||
this.commands.toggleRecording();
|
||||
|
||||
this.commands.on("exec", this.startOperation.bind(this), true);
|
||||
this.commands.on("afterExec", this.endOperation.bind(this), true);
|
||||
|
||||
this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this));
|
||||
|
||||
|
||||
// todo: add before change events?
|
||||
this.on("change", function() {
|
||||
this.curOp || this.startOperation();
|
||||
if (!this.curOp) {
|
||||
this.startOperation();
|
||||
this.curOp.selectionBefore = this.$lastSel;
|
||||
}
|
||||
this.curOp.docChanged = true;
|
||||
}.bind(this), true);
|
||||
|
||||
|
||||
this.on("changeSelection", function() {
|
||||
this.curOp || this.startOperation();
|
||||
if (!this.curOp) {
|
||||
this.startOperation();
|
||||
this.curOp.selectionBefore = this.$lastSel;
|
||||
}
|
||||
this.curOp.selectionChanged = true;
|
||||
}.bind(this), true);
|
||||
};
|
||||
|
@ -150,13 +156,12 @@ var Editor = function(renderer, session) {
|
|||
scrollTop: this.renderer.scrollTop
|
||||
};
|
||||
this.curOp.selectionBefore = this.selection.toJSON();
|
||||
// this.selections.push();
|
||||
};
|
||||
|
||||
this.endOperation = function(e) {
|
||||
if (this.curOp) {
|
||||
if (e && e.returnValue === false)
|
||||
return this.curOp = null;
|
||||
return (this.curOp = null);
|
||||
this._signal("beforeEndOperation");
|
||||
var command = this.curOp.command;
|
||||
var scrollIntoView = command && command.scrollIntoView;
|
||||
|
@ -185,9 +190,12 @@ var Editor = function(renderer, session) {
|
|||
if (scrollIntoView == "animate")
|
||||
this.renderer.animateScrolling(this.curOp.scrollTop);
|
||||
}
|
||||
this.curOp.selectionAfter = this.selection.toJSON();
|
||||
if (this.curOp.group)
|
||||
this.curOp.group.selectionAfter = this.curOp.selectionAfter;
|
||||
var sel = this.selection.toJSON();
|
||||
this.curOp.selectionAfter = sel;
|
||||
this.$lastSel = this.selection.toJSON();
|
||||
|
||||
// console.log(this.$lastSel+" endOP")
|
||||
this.session.getUndoManager().addSelection(sel);
|
||||
this.prevOp = this.curOp;
|
||||
this.curOp = null;
|
||||
}
|
||||
|
|
|
@ -56,52 +56,101 @@ var UndoManager = function() {
|
|||
* @param {Object} options Contains additional properties
|
||||
*
|
||||
**/
|
||||
this.add = function(delta, doc) {
|
||||
// Normalize deltas for storage.
|
||||
// var deltaSets = this.$serializeDeltas(options.args[0]);
|
||||
|
||||
// Add deltas to undo stack.
|
||||
this.$doc = doc;
|
||||
// if (options.merge && this.hasUndo()){
|
||||
// this.dirtyCounter--;
|
||||
// deltaSets = this.$undoStack.pop().concat(deltaSets);
|
||||
// }
|
||||
if (doc.mergeUndoDeltas === false || !this.lastDeltas) {
|
||||
this.add = function(delta) {
|
||||
if (this.$session.mergeUndoDeltas === false || !this.lastDeltas) {
|
||||
this.lastDeltas = [];
|
||||
this.$undoStack.push(this.lastDeltas);
|
||||
this.$rev++;
|
||||
delta.id = this.$rev;
|
||||
}
|
||||
this.lastDeltas.push(delta);
|
||||
|
||||
// Reset redo stack.
|
||||
this.$redoStack = [];
|
||||
if (this.dirtyCounter < 0) {
|
||||
// The user has made a change after undoing past the last clean state.
|
||||
// We can never get back to a clean state now until markClean() is called.
|
||||
this.dirtyCounter = NaN;
|
||||
}
|
||||
this.dirtyCounter++;
|
||||
};
|
||||
|
||||
this.startGroup = function() {
|
||||
this.addSelection = function(selection, rev) {
|
||||
this.selections.push({
|
||||
value: selection,
|
||||
rev: rev || this.$rev
|
||||
});
|
||||
};
|
||||
|
||||
this.startNewGroup = function() {
|
||||
this.lastDeltas = null;
|
||||
return this.$rev;
|
||||
};
|
||||
|
||||
this.markIgnored = function(from, to) {
|
||||
if (to == null) to = this.$rev + 1;
|
||||
var stack = this.$undoStack;
|
||||
for (var i = stack.length; i--;) {
|
||||
var delta = stack[i][0];
|
||||
if (delta.id < to)
|
||||
delta.ignore = true;
|
||||
if (delta.id <= from)
|
||||
break;
|
||||
}
|
||||
this.lastDeltas = null;
|
||||
};
|
||||
|
||||
|
||||
this.getSelection = function(rev, after) {
|
||||
var stack = this.selections;
|
||||
for (var i = stack.length; i--;) {
|
||||
var selection = stack[i];
|
||||
if (selection.rev < rev) {
|
||||
if (after)
|
||||
selection = stack[i + 1];
|
||||
return selection;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.getRevision = function() {
|
||||
return this.$rev;
|
||||
};
|
||||
|
||||
this.getDeltas = function(from, to) {
|
||||
if (to == null) to = this.$rev + 1;
|
||||
var stack = this.$undoStack;
|
||||
var end = null, start = 0;
|
||||
for (var i = stack.length; i--;) {
|
||||
var delta = stack[i][0];
|
||||
if (delta.id < to && !end)
|
||||
end = i+1;
|
||||
if (delta.id <= from) {
|
||||
start = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return stack.slice(start, end);
|
||||
};
|
||||
|
||||
this.getChangedRanges = function(from, to) {
|
||||
|
||||
};
|
||||
|
||||
this.getChangedLines = function(from, to) {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* [Perform an undo operation on the document, reverting the last change.]{: #UndoManager.undo}
|
||||
* @param {Boolean} dontSelect {:dontSelect}
|
||||
*
|
||||
* @returns {Range} The range of the undo.
|
||||
**/
|
||||
this.undo = function() {
|
||||
this.undo = function(dontSelect) {
|
||||
this.lastDeltas = null;
|
||||
var stack = this.$undoStack;
|
||||
UndoManager.rebase(stack, stack.length);
|
||||
findDelta(stack, stack.length);
|
||||
var deltaSet = stack.pop();
|
||||
var undoSelectionRange = null;
|
||||
if (deltaSet) {
|
||||
undoSelectionRange = this.$doc.undoChanges(deltaSet);
|
||||
if (deltaSet && deltaSet.length) {
|
||||
var id = deltaSet[0].id;
|
||||
undoSelectionRange = this.$session.undoChanges(deltaSet, dontSelect);
|
||||
if (this.$redoStackBaseRev !== id) {
|
||||
this.$redoStack = [];
|
||||
}
|
||||
this.$redoStack.push(deltaSet);
|
||||
this.dirtyCounter--;
|
||||
this.$syncRev();
|
||||
}
|
||||
|
||||
return undoSelectionRange;
|
||||
|
@ -114,23 +163,39 @@ var UndoManager = function() {
|
|||
**/
|
||||
this.redo = function(dontSelect) {
|
||||
this.lastDeltas = null;
|
||||
if (this.$redoStackBaseRev != this.$rev) {
|
||||
var diff = this.getDeltas(this.$redoStackBaseRev, this.$rev + 1);
|
||||
rebaseRedoStack(this.$redoStack, diff);
|
||||
this.$redoStackBaseRev = this.$rev;
|
||||
}
|
||||
var deltaSet = this.$redoStack.pop();
|
||||
var redoSelectionRange = null;
|
||||
|
||||
if (deltaSet) {
|
||||
redoSelectionRange = this.$doc.redoChanges(deltaSet);
|
||||
redoSelectionRange = this.$session.redoChanges(deltaSet, dontSelect);
|
||||
this.$undoStack.push(deltaSet);
|
||||
this.dirtyCounter++;
|
||||
this.$syncRev();
|
||||
}
|
||||
return redoSelectionRange;
|
||||
};
|
||||
|
||||
this.$syncRev = function() {
|
||||
var stack = this.$undoStack;
|
||||
var nextDelta = stack[stack.length - 1];
|
||||
var id = nextDelta && nextDelta[0].id || 0;
|
||||
this.$redoStackBaseRev = id;
|
||||
this.$rev = id;
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroys the stack of undo and redo redo operations.
|
||||
**/
|
||||
this.reset = function() {
|
||||
this.lastDeltas = null;
|
||||
this.$undoStack = [];
|
||||
this.$redoStack = [];
|
||||
this.dirtyCounter = 0;
|
||||
this.$rev = 0;
|
||||
this.selections = [];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -164,22 +229,13 @@ var UndoManager = function() {
|
|||
return this.dirtyCounter === 0;
|
||||
};
|
||||
|
||||
// // Serializes deltaSets to reduce memory usage.
|
||||
// this.$serializeDeltas = function(deltaSets) {
|
||||
// return cloneDeltaSetsObj(deltaSets, $serializeDelta);
|
||||
// };
|
||||
|
||||
// // Deserializes deltaSets to allow application to the document.
|
||||
// this.$deserializeDeltas = function(deltaSets) {
|
||||
// return cloneDeltaSetsObj(deltaSets, $deserializeDelta);
|
||||
// };
|
||||
|
||||
}).call(UndoManager.prototype);
|
||||
|
||||
UndoManager.rebase = function(stack, pos) {
|
||||
function findDelta(stack, pos) {
|
||||
for (var i = pos; i--; ) {
|
||||
var deltaSet = stack[i];
|
||||
if (deltaSet && !deltaSet[0].disabled) {
|
||||
if (deltaSet && !deltaSet[0].ignore) {
|
||||
while(i < pos - 1) {
|
||||
var swapped = swapGroups(stack[i], stack[i + 1]);
|
||||
stack[i] = swapped[0];
|
||||
|
@ -191,7 +247,91 @@ UndoManager.rebase = function(stack, pos) {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
var Range = require("./range").Range;
|
||||
var cmp = Range.comparePoints;
|
||||
var comparePoints = Range.comparePoints;
|
||||
|
||||
function $updateMarkers(delta) {
|
||||
var isInsert = delta.action == "insert";
|
||||
var start = delta.start;
|
||||
var end = delta.end;
|
||||
var rowShift = (end.row - start.row) * (isInsert ? 1 : -1);
|
||||
var colShift = (end.column - start.column) * (isInsert ? 1 : -1);
|
||||
if (isInsert) end = start;
|
||||
|
||||
for (var i in this.marks) {
|
||||
var point = this.marks[i];
|
||||
var cmp = comparePoints(point, start);
|
||||
if (cmp < 0) {
|
||||
continue; // delta starts after the range
|
||||
}
|
||||
if (cmp === 0) {
|
||||
if (isInsert) {
|
||||
if (point.bias == 1) {
|
||||
cmp = 1;
|
||||
}
|
||||
else {
|
||||
point.bias == -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
var cmp2 = isInsert ? cmp : comparePoints(point, end);
|
||||
if (cmp2 > 0) {
|
||||
point.row += rowShift;
|
||||
point.column += point.row == end.row ? colShift : 0;
|
||||
continue;
|
||||
}
|
||||
if (!isInsert && cmp2 <= 0) {
|
||||
point.row = start.row;
|
||||
point.column = start.column;
|
||||
if (cmp2 === 0)
|
||||
point.bias = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function clonePos(pos) {
|
||||
return {row: pos.row,column: pos.column};
|
||||
}
|
||||
function cloneDelta(d) {
|
||||
return {
|
||||
start: clonePos(d.start),
|
||||
end: clonePos(d.end),
|
||||
action: d.action,
|
||||
lines: d.lines.slice()
|
||||
};
|
||||
}
|
||||
function stringifyDelta(d) {
|
||||
d = d || this;
|
||||
if (Array.isArray(d)) {
|
||||
return d.map(stringifyDelta).join("\n");
|
||||
}
|
||||
var type = "";
|
||||
if (d.action) {
|
||||
type = d.action == "insert" ? "+" : "-";
|
||||
type += "[" + d.lines + "]";
|
||||
} else if (d.value) {
|
||||
if (Array.isArray(d.value)) {
|
||||
type = d.value.map(stringifyRange).join("\n");
|
||||
} else {
|
||||
type = stringifyRange(d.value);
|
||||
}
|
||||
}
|
||||
if (d.start) {
|
||||
type += stringifyRange(d);
|
||||
}
|
||||
if (d.id || d.rev) {
|
||||
type += "\t(" + (d.id || d.rev) + ")";
|
||||
}
|
||||
return type;
|
||||
}
|
||||
function stringifyRange(r) {
|
||||
return r.start.row + ":" + r.start.column
|
||||
+ "=>" + r.end.row + ":" + r.end.column;
|
||||
}
|
||||
/*
|
||||
* i i d1 d2
|
||||
* |/ |/ d2.s >= d1.e shift(d2, d1, -1)
|
||||
|
@ -213,8 +353,7 @@ UndoManager.rebase = function(stack, pos) {
|
|||
* d2.e <= d1.s shift(d1, d2, -1)
|
||||
* d2.s < d1.s < d2.e // can split
|
||||
*/
|
||||
var Range = require("./range").Range;
|
||||
var cmp = Range.comparePoints;
|
||||
|
||||
function swap(d1, d2) {
|
||||
var i1 = d1.action == "insert";
|
||||
var i2 = d2.action == "insert";
|
||||
|
@ -253,36 +392,6 @@ function swap(d1, d2) {
|
|||
}
|
||||
}
|
||||
return [d2, d1];
|
||||
|
||||
function shift(d1, d2, dir) {
|
||||
shiftPos(d1.start, d2.start, d2.end, dir);
|
||||
shiftPos(d1.end, d2.start, d2.end, dir);
|
||||
}
|
||||
function shiftPos(pos, start, end, dir) {
|
||||
if (pos.row == (dir == 1 ? start : end).row) {
|
||||
pos.column += dir * (end.column - start.column);
|
||||
}
|
||||
pos.row += dir * (end.row - start.row);
|
||||
}
|
||||
}
|
||||
function clonePos(pos) {
|
||||
return {row: pos.row,column: pos.column};
|
||||
}
|
||||
function cloneDelta(d) {
|
||||
return {
|
||||
start: clonePos(d.start),
|
||||
end: clonePos(d.end),
|
||||
action: d.action,
|
||||
lines: d.lines.slice(),
|
||||
toString: logDelta
|
||||
};
|
||||
}
|
||||
function logDelta(d) {
|
||||
d = d || this;
|
||||
var type = d.action == "insert" ? "+" : "-";
|
||||
return type + "[" + d.lines + "]"
|
||||
+ d.start.row + ":" + d.start.column + "=>"
|
||||
+ d.end.row + ":" + d.end.column;
|
||||
}
|
||||
function swapGroups(ds1, ds2) {
|
||||
for (var i = ds1.length; i--; ) {
|
||||
|
@ -305,6 +414,129 @@ function swapGroups(ds1, ds2) {
|
|||
return [ds2, ds1];
|
||||
}
|
||||
|
||||
/*
|
||||
d2 xform(d1, c1) = [d2, c2]
|
||||
o<---o xform(c1, d1) = [c2, d2]
|
||||
c2 | | d1
|
||||
o<---o
|
||||
c1
|
||||
*/
|
||||
function xform(d1, c1) {
|
||||
var i1 = d1.action == "insert";
|
||||
var i2 = c1.action == "insert";
|
||||
|
||||
if (i1 && i2) {
|
||||
if (cmp(d1.start, c1.start) < 0) {
|
||||
shift(c1, d1, 1);
|
||||
} else {
|
||||
shift(d1, c1, 1);
|
||||
}
|
||||
} else if (i1 && !i2) {
|
||||
if (cmp(d1.start, c1.end) >= 0) {
|
||||
shift(d1, c1, -1);
|
||||
} else if (cmp(d1.start, c1.start) <= 0) {
|
||||
shift(c1, d1, +1);
|
||||
} else {
|
||||
shift(d1, Range.fromPoints(c1.start, d1.start), -1);
|
||||
shift(c1, d1, +1);
|
||||
}
|
||||
} else if (!i1 && i2) {
|
||||
if (cmp(c1.start, d1.end) >= 0) {
|
||||
shift(c1, d1, -1);
|
||||
} else if (cmp(c1.start, d1.start) <= 0) {
|
||||
shift(d1, c1, +1);
|
||||
} else {
|
||||
shift(c1, Range.fromPoints(d1.start, c1.start), -1);
|
||||
shift(d1, c1, +1);
|
||||
}
|
||||
} else if (!i1 && !i2) {
|
||||
if (cmp(c1.start, d1.end) >= 0) {
|
||||
shift(c1, d1, -1);
|
||||
} else if (cmp(c1.end, d1.start) <= 0) {
|
||||
shift(d1, c1, -1);
|
||||
} else {
|
||||
var before, after;
|
||||
if (cmp(d1.start, c1.start) < 0) {
|
||||
before = d1;
|
||||
d1 = splitDelta(d1, c1.start);
|
||||
}
|
||||
if (cmp(d1.end, c1.end) > 0) {
|
||||
after = splitDelta(d1, c1.end);
|
||||
}
|
||||
|
||||
shiftPos(c1.end, d1.start, d1.end, -1);
|
||||
if (after && !before) {
|
||||
d1.lines = after.lines;
|
||||
d1.start = after.start;
|
||||
d1.end = after.end;
|
||||
after = d1;
|
||||
}
|
||||
|
||||
return [c1, before, after].filter(Boolean);
|
||||
}
|
||||
}
|
||||
return [c1, d1];
|
||||
}
|
||||
|
||||
function shift(d1, d2, dir) {
|
||||
shiftPos(d1.start, d2.start, d2.end, dir);
|
||||
shiftPos(d1.end, d2.start, d2.end, dir);
|
||||
}
|
||||
function shiftPos(pos, start, end, dir) {
|
||||
if (pos.row == (dir == 1 ? start : end).row) {
|
||||
pos.column += dir * (end.column - start.column);
|
||||
}
|
||||
pos.row += dir * (end.row - start.row);
|
||||
}
|
||||
function splitDelta(c, pos) {
|
||||
var lines = c.lines;
|
||||
var end = c.end;
|
||||
c.end = clonePos(pos);
|
||||
var rowsBefore = c.end.row - c.start.row;
|
||||
var otherLines = lines.splice(rowsBefore, lines.length);
|
||||
|
||||
var col = rowsBefore ? pos.column : pos.column - c.start.column;
|
||||
lines.push(otherLines[0].substring(0, col));
|
||||
otherLines[0] = otherLines[0].substr(col) ;
|
||||
var rest = {
|
||||
start: clonePos(pos),
|
||||
end: end,
|
||||
lines: otherLines,
|
||||
action: c.action
|
||||
};
|
||||
return rest;
|
||||
}
|
||||
|
||||
function moveDeltasByOne(redoStack, d) {
|
||||
d = cloneDelta(d);
|
||||
for (var j = redoStack.length; j--;) {
|
||||
var deltaSet = redoStack[j];
|
||||
for (var i = deltaSet.length; i--;) {
|
||||
var x = deltaSet[i];
|
||||
var xformed = xform(x, d);
|
||||
d = xformed[0];
|
||||
if (xformed.length != 2) {
|
||||
if (xformed[2]) {
|
||||
redoStack.splice(i + 1, 1, xformed[1], xformed[2]);
|
||||
i++;
|
||||
} else if (!xformed[1]) {
|
||||
redoStack.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return redoStack;
|
||||
}
|
||||
function rebaseRedoStack(redoStack, deltaSets) {
|
||||
for (var i = 0; i < deltaSets.length; i++) {
|
||||
var deltas = deltaSets[i];
|
||||
for (var j = 0; j < deltas.length; j++) {
|
||||
moveDeltasByOne(redoStack, deltas[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UndoManager.swapGroups = swapGroups;
|
||||
exports.UndoManager = UndoManager;
|
||||
});
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
"c9.ide.language.javascript.tern": "#7aab8b0b6a",
|
||||
"c9.ide.language.javascript.infer": "#cfec494a3c",
|
||||
"c9.ide.language.jsonalyzer": "#21b64e5820",
|
||||
"c9.ide.collab": "#749c26b859",
|
||||
"c9.ide.collab": "#da4d09ae6a",
|
||||
"c9.ide.local": "#2bfd7ff051",
|
||||
"c9.ide.find": "#6cc6d3379d",
|
||||
"c9.ide.find.infiles": "#72582de3cd",
|
||||
|
|
Ładowanie…
Reference in New Issue