kopia lustrzana https://github.com/c9/core
use same undo manager for multiple sessions
rodzic
8312d3d5ac
commit
3644d203c2
|
@ -132,7 +132,6 @@ var SearchHighlight = require("./search_highlight").SearchHighlight;
|
|||
//}
|
||||
|
||||
/**
|
||||
*
|
||||
* Sets up a new `EditSession` and associates it with the given `Document` and `TextMode`.
|
||||
* @param {Document | String} text [If `text` is a `Document`, it associates the `EditSession` with it. Otherwise, a new `Document` is created, with the initial text]{: #textParam}
|
||||
* @param {TextMode} mode [The inital language mode to use for the document]{: #modeParam}
|
||||
|
@ -149,9 +148,10 @@ var EditSession = function(text, mode) {
|
|||
this.$undoSelect = true;
|
||||
|
||||
this.$foldData = [];
|
||||
this.id = "session" + EditSession.$uid;
|
||||
this.$foldData.toString = function() {
|
||||
return this.join("\n");
|
||||
}
|
||||
};
|
||||
this.on("changeFold", this.onChangeFold.bind(this));
|
||||
this.$onChange = this.onChange.bind(this);
|
||||
|
||||
|
@ -167,6 +167,8 @@ var EditSession = function(text, mode) {
|
|||
};
|
||||
|
||||
|
||||
EditSession.$uid = 0;
|
||||
|
||||
(function() {
|
||||
|
||||
oop.implement(this, EventEmitter);
|
||||
|
@ -376,7 +378,7 @@ var EditSession = function(text, mode) {
|
|||
|
||||
if (undoManager) {
|
||||
var self = this;
|
||||
undoManager.setSession(this);
|
||||
undoManager.addSession(this);
|
||||
this.$syncInformUndoManager = function() {
|
||||
self.$informUndoManager.cancel();
|
||||
self.mergeUndoDeltas = false;
|
||||
|
@ -402,7 +404,7 @@ var EditSession = function(text, mode) {
|
|||
add: function() {},
|
||||
addSelection: function() {},
|
||||
startNewGroup: function() {},
|
||||
setSession: function() {},
|
||||
addSession: function() {},
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -2496,7 +2496,7 @@ var Editor = function(renderer, session) {
|
|||
* @related UndoManager.undo
|
||||
**/
|
||||
this.undo = function() {
|
||||
this.session.getUndoManager().undo();
|
||||
this.session.getUndoManager().undo(this.session);
|
||||
this.renderer.scrollCursorIntoView(null, 0.5);
|
||||
};
|
||||
|
||||
|
@ -2505,7 +2505,7 @@ var Editor = function(renderer, session) {
|
|||
* @related UndoManager.redo
|
||||
**/
|
||||
this.redo = function() {
|
||||
this.session.getUndoManager().redo();
|
||||
this.session.getUndoManager().redo(this.session);
|
||||
this.renderer.scrollCursorIntoView(null, 0.5);
|
||||
};
|
||||
|
||||
|
|
|
@ -42,8 +42,6 @@ var EditSession = require("./edit_session").EditSession;
|
|||
/**
|
||||
* @class Split
|
||||
*
|
||||
*
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
|
@ -217,14 +215,7 @@ var Split = function(container, theme, splits) {
|
|||
var s = new EditSession(session.getDocument(), session.getMode());
|
||||
|
||||
var undoManager = session.getUndoManager();
|
||||
if (undoManager) {
|
||||
var undoManagerProxy = new UndoManagerProxy(undoManager, s);
|
||||
s.setUndoManager(undoManagerProxy);
|
||||
}
|
||||
|
||||
// Overwrite the default $informUndoManager function such that new delas
|
||||
// aren't added to the undo manager from the new and the old session.
|
||||
s.$informUndoManager = lang.delayedCall(function() { s.$deltas = []; });
|
||||
s.setUndoManager(undoManager);
|
||||
|
||||
// Copy over 'settings' from the session.
|
||||
s.setTabSize(session.getTabSize());
|
||||
|
@ -331,43 +322,5 @@ var Split = function(container, theme, splits) {
|
|||
|
||||
}).call(Split.prototype);
|
||||
|
||||
|
||||
function UndoManagerProxy(undoManager, session) {
|
||||
this.$u = undoManager;
|
||||
this.$doc = session;
|
||||
}
|
||||
|
||||
(function() {
|
||||
this.execute = function(options) {
|
||||
this.$u.execute(options);
|
||||
};
|
||||
|
||||
this.undo = function() {
|
||||
var selectionRange = this.$u.undo(true);
|
||||
if (selectionRange) {
|
||||
this.$doc.selection.setSelectionRange(selectionRange);
|
||||
}
|
||||
};
|
||||
|
||||
this.redo = function() {
|
||||
var selectionRange = this.$u.redo(true);
|
||||
if (selectionRange) {
|
||||
this.$doc.selection.setSelectionRange(selectionRange);
|
||||
}
|
||||
};
|
||||
|
||||
this.reset = function() {
|
||||
this.$u.reset();
|
||||
};
|
||||
|
||||
this.hasUndo = function() {
|
||||
return this.$u.hasUndo();
|
||||
};
|
||||
|
||||
this.hasRedo = function() {
|
||||
return this.$u.hasRedo();
|
||||
};
|
||||
}).call(UndoManagerProxy.prototype);
|
||||
|
||||
exports.Split = Split;
|
||||
});
|
||||
|
|
|
@ -5,9 +5,9 @@ require("ace/lib/fixoldbrowsers");
|
|||
var AsyncTest = require("asyncjs").test;
|
||||
var async = require("asyncjs");
|
||||
|
||||
var passed = 0
|
||||
var failed = 0
|
||||
var log = document.getElementById("log")
|
||||
var passed = 0;
|
||||
var failed = 0;
|
||||
var log = document.getElementById("log");
|
||||
|
||||
var testNames = [
|
||||
"ace/anchor_test",
|
||||
|
@ -55,6 +55,7 @@ var testNames = [
|
|||
"ace/snippets_test",
|
||||
"ace/token_iterator_test",
|
||||
"ace/tokenizer_test",
|
||||
"ace/undomanager_test",
|
||||
"ace/virtual_renderer_test"
|
||||
];
|
||||
|
||||
|
@ -64,13 +65,30 @@ for (var i in testNames) {
|
|||
html.push("<a href='?", href, "'>", href.replace(/^ace\//, "") ,"</a><br>");
|
||||
}
|
||||
|
||||
|
||||
if (location.search.indexOf("show=1") != -1) {
|
||||
var VirtualRenderer = require("ace/virtual_renderer").VirtualRenderer;
|
||||
require("ace/test/mockrenderer").MockRenderer = function() {
|
||||
var el = document.createElement("div");
|
||||
el.style.position = "fixed";
|
||||
el.style.left = "20px";
|
||||
el.style.top = "30px";
|
||||
el.style.width = "500px";
|
||||
el.style.height = "300px";
|
||||
document.body.appendChild(el);
|
||||
|
||||
return new VirtualRenderer(el);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
var nav = document.createElement("div");
|
||||
nav.innerHTML = html.join("");
|
||||
nav.style.cssText = "position:absolute;right:0;top:0";
|
||||
document.body.appendChild(nav);
|
||||
|
||||
if (location.search)
|
||||
testNames = location.search.substr(1).split(",")
|
||||
testNames = location.search.substr(1).split(",");
|
||||
|
||||
var filter = location.hash.substr(1);
|
||||
|
||||
|
@ -89,7 +107,7 @@ require(testNames, function() {
|
|||
test[method] = undefined;
|
||||
});
|
||||
}
|
||||
return AsyncTest.testcase(test)
|
||||
return AsyncTest.testcase(test);
|
||||
}, AsyncTest.TestGenerator)
|
||||
.run()
|
||||
.each(function(test, next) {
|
||||
|
@ -102,16 +120,16 @@ require(testNames, function() {
|
|||
var node = document.createElement("div");
|
||||
node.className = test.passed ? "passed" : "failed";
|
||||
|
||||
var name = test.name
|
||||
var name = test.name;
|
||||
if (test.suiteName)
|
||||
name = test.suiteName + ": " + test.name
|
||||
name = test.suiteName + ": " + test.name;
|
||||
|
||||
var msg = "[" + test.count + "/" + test.index + "] " + name + " " + (test.passed ? "OK" : "FAIL")
|
||||
var msg = "[" + test.count + "/" + test.index + "] " + name + " " + (test.passed ? "OK" : "FAIL");
|
||||
if (!test.passed) {
|
||||
if (test.err.stack)
|
||||
var err = test.err.stack
|
||||
var err = test.err.stack;
|
||||
else
|
||||
var err = test.err
|
||||
var err = test.err;
|
||||
|
||||
console.error(msg);
|
||||
console.error(err);
|
||||
|
@ -123,13 +141,13 @@ require(testNames, function() {
|
|||
node.innerHTML = msg;
|
||||
log.appendChild(node);
|
||||
|
||||
next()
|
||||
next();
|
||||
})
|
||||
.each(function(test) {
|
||||
if (test.passed)
|
||||
passed += 1
|
||||
passed += 1;
|
||||
else
|
||||
failed += 1
|
||||
failed += 1;
|
||||
})
|
||||
.end(function() {
|
||||
log.innerHTML += [
|
||||
|
@ -140,11 +158,11 @@ require(testNames, function() {
|
|||
"Total number of tests: " + (passed + failed) + "<br>",
|
||||
(passed ? "Passed tests: " + passed + "<br>" : ""),
|
||||
(failed ? "Failed tests: " + failed + "<br>" : "")
|
||||
].join("")
|
||||
].join("");
|
||||
console.log("Total number of tests: " + (passed + failed));
|
||||
console.log("Passed tests: " + passed);
|
||||
console.log("Failed tests: " + failed);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -49,7 +49,7 @@ var UndoManager = function() {
|
|||
|
||||
(function() {
|
||||
|
||||
this.setSession = function(session) {
|
||||
this.addSession = function(session) {
|
||||
this.$session = session;
|
||||
};
|
||||
/**
|
||||
|
@ -61,13 +61,16 @@ var UndoManager = function() {
|
|||
* @param {Object} options Contains additional properties
|
||||
*
|
||||
**/
|
||||
this.add = function(delta, allowMerge) {
|
||||
this.add = function(delta, allowMerge, session) {
|
||||
if (this.$fromUndo) return;
|
||||
if (delta == this.$lastDelta) return;
|
||||
if (allowMerge === false || !this.lastDeltas) {
|
||||
this.lastDeltas = [];
|
||||
this.$undoStack.push(this.lastDeltas);
|
||||
delta.id = this.$rev = ++this.$maxRev;
|
||||
}
|
||||
if (delta.action == "remove" || delta.action == "insert")
|
||||
this.$lastDelta = delta;
|
||||
this.lastDeltas.push(delta);
|
||||
};
|
||||
|
||||
|
@ -144,7 +147,7 @@ var UndoManager = function() {
|
|||
*
|
||||
* @returns {Range} The range of the undo.
|
||||
**/
|
||||
this.undo = function(dontSelect) {
|
||||
this.undo = function(session, dontSelect) {
|
||||
this.lastDeltas = null;
|
||||
var stack = this.$undoStack;
|
||||
|
||||
|
@ -159,7 +162,7 @@ var UndoManager = function() {
|
|||
var deltaSet = stack.pop();
|
||||
var undoSelectionRange = null;
|
||||
if (deltaSet && deltaSet.length) {
|
||||
undoSelectionRange = this.$session.undoChanges(deltaSet, dontSelect);
|
||||
undoSelectionRange = session.undoChanges(deltaSet, dontSelect);
|
||||
this.$redoStack.push(deltaSet);
|
||||
this.$syncRev();
|
||||
}
|
||||
|
@ -174,7 +177,7 @@ var UndoManager = function() {
|
|||
* @param {Boolean} dontSelect {:dontSelect}
|
||||
*
|
||||
**/
|
||||
this.redo = function(dontSelect) {
|
||||
this.redo = function(session, dontSelect) {
|
||||
this.lastDeltas = null;
|
||||
|
||||
this.$fromUndo = true;
|
||||
|
@ -190,7 +193,7 @@ var UndoManager = function() {
|
|||
var redoSelectionRange = null;
|
||||
|
||||
if (deltaSet) {
|
||||
redoSelectionRange = this.$session.redoChanges(deltaSet, dontSelect);
|
||||
redoSelectionRange = session.redoChanges(deltaSet, dontSelect);
|
||||
this.$undoStack.push(deltaSet);
|
||||
this.$syncRev();
|
||||
}
|
||||
|
@ -212,6 +215,7 @@ var UndoManager = function() {
|
|||
**/
|
||||
this.reset = function() {
|
||||
this.lastDeltas = null;
|
||||
this.$lastDelta = null;
|
||||
this.$undoStack = [];
|
||||
this.$redoStack = [];
|
||||
this.$rev = 0;
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Distributed under the BSD license:
|
||||
*
|
||||
* Copyright (c) 2010, Ajax.org B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Ajax.org B.V. nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
if (typeof process !== "undefined") {
|
||||
require("amd-loader");
|
||||
require("./test/mockdom");
|
||||
}
|
||||
|
||||
define(function(require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
require("./multi_select");
|
||||
var assert = require("./test/assertions");
|
||||
var Range = require("./range").Range;
|
||||
var Editor = require("./editor").Editor;
|
||||
var EditSession = require("./edit_session").EditSession;
|
||||
var MockRenderer = require("./test/mockrenderer").MockRenderer;
|
||||
var UndoManager = require("./undomanager").UndoManager;
|
||||
|
||||
var editor;
|
||||
|
||||
|
||||
module.exports = {
|
||||
|
||||
name: "ACE undoManager.js",
|
||||
|
||||
"test: reabsing": function() {
|
||||
var session = new EditSession("");
|
||||
var editor = new Editor(new MockRenderer(), session);
|
||||
var undoManager = new UndoManager();
|
||||
session.setUndoManager(undoManager);
|
||||
|
||||
session.setValue("012345-012345-012345");
|
||||
session.insert({row: 0, column: 0}, "xx");
|
||||
session.markUndoGroup();
|
||||
session.remove({start: {row: 0, column: 10}, end: {row: 0, column: 15}});
|
||||
session.markUndoGroup();
|
||||
session.insert({row: 0, column: 5}, "yy");
|
||||
session.markUndoGroup();
|
||||
editor.undo();
|
||||
editor.undo();
|
||||
var rev = session.getUndoManager().startNewGroup();
|
||||
session.insert({row: 0, column: 5}, "z\nz");
|
||||
session.getUndoManager().markIgnored(rev);
|
||||
// editor.undo()
|
||||
editor.redo();
|
||||
editor.redo();
|
||||
var val1 = editor.getValue();
|
||||
editor.undo();
|
||||
editor.undo();
|
||||
editor.undo();
|
||||
|
||||
editor.redo();
|
||||
editor.redo();
|
||||
editor.redo();
|
||||
var val2 = editor.getValue();
|
||||
assert.equal(val1, val2);
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
if (typeof module !== "undefined" && module === require.main) {
|
||||
require("asyncjs").test.testcase(module.exports).exec();
|
||||
}
|
|
@ -352,6 +352,12 @@ define(function(require, exports, module) {
|
|||
this.$aceUndo.$redoStack = [];
|
||||
this._emit("changeSync");
|
||||
},
|
||||
startNewGroup: function() {
|
||||
return this.$aceUndo.startNewGroup();
|
||||
},
|
||||
markIgnored: function(from, to) {
|
||||
return this.$aceUndo.markIgnored(from, to);
|
||||
},
|
||||
getState: function() {
|
||||
console.log("getState()");
|
||||
var aceUndo = this.$aceUndo;
|
||||
|
@ -371,9 +377,9 @@ define(function(require, exports, module) {
|
|||
var aceUndo = this.$aceUndo;
|
||||
aceUndo.$undoStack = (e.stack || []).filter(function(x) {
|
||||
return x.length;
|
||||
});
|
||||
}).map(updateDeltas);
|
||||
var stack = aceUndo.$undoStack;
|
||||
var lastDeltaGroup = stack[stack.length] - 1;
|
||||
var lastDeltaGroup = stack[stack.length - 1];
|
||||
var lastRev = lastDeltaGroup && lastDeltaGroup[0].id || 0;
|
||||
aceUndo.$rev = lastRev;
|
||||
aceUndo.$maxRev = Math.max(aceUndo.$maxRev, lastRev);
|
||||
|
@ -404,70 +410,19 @@ define(function(require, exports, module) {
|
|||
}
|
||||
this._emit("changeSync");
|
||||
},
|
||||
setSession: function(session) {
|
||||
this.$aceUndo.setSession(session);
|
||||
addSession: function(session) {
|
||||
this.$aceUndo.addSession(session);
|
||||
},
|
||||
getPosition: function() {
|
||||
var aceUndo = this.$aceUndo;
|
||||
return aceUndo.$undoStack.length - 1;
|
||||
},
|
||||
getMark: function() {
|
||||
var aceUndo = this.$aceUndo;
|
||||
return aceUndo.$undoStack.length - 1;
|
||||
},
|
||||
getLength: function() {
|
||||
var aceUndo = this.$aceUndo;
|
||||
return aceUndo.$undoStack.length + aceUndo.$redoStack.length;
|
||||
}
|
||||
};
|
||||
|
||||
function UndoManagerProxy(undoManager, session) {
|
||||
this.$u = undoManager;
|
||||
this.$doc = session;
|
||||
}
|
||||
|
||||
(function() {
|
||||
this.add = function(delta, doc) {
|
||||
this.$u.add(delta, doc);
|
||||
};
|
||||
|
||||
Object.defineProperty(this, "", {
|
||||
configurable: true,
|
||||
get: function() {
|
||||
return this.$u.lastDeltas;
|
||||
},
|
||||
set: function(v) {
|
||||
this.$u.lastDeltas = v;
|
||||
}
|
||||
});
|
||||
|
||||
this.undo = function() {
|
||||
var selectionRange = this.$u.undo(true);
|
||||
if (selectionRange) {
|
||||
this.$doc.selection.setSelectionRange(selectionRange);
|
||||
}
|
||||
};
|
||||
|
||||
this.redo = function() {
|
||||
var selectionRange = this.$u.redo(true);
|
||||
if (selectionRange) {
|
||||
this.$doc.selection.setSelectionRange(selectionRange);
|
||||
}
|
||||
};
|
||||
|
||||
this.reset = function() {
|
||||
this.$u.reset();
|
||||
};
|
||||
|
||||
this.hasUndo = function() {
|
||||
return this.$u.hasUndo();
|
||||
};
|
||||
|
||||
this.hasRedo = function() {
|
||||
return this.$u.hasRedo();
|
||||
};
|
||||
}).call(UndoManagerProxy.prototype);
|
||||
|
||||
/***** Generic Load *****/
|
||||
|
||||
handle.on("load", function(){
|
||||
|
@ -1463,8 +1418,7 @@ define(function(require, exports, module) {
|
|||
if (!undoManager)
|
||||
undoManager = session.getUndoManager();
|
||||
if (undoManager) {
|
||||
var undoManagerProxy = new UndoManagerProxy(undoManager, s);
|
||||
s.setUndoManager(undoManagerProxy.$aceUndo);
|
||||
s.setUndoManager(undoManager);
|
||||
}
|
||||
|
||||
// Overwrite the default $informUndoManager function such that new deltas
|
||||
|
|
|
@ -40,15 +40,16 @@ define(function(require, module, exports) {
|
|||
|
||||
// Listen to changes and detect when the value of the editor
|
||||
// is different from what is on disk
|
||||
function updateStatus(e) {
|
||||
var c = !undoManager.isAtBookmark();
|
||||
if (changed !== c) {
|
||||
changed = c;
|
||||
emit("changed", { changed: c });
|
||||
}
|
||||
function initUndo(){
|
||||
undoManager.on("change", function(e) {
|
||||
var c = !undoManager.isAtBookmark();
|
||||
if (changed !== c) {
|
||||
changed = c;
|
||||
emit("changed", { changed: c });
|
||||
}
|
||||
});
|
||||
}
|
||||
undoManager.on("change", updateStatus);
|
||||
undoManager.on("changeSync", updateStatus);
|
||||
initUndo();
|
||||
|
||||
/***** Methods *****/
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue