diff --git a/node_modules/ace/lib/ace/edit_session.js b/node_modules/ace/lib/ace/edit_session.js
index e385647a..30a8749d 100644
--- a/node_modules/ace/lib/ace/edit_session.js
+++ b/node_modules/ace/lib/ace/edit_session.js
@@ -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() {},
};
/**
diff --git a/node_modules/ace/lib/ace/editor.js b/node_modules/ace/lib/ace/editor.js
index ce099e62..8d816cbd 100644
--- a/node_modules/ace/lib/ace/editor.js
+++ b/node_modules/ace/lib/ace/editor.js
@@ -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);
};
diff --git a/node_modules/ace/lib/ace/split.js b/node_modules/ace/lib/ace/split.js
index 878b0dc3..e960c128 100644
--- a/node_modules/ace/lib/ace/split.js
+++ b/node_modules/ace/lib/ace/split.js
@@ -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;
});
diff --git a/node_modules/ace/lib/ace/test/all_browser.js b/node_modules/ace/lib/ace/test/all_browser.js
index 7ac5092e..71e96e2f 100644
--- a/node_modules/ace/lib/ace/test/all_browser.js
+++ b/node_modules/ace/lib/ace/test/all_browser.js
@@ -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("", href.replace(/^ace\//, "") ,"
");
}
+
+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) + "
",
(passed ? "Passed tests: " + passed + "
" : ""),
(failed ? "Failed tests: " + failed + "
" : "")
- ].join("")
+ ].join("");
console.log("Total number of tests: " + (passed + failed));
console.log("Passed tests: " + passed);
console.log("Failed tests: " + failed);
- })
+ });
});
});
diff --git a/node_modules/ace/lib/ace/undomanager.js b/node_modules/ace/lib/ace/undomanager.js
index 3bf6b5bc..c23eb4f9 100644
--- a/node_modules/ace/lib/ace/undomanager.js
+++ b/node_modules/ace/lib/ace/undomanager.js
@@ -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;
diff --git a/node_modules/ace/lib/ace/undomanager_test.js b/node_modules/ace/lib/ace/undomanager_test.js
new file mode 100644
index 00000000..6d0dbf58
--- /dev/null
+++ b/node_modules/ace/lib/ace/undomanager_test.js
@@ -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();
+}
diff --git a/plugins/c9.ide.ace/ace.js b/plugins/c9.ide.ace/ace.js
index 1affd8b2..d453afc0 100644
--- a/plugins/c9.ide.ace/ace.js
+++ b/plugins/c9.ide.ace/ace.js
@@ -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
diff --git a/plugins/c9.ide.editors/document.js b/plugins/c9.ide.editors/document.js
index ec70358e..6c7174c5 100644
--- a/plugins/c9.ide.editors/document.js
+++ b/plugins/c9.ide.editors/document.js
@@ -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 *****/