mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-27 15:50:29 +00:00
Implement basic replace processor
* Implement basic TransactionProcessor.replace(), only does content replacements * Add ve.dm.Document.containsElementData() * Fix bug in attribute() * Write basic tests for attribute() and replace() Change-Id: Ie9c22aec3f2631be5b0bd66790408ad283565491
This commit is contained in:
parent
a9b26c8b55
commit
11a3b6886b
|
@ -65,6 +65,24 @@ ve.dm.Document.prototype.rebuildNodes = function( parent, index, numNodes, offse
|
|||
return nodes;
|
||||
};
|
||||
|
||||
/* Static methods */
|
||||
/**
|
||||
* Checks if elements are present within data.
|
||||
*
|
||||
* @static
|
||||
* @method
|
||||
* @param {Array} data Data to look for elements within
|
||||
* @returns {Boolean} If elements exist in data
|
||||
*/
|
||||
ve.dm.Document.containsElementData = function( data ) {
|
||||
for ( var i = 0, length = data.length; i < length; i++ ) {
|
||||
if ( data[i].type !== undefined ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
||||
ve.extendClass( ve.dm.Document, ve.dm.DocumentFragment );
|
||||
|
|
|
@ -169,7 +169,7 @@ ve.dm.TransactionProcessor.prototype.annotate = function( op ) {
|
|||
* to: new attribute value, or undefined to unset
|
||||
*/
|
||||
ve.dm.TransactionProcessor.prototype.attribute = function( op ) {
|
||||
var element = this.model.data[this.cursor];
|
||||
var element = this.document.data[this.cursor];
|
||||
if ( element.type === undefined ) {
|
||||
throw 'Invalid element error. Can not set attributes on non-element data.';
|
||||
}
|
||||
|
@ -207,5 +207,26 @@ ve.dm.TransactionProcessor.prototype.attribute = function( op ) {
|
|||
* replacement: Linear model data fragment to insert
|
||||
*/
|
||||
ve.dm.TransactionProcessor.prototype.replace = function( op ) {
|
||||
// TODO
|
||||
var remove = this.reversed ? op.replacement : op.remove,
|
||||
replacement = this.reversed ? op.remove : op.replacement,
|
||||
removeHasStructure = ve.dm.Document.containsElementData( remove ),
|
||||
replacementHasStructure = ve.dm.Document.containsElementData( replacement ),
|
||||
node;
|
||||
// Figure out if this is a structural replacement or a content replacement
|
||||
if ( !removeHasStructure && !replacementHasStructure ) {
|
||||
// Content replacement
|
||||
// Update the linear model
|
||||
ve.batchSplice( this.document.data, this.cursor, remove.length, replacement );
|
||||
this.applyAnnotations( this.cursor + replacement.length );
|
||||
|
||||
// Get the node containing the replaced content
|
||||
node = this.document.getNodeFromOffset( this.cursor );
|
||||
// Queue a resize for this node
|
||||
//this.synchronizer.pushResize( node, replacement.length - remove.length );
|
||||
// Advance the cursor
|
||||
this.cursor += replacement.length;
|
||||
} else {
|
||||
// Structural replacement
|
||||
// TODO implement
|
||||
}
|
||||
};
|
||||
|
|
|
@ -51,3 +51,49 @@ test( 'annotate', function() {
|
|||
deepEqual( doc.getData(), ve.dm.example.data,
|
||||
'Complex annotation transaction rolls back correctly' );
|
||||
} );
|
||||
|
||||
test( 'attribute', function() {
|
||||
var doc = new ve.dm.Document( ve.dm.example.data.slice( 0 ) );
|
||||
var tx = new ve.dm.Transaction();
|
||||
var expectedData = ve.dm.example.data.slice( 0 );
|
||||
tx.pushReplaceElementAttribute( 'level', 1, 2 );
|
||||
tx.pushRetain( 11 );
|
||||
tx.pushReplaceElementAttribute( 'styles', ['bullet'], ['number'] );
|
||||
expectedData[0].attributes.level = 2;
|
||||
expectedData[11].attributes.styles = ['number'];
|
||||
|
||||
ve.dm.TransactionProcessor.commit( doc, tx );
|
||||
deepEqual( doc.getData(), expectedData,
|
||||
'Attribute transaction replaces attributes correctly' );
|
||||
ve.dm.TransactionProcessor.rollback( doc, tx );
|
||||
deepEqual( doc.getData(), ve.dm.example.data,
|
||||
'Attribute transaction rolls back correctly' );
|
||||
|
||||
// TODO test attribute addition/removal
|
||||
|
||||
doc = new ve.dm.Document( ve.dm.example.data.slice( 0 ) );
|
||||
tx = new ve.dm.Transaction();
|
||||
tx.pushRetain( 1 );
|
||||
tx.pushReplaceElementAttribute( 'foo', 23, 42 );
|
||||
raises(
|
||||
function() { ve.dm.TransactionProcessor.commit( doc, tx ); },
|
||||
/^Invalid element error. Can not set attributes on non-element data.$/,
|
||||
'Trying to replace attributes on content results in an exception'
|
||||
);
|
||||
} );
|
||||
|
||||
test( 'replace', function() {
|
||||
var doc = new ve.dm.Document( ve.dm.example.data.slice( 0 ) );
|
||||
var tx = new ve.dm.Transaction();
|
||||
var expectedData = ve.dm.example.data.slice( 0 );
|
||||
tx.pushRetain( 1 );
|
||||
tx.pushReplace( [ 'a' ], [ 'F', 'O', 'O' ] );
|
||||
expectedData.splice( 1, 1, 'F', 'O', 'O' );
|
||||
|
||||
ve.dm.TransactionProcessor.commit( doc, tx );
|
||||
deepEqual( doc.getData(), expectedData,
|
||||
'Replace transaction replaces content correctly' );
|
||||
ve.dm.TransactionProcessor.rollback( doc, tx );
|
||||
deepEqual( doc.getData(), ve.dm.example.data,
|
||||
'Replace transaction rolls back correctly' );
|
||||
} );
|
Loading…
Reference in a new issue