mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-12 09:09:25 +00:00
Move .commit()/.rollback() from TransactionProcessor to Document
Previously these were static functions in TransactionProcessor which instantiated a TP called .process() on it. These are now methods of ve.dm.Document. Also moved the emission of the 'transact' event on the document from TransactionProcessor to Document itself, and moved the tests asserting double application is protected against from TP to Document (because the corresponding code moved as well). Change-Id: I7c9f22a14accaf0ba1f70d5aa4f0573bb7e677d0
This commit is contained in:
parent
8199f2a1c1
commit
1176bf9677
|
@ -475,20 +475,32 @@ ve.dm.Document.getDataSlice = function ( sourceData, range, deep ) {
|
|||
* Reverse a transaction's effects on the content data.
|
||||
*
|
||||
* @method
|
||||
* @param {ve.dm.Transaction}
|
||||
* @param {ve.dm.Transaction} transaction Transaction to roll back
|
||||
* @emits transact
|
||||
* @throws {Error} Cannot roll back a transaction that has not been committed
|
||||
*/
|
||||
ve.dm.Document.prototype.rollback = function ( transaction ) {
|
||||
ve.dm.TransactionProcessor.rollback( this, transaction );
|
||||
if ( !transaction.hasBeenApplied() ) {
|
||||
throw new Error( 'Cannot roll back a transaction that has not been committed' );
|
||||
}
|
||||
new ve.dm.TransactionProcessor( this, transaction, true ).process();
|
||||
this.emit( 'transact', transaction, true );
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply a transaction's effects on the content data.
|
||||
*
|
||||
* @method
|
||||
* @param {ve.dm.Transaction}
|
||||
* @param {ve.dm.Transaction} transaction Transaction to apply
|
||||
* @emits transact
|
||||
* @throws {Error} Cannot commit a transaction that has already been committed
|
||||
*/
|
||||
ve.dm.Document.prototype.commit = function ( transaction ) {
|
||||
ve.dm.TransactionProcessor.commit( this, transaction );
|
||||
if ( transaction.hasBeenApplied() ) {
|
||||
throw new Error( 'Cannot commit a transaction that has already been committed' );
|
||||
}
|
||||
new ve.dm.TransactionProcessor( this, transaction, false ).process();
|
||||
this.emit( 'transact', transaction, false );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -285,7 +285,7 @@ ve.dm.Surface.prototype.change = function ( transactions, selection ) {
|
|||
this.bigStack = this.bigStack.slice( 0, this.bigStack.length - this.undoIndex );
|
||||
this.undoIndex = 0;
|
||||
this.smallStack.push( transactions[i] );
|
||||
ve.dm.TransactionProcessor.commit( this.documentModel, transactions[i] );
|
||||
this.documentModel.commit( transactions[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
* DataModel transaction processor.
|
||||
*
|
||||
* This class reads operations from a transaction and applies them one by one. It's not intended
|
||||
* to be used directly; use the static functions ve.dm.TransactionProcessor.commit() and .rollback()
|
||||
* instead.
|
||||
* to be used directly; use the .commit() and .rollback() methods of ve.dm.Document.
|
||||
*
|
||||
* NOTE: Instances of this class are not recyclable: you can only call .process() on them once.
|
||||
*
|
||||
|
@ -42,40 +41,6 @@ ve.dm.TransactionProcessor = function VeDmTransactionProcessor( doc, transaction
|
|||
/* See ve.dm.TransactionProcessor.processors */
|
||||
ve.dm.TransactionProcessor.processors = {};
|
||||
|
||||
/* Static methods */
|
||||
|
||||
/**
|
||||
* Commit a transaction to a document.
|
||||
*
|
||||
* @static
|
||||
* @method
|
||||
* @param {ve.dm.Document} doc Document object to apply the transaction to
|
||||
* @param {ve.dm.Transaction} transaction Transaction to apply
|
||||
*/
|
||||
ve.dm.TransactionProcessor.commit = function ( doc, transaction ) {
|
||||
if ( transaction.hasBeenApplied() ) {
|
||||
throw new Error( 'Cannot commit a transaction that has already been committed' );
|
||||
}
|
||||
new ve.dm.TransactionProcessor( doc, transaction, false ).process();
|
||||
};
|
||||
|
||||
/**
|
||||
* Roll back a transaction.
|
||||
*
|
||||
* This applies the transaction to the document in reverse.
|
||||
*
|
||||
* @static
|
||||
* @method
|
||||
* @param {ve.dm.Document} doc Document object to apply the transaction to
|
||||
* @param {ve.dm.Transaction} transaction Transaction to apply
|
||||
*/
|
||||
ve.dm.TransactionProcessor.rollback = function ( doc, transaction ) {
|
||||
if ( !transaction.hasBeenApplied() ) {
|
||||
throw new Error( 'Cannot roll back a transaction that has not been committed' );
|
||||
}
|
||||
new ve.dm.TransactionProcessor( doc, transaction, true ).process();
|
||||
};
|
||||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
|
@ -144,8 +109,6 @@ ve.dm.TransactionProcessor.prototype.process = function () {
|
|||
}
|
||||
// Mark the transaction as committed or rolled back, as appropriate
|
||||
this.transaction.toggleApplied();
|
||||
// Emit an event on the document
|
||||
this.document.emit( 'transact', this.transaction, this.reversed );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1533,3 +1533,33 @@ QUnit.test( 'getSlice', function ( assert ) {
|
|||
);
|
||||
}
|
||||
} );
|
||||
|
||||
QUnit.test( 'protection against double application of transactions', 3, function ( assert ) {
|
||||
var tx = new ve.dm.Transaction(),
|
||||
testDocument = new ve.dm.Document( ve.dm.example.data );
|
||||
tx.pushRetain( 1 );
|
||||
tx.pushReplace( [], ['H', 'e', 'l', 'l', 'o' ] );
|
||||
assert.throws(
|
||||
function () {
|
||||
testDocument.rollback( tx );
|
||||
},
|
||||
Error,
|
||||
'exception thrown when trying to rollback an uncommitted transaction'
|
||||
);
|
||||
testDocument.commit( tx );
|
||||
assert.throws(
|
||||
function () {
|
||||
testDocument.commit( tx );
|
||||
},
|
||||
Error,
|
||||
'exception thrown when trying to commit an already-committed transaction'
|
||||
);
|
||||
testDocument.rollback( tx );
|
||||
assert.throws(
|
||||
function () {
|
||||
testDocument.rollback( tx );
|
||||
},
|
||||
Error,
|
||||
'exception thrown when trying to roll back a transaction that has already been rolled back'
|
||||
);
|
||||
} );
|
|
@ -135,9 +135,9 @@ QUnit.test( 'onTransact', function ( assert ) {
|
|||
}
|
||||
doc = new ve.dm.Document( ve.copyArray( ve.dm.example.withMeta ) );
|
||||
list = new ve.dm.MetaList( doc );
|
||||
ve.dm.TransactionProcessor.commit( doc, tx );
|
||||
doc.commit( tx );
|
||||
assertItemsMatchMetadata( assert, doc.metadata, list, cases[i].msg, false );
|
||||
ve.dm.TransactionProcessor.rollback( doc, tx );
|
||||
doc.rollback( tx );
|
||||
assertItemsMatchMetadata( assert, doc.metadata, list, cases[i].msg + ' (rollback)', false );
|
||||
}
|
||||
} );
|
||||
|
|
|
@ -9,37 +9,6 @@ QUnit.module( 've.dm.TransactionProcessor' );
|
|||
|
||||
/* Tests */
|
||||
|
||||
QUnit.test( 'protection against double application', 3, function ( assert ) {
|
||||
var tx,
|
||||
testDocument = new ve.dm.Document( ve.dm.example.data );
|
||||
tx = new ve.dm.Transaction();
|
||||
tx.pushRetain( 1 );
|
||||
tx.pushReplace( [], ['H', 'e', 'l', 'l', 'o' ] );
|
||||
assert.throws(
|
||||
function () {
|
||||
ve.dm.TransactionProcessor.rollback( testDocument, tx );
|
||||
},
|
||||
Error,
|
||||
'exception thrown when trying to rollback an uncommitted transaction'
|
||||
);
|
||||
ve.dm.TransactionProcessor.commit( testDocument, tx );
|
||||
assert.throws(
|
||||
function () {
|
||||
ve.dm.TransactionProcessor.commit( testDocument, tx );
|
||||
},
|
||||
Error,
|
||||
'exception thrown when trying to commit an already-committed transaction'
|
||||
);
|
||||
ve.dm.TransactionProcessor.rollback( testDocument, tx );
|
||||
assert.throws(
|
||||
function () {
|
||||
ve.dm.TransactionProcessor.rollback( testDocument, tx );
|
||||
},
|
||||
Error,
|
||||
'exception thrown when trying to roll back a transaction that has already been rolled back'
|
||||
);
|
||||
} );
|
||||
|
||||
QUnit.test( 'commit/rollback', 86, function ( assert ) {
|
||||
var i, key, originalData, originalDoc, msg, testDocument, tx,
|
||||
expectedData, expectedDocument,
|
||||
|
@ -396,7 +365,7 @@ QUnit.test( 'commit/rollback', 86, function ( assert ) {
|
|||
cases[msg].expected( expectedData );
|
||||
expectedDocument = new ve.dm.Document( ve.copyArray ( expectedData ) );
|
||||
// Commit
|
||||
ve.dm.TransactionProcessor.commit( testDocument, tx );
|
||||
testDocument.commit( tx );
|
||||
assert.deepEqual( testDocument.getFullData(), expectedData, 'commit (data): ' + msg );
|
||||
assert.equalNodeTree(
|
||||
testDocument.getDocumentNode(),
|
||||
|
@ -404,7 +373,7 @@ QUnit.test( 'commit/rollback', 86, function ( assert ) {
|
|||
'commit (tree): ' + msg
|
||||
);
|
||||
// Rollback
|
||||
ve.dm.TransactionProcessor.rollback( testDocument, tx );
|
||||
testDocument.rollback( tx );
|
||||
assert.deepEqual( testDocument.getFullData(), originalData, 'rollback (data): ' + msg );
|
||||
assert.equalNodeTree(
|
||||
testDocument.getDocumentNode(),
|
||||
|
@ -415,7 +384,7 @@ QUnit.test( 'commit/rollback', 86, function ( assert ) {
|
|||
/*jshint loopfunc:true */
|
||||
assert.throws(
|
||||
function () {
|
||||
ve.dm.TransactionProcessor.commit( testDocument, tx );
|
||||
testDocument.commit( tx );
|
||||
},
|
||||
cases[msg].exception,
|
||||
'commit: ' + msg
|
||||
|
|
Loading…
Reference in a new issue