2011-11-02 21:00:55 +00:00
|
|
|
/**
|
2011-11-17 22:42:18 +00:00
|
|
|
* Creates an es.TransactionModel object.
|
2011-11-02 21:00:55 +00:00
|
|
|
*
|
|
|
|
* @class
|
|
|
|
* @constructor
|
|
|
|
* @param {Object[]} operations List of operations
|
|
|
|
*/
|
2011-11-17 22:42:18 +00:00
|
|
|
es.TransactionModel = function( operations ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
this.operations = es.isArray( operations ) ? operations : [];
|
2011-11-17 22:42:18 +00:00
|
|
|
this.lengthDiff = 0;
|
2011-11-02 21:00:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Methods */
|
|
|
|
|
2011-11-04 21:06:06 +00:00
|
|
|
/**
|
|
|
|
* Gets a list of all operations.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @returns {Object[]} List of operations
|
|
|
|
*/
|
2011-11-17 22:42:18 +00:00
|
|
|
es.TransactionModel.prototype.getOperations = function() {
|
2011-11-17 14:43:11 +00:00
|
|
|
return this.operations;
|
2011-11-02 21:00:55 +00:00
|
|
|
};
|
|
|
|
|
2011-11-17 22:42:18 +00:00
|
|
|
/**
|
|
|
|
* Gets the difference in content length this transaction will cause if applied.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @returns {Integer} Difference in content length
|
|
|
|
*/
|
|
|
|
es.TransactionModel.prototype.getLengthDiff = function() {
|
|
|
|
return this.lengthDiff;
|
|
|
|
};
|
|
|
|
|
2011-11-04 21:06:06 +00:00
|
|
|
/**
|
|
|
|
* Merges consecutive operations of the same type.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
*/
|
2011-11-17 22:42:18 +00:00
|
|
|
es.TransactionModel.prototype.optimize = function() {
|
2011-11-04 20:38:47 +00:00
|
|
|
for ( var i = 0; i < this.operations.length - 1; i++ ) {
|
|
|
|
var a = this.operations[i];
|
|
|
|
var b = this.operations[i + 1];
|
|
|
|
if ( a.type === b.type ) {
|
|
|
|
switch ( a.type ) {
|
|
|
|
case 'retain':
|
|
|
|
a.length += b.length;
|
|
|
|
this.operations.splice( i + 1, 1 );
|
2011-11-09 23:39:11 +00:00
|
|
|
i--;
|
2011-11-04 20:38:47 +00:00
|
|
|
break;
|
|
|
|
case 'insert':
|
|
|
|
case 'remove':
|
2011-11-16 00:02:27 +00:00
|
|
|
a.data = a.data.concat( b.data );
|
2011-11-04 20:38:47 +00:00
|
|
|
this.operations.splice( i + 1, 1 );
|
2011-11-09 23:39:11 +00:00
|
|
|
i--;
|
2011-11-04 20:38:47 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-11-04 21:06:06 +00:00
|
|
|
/**
|
|
|
|
* Adds a retain operation.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @param {Integer} length Length of content data to retain
|
|
|
|
*/
|
2011-11-17 22:42:18 +00:00
|
|
|
es.TransactionModel.prototype.pushRetain = function( length ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
this.operations.push( {
|
|
|
|
'type': 'retain',
|
|
|
|
'length': length
|
|
|
|
} );
|
|
|
|
};
|
|
|
|
|
2011-11-04 21:06:06 +00:00
|
|
|
/**
|
|
|
|
* Adds an insertion operation.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @param {Array} data Data to retain
|
|
|
|
*/
|
2011-11-17 22:42:18 +00:00
|
|
|
es.TransactionModel.prototype.pushInsert = function( data ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
this.operations.push( {
|
|
|
|
'type': 'insert',
|
2011-11-04 21:06:06 +00:00
|
|
|
'data': data
|
2011-11-02 21:00:55 +00:00
|
|
|
} );
|
2011-11-17 22:42:18 +00:00
|
|
|
this.lengthDiff += data.length;
|
2011-11-02 21:00:55 +00:00
|
|
|
};
|
|
|
|
|
2011-11-04 21:06:06 +00:00
|
|
|
/**
|
|
|
|
* Adds a removal operation.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @param {Array} data Data to remove
|
|
|
|
*/
|
2011-11-17 22:42:18 +00:00
|
|
|
es.TransactionModel.prototype.pushRemove = function( data ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
this.operations.push( {
|
|
|
|
'type': 'remove',
|
|
|
|
'data': data
|
|
|
|
} );
|
2011-11-17 22:42:18 +00:00
|
|
|
this.lengthDiff -= data.length;
|
2011-11-02 21:00:55 +00:00
|
|
|
};
|
|
|
|
|
2011-11-04 21:06:06 +00:00
|
|
|
/**
|
|
|
|
* Adds an element attribute change operation.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @param {String} method Method to use, either "set" or "clear"
|
|
|
|
* @param {String} key Name of attribute to change
|
|
|
|
* @param {Mixed} value Value to set attribute to, or value of attribute being cleared
|
|
|
|
*/
|
2011-11-17 22:42:18 +00:00
|
|
|
es.TransactionModel.prototype.pushChangeElementAttribute = function( method, key, value ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
this.operations.push( {
|
|
|
|
'type': 'attribute',
|
|
|
|
'method': method,
|
|
|
|
'key': key,
|
|
|
|
'value': value
|
|
|
|
} );
|
|
|
|
};
|
|
|
|
|
2011-11-04 21:06:06 +00:00
|
|
|
/**
|
|
|
|
* Adds a start annotating operation.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @param {String} method Method to use, either "set" or "clear"
|
|
|
|
* @param {Object} annotation Annotation object to start setting or clearing from content data
|
|
|
|
*/
|
2011-11-17 22:42:18 +00:00
|
|
|
es.TransactionModel.prototype.pushStartAnnotating = function( method, annotation ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
this.operations.push( {
|
|
|
|
'type': 'annotate',
|
|
|
|
'method': method,
|
|
|
|
'bias': 'start',
|
|
|
|
'annotation': annotation
|
|
|
|
} );
|
|
|
|
};
|
|
|
|
|
2011-11-04 21:06:06 +00:00
|
|
|
/**
|
|
|
|
* Adds a stop annotating operation.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @param {String} method Method to use, either "set" or "clear"
|
|
|
|
* @param {Object} annotation Annotation object to stop setting or clearing from content data
|
|
|
|
*/
|
2011-11-17 22:42:18 +00:00
|
|
|
es.TransactionModel.prototype.pushStopAnnotating = function( method, annotation ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
this.operations.push( {
|
|
|
|
'type': 'annotate',
|
|
|
|
'method': method,
|
|
|
|
'bias': 'stop',
|
|
|
|
'annotation': annotation
|
|
|
|
} );
|
|
|
|
};
|