1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
/*!
* VisualEditor DataModel TestRebaseClient class
*
* @copyright See AUTHORS.txt
*/
/**
* Rebase client used for testing
*
* @class
* @extends ve.dm.RebaseClient
*
* @constructor
* @param {ve.dm.TestRebaseServer} server Rebase server
* @param {Array} initialData Document
*/
ve.dm.TestRebaseClient = function VeDmTestRebaseClient( server, initialData ) {
ve.dm.RebaseClient.apply( this );
this.server = server;
this.incomingPointer = 0;
this.outgoing = [];
this.outgoingPointer = 0;
this.doc = new ve.dm.Document( OO.copy( initialData ) );
this.surface = new ve.dm.Surface( this.doc );
};
OO.initClass( ve.dm.TestRebaseClient );
OO.mixinClass( ve.dm.TestRebaseClient, ve.dm.RebaseClient );
/**
* Compact, potentially ambiguous summary of insertions/removals, disregarding location
*
* Example: insertion1insertion2-(removal3)insertion3/uncommittedinsertion4?/-(unsentremoval5)!
*
* Only insertions and removals are represented. An insertion is represented by the toString
* content inserted; a removal by '-(' then the toString content removed then ')'. The offset
* in the document of the insertion/removal is not represented at all. Consecutive transaction
* representations are concatenated.
*
* Therefore this format is ambiguous unless the test transactions are chosen very carefully.
* The summary 'abc' could represent any of the following changes (amongst others):
*
* - Append 'abc'
* - Append 'a', then append 'bc'
* - Append 'a' then prepend 'bc'
* - Append 'a' then prepend 'b' then append 'c'
*
* @param {ve.dm.Change} change The document history
* @param {number} [commitLength] The point above which the transactions are uncommitted
* @param {number} [sentLength] The point above which the transactions are unsent
* @return {string} Compact summary of the history
*/
ve.dm.TestRebaseClient.static.historySummary = function ( change, commitLength, sentLength ) {
const parts = [];
if ( commitLength === undefined ) {
commitLength = change.transactions.length;
}
if ( sentLength === undefined ) {
sentLength = change.transactions.length;
}
const committed = change.transactions.slice( 0, commitLength );
const sent = change.transactions.slice( commitLength, sentLength );
const unsent = change.transactions.slice( sentLength );
function joinText( transactions ) {
return transactions.map( ( transaction ) => transaction.operations.filter( ( op ) => op.type === 'replace' ).map( ( op ) => {
const text = [];
if ( op.remove.length ) {
text.push( '-(' + op.remove.map( ( item ) => item[ 0 ] ).join( '' ) + ')' );
}
if ( op.insert.length ) {
text.push( op.insert.map( ( item ) => item[ 0 ] ).join( '' ) );
}
return text.join( '' );
} ).join( '' ) ).join( '' );
}
if ( committed.length ) {
parts.push( joinText( committed ) );
}
if ( sent.length ) {
parts.push( joinText( sent ) + '?' );
}
if ( unsent.length ) {
parts.push( joinText( unsent ) + '!' );
}
return parts.join( '/' );
};
ve.dm.TestRebaseClient.prototype.getHistorySummary = function () {
return this.constructor.static.historySummary( this.getChangeSince( 0 ), this.commitLength, this.sentLength );
};
ve.dm.TestRebaseClient.prototype.getChangeSince = function ( start ) {
return this.doc.getChangeSince( start );
};
ve.dm.TestRebaseClient.prototype.sendChange = function ( backtrack, change ) {
this.outgoing.push( { backtrack: backtrack, change: change } );
};
ve.dm.TestRebaseClient.prototype.applyChange = function ( change ) {
change.applyTo( this.surface );
};
ve.dm.TestRebaseClient.prototype.applyTransactions = function ( txs ) {
const authorId = this.getAuthorId();
txs.forEach( ( transaction ) => {
if ( transaction.authorId === null ) {
transaction.authorId = authorId;
}
} );
this.surface.change( txs );
};
ve.dm.TestRebaseClient.prototype.unapplyChange = function ( change ) {
change.unapplyTo( this.surface );
};
ve.dm.TestRebaseClient.prototype.addToHistory = function ( change ) {
change.addToHistory( this.doc );
};
ve.dm.TestRebaseClient.prototype.removeFromHistory = function ( change ) {
change.removeFromHistory( this.doc );
};
ve.dm.TestRebaseClient.prototype.deliverOne = function () {
const item = this.outgoing[ this.outgoingPointer++ ];
const rebased = this.server.applyChange(
ve.dm.TestRebaseServer.static.fakeDocName,
this.getAuthorId(),
item.backtrack,
item.change
);
if ( !rebased.isEmpty() ) {
this.server.incoming.push( rebased );
}
};
ve.dm.TestRebaseClient.prototype.receiveOne = function () {
this.acceptChange( this.server.incoming[ this.incomingPointer++ ] );
};
|