smartxml: Rollback support for transactions
authorAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Wed, 19 Mar 2014 09:36:45 +0000 (10:36 +0100)
committerAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Fri, 28 Mar 2014 11:25:31 +0000 (12:25 +0100)
src/smartxml/smartxml.js
src/smartxml/smartxml.test.js

index 426dce0..31faef0 100644 (file)
@@ -560,6 +560,7 @@ $.extend(Document.prototype, Backbone.Events, {
         if(this._currentTransaction) {
             throw new Error('Nested transactions not supported!');
         }
+        this._rollbackBackup = this.root.clone();
         this._currentTransaction = new Transaction([], metadata);
     },
 
@@ -573,6 +574,15 @@ $.extend(Document.prototype, Backbone.Events, {
         this._currentTransaction = null;
     },
 
+    rollbackTransaction: function() {
+        if(!this._currentTransaction) {
+            throw new Error('Transaction rollback requested, but there is no transaction in progress!');
+        }
+        this.replaceRoot(this._rollbackBackup);
+        this._rollbackBackup = null;
+        this._currentTransaction = null;
+    },
+
     transaction: function(callback, context, metadata) {
         var toret;
         this.startTransaction(metadata);
index 8f7deb6..c792cf9 100644 (file)
@@ -1649,6 +1649,17 @@ describe('smartxml', function() {
                 var transaction = doc.undoStack[0];
                 expect(transaction.metadata).to.equal(metadata);
             });
+
+            it('can be rolled back', function() {
+                var doc = getDocumentFromXML('<root></root>');
+
+                doc.startTransaction();
+                doc.root.append({tagName: 'div'});
+                doc.rollbackTransaction();
+
+                expect(doc.undoStack.length).to.equal(0, 'nothing to undo');
+                expect(doc.root.contents().length).to.equal(0);
+            });
         });
 
         describe('Regression tests', function() {