Actually use op.retainMetadata in structural replace mode

It was being used correctly in the textual replace case, but it was
omitted in the structural replace case. This caused rare, insidious
metadata placement bugs that I haven't been able to reproduce outside
of newFromDocumentInsertion testing, but this might explain some of
the odd category bugs that have been reported.

Change-Id: I1424e482303853f285e4516a93c9609076648eff
This commit is contained in:
Roan Kattouw 2013-07-12 15:57:26 -07:00
parent 4c85442047
commit bab7689feb
3 changed files with 24 additions and 2 deletions

View file

@ -96,7 +96,7 @@ ve.dm.MetaList.prototype.onTransact = function ( tx, reversed ) {
index = 0;
break;
case 'replace':
// if we have metadata replace info we can calulcate the new
// if we have metadata replace info we can calculate the new
// offset and index directly
ins = reversed ? ops[i].removeMetadata : ops[i].insertMetadata;
rm = reversed ? ops[i].insertMetadata : ops[i].removeMetadata;

View file

@ -387,7 +387,7 @@ ve.dm.TransactionProcessor.processors.replace = function ( op ) {
this.document.data.batchSplice( this.cursor, opRemove.length, opInsert );
// Keep the meta linear model in sync
if ( opRemoveMetadata !== undefined ) {
this.document.metadata.batchSplice( this.cursor, opRemoveMetadata.length, opInsertMetadata );
this.document.metadata.batchSplice( this.cursor + op.retainMetadata, opRemoveMetadata.length, opInsertMetadata );
} else if ( opInsert.length > opRemove.length ) {
this.document.metadata.batchSplice( this.cursor + opRemove.length, 0, new Array( opInsert.length - opRemove.length ) );
} else if ( opInsert.length < opRemove.length ) {

View file

@ -315,6 +315,28 @@ QUnit.test( 'commit/rollback', function ( assert ) {
'expected': function ( data ) {
data.splice( 15, 2 );
}
},
'structural replacement starting at an offset without metadata': {
'data': [
{ 'type': 'paragraph' },
'F',
{
'type': 'alienMeta',
'attributes': {
'domElements': $( '<!-- foo -->' ).toArray()
}
},
{ 'type': '/alienMeta' },
'o', 'o',
{ 'type': '/paragraph' }
],
'calls': [
['pushReplace', 0, 5, [ { 'type': 'table' }, { 'type': '/table' } ]]
],
'expected': function ( data ) {
data.splice( 0, 2, { 'type': 'table' }, { 'type': '/table' } );
data.splice( 4, 3 );
}
}
};