@@ -148,16 +148,24 @@ export function transform( a, b, context = {} ) {
148
148
* @returns {Object } Transformation result.
149
149
* @returns {Array.<module:engine/model/operation/operation~Operation> } return.operationsA Transformed `operationsA`.
150
150
* @returns {Array.<module:engine/model/operation/operation~Operation> } return.operationsB Transformed `operationsB`.
151
+ * @returns {Map } return.originalOperations A map that links transformed operations to original operations. The keys are the transformed
152
+ * operations and the values are the original operations from the input (`operationsA` and `operationsB`).
151
153
*/
152
154
export function transformSets ( operationsA , operationsB , options ) {
153
155
// Create new arrays so the originally passed arguments are not changed.
154
156
// No need to clone operations, they are cloned as they are transformed.
155
157
operationsA = operationsA . slice ( ) ;
156
158
operationsB = operationsB . slice ( ) ;
157
159
160
+ const contextFactory = new ContextFactory ( options . document , options . useRelations , options . forceWeakRemove ) ;
161
+ contextFactory . setOriginalOperations ( operationsA ) ;
162
+ contextFactory . setOriginalOperations ( operationsB ) ;
163
+
164
+ const originalOperations = contextFactory . originalOperations ;
165
+
158
166
// If one of sets is empty there is simply nothing to transform, so return sets as they are.
159
167
if ( operationsA . length == 0 || operationsB . length == 0 ) {
160
- return { operationsA, operationsB } ;
168
+ return { operationsA, operationsB, originalOperations } ;
161
169
}
162
170
//
163
171
// Following is a description of transformation process:
@@ -305,10 +313,6 @@ export function transformSets( operationsA, operationsB, options ) {
305
313
originalOperationsBCount : operationsB . length
306
314
} ;
307
315
308
- const contextFactory = new ContextFactory ( options . document , options . useRelations , options . forceWeakRemove ) ;
309
- contextFactory . setOriginalOperations ( operationsA ) ;
310
- contextFactory . setOriginalOperations ( operationsB ) ;
311
-
312
316
// Index of currently transformed operation `a`.
313
317
let i = 0 ;
314
318
@@ -374,7 +378,7 @@ export function transformSets( operationsA, operationsB, options ) {
374
378
updateBaseVersions ( operationsA , data . nextBaseVersionB ) ;
375
379
updateBaseVersions ( operationsB , data . nextBaseVersionA ) ;
376
380
377
- return { operationsA, operationsB } ;
381
+ return { operationsA, operationsB, originalOperations } ;
378
382
}
379
383
380
384
// Gathers additional data about operations processed during transformation. Can be used to obtain contextual information
@@ -388,6 +392,13 @@ class ContextFactory {
388
392
// @param {Boolean } [forceWeakRemove=false] If set to `false`, remove operation will be always stronger than move operation,
389
393
// so the removed nodes won't end up back in the document root. When set to `true`, context data will be used.
390
394
constructor ( document , useRelations , forceWeakRemove = false ) {
395
+ // For each operation that is created during transformation process, we keep a reference to the original operation
396
+ // which it comes from. The original operation works as a kind of "identifier". Every contextual information
397
+ // gathered during transformation that we want to save for given operation, is actually saved for the original operation.
398
+ // This way no matter if operation `a` is cloned, then transformed, even breaks, we still have access to the previously
399
+ // gathered data through original operation reference.
400
+ this . originalOperations = new Map ( ) ;
401
+
391
402
// `model.History` instance which information about undone operations will be taken from.
392
403
this . _history = document . history ;
393
404
@@ -396,13 +407,6 @@ class ContextFactory {
396
407
397
408
this . _forceWeakRemove = ! ! forceWeakRemove ;
398
409
399
- // For each operation that is created during transformation process, we keep a reference to the original operation
400
- // which it comes from. The original operation works as a kind of "identifier". Every contextual information
401
- // gathered during transformation that we want to save for given operation, is actually saved for the original operation.
402
- // This way no matter if operation `a` is cloned, then transformed, even breaks, we still have access to the previously
403
- // gathered data through original operation reference.
404
- this . _originalOperations = new Map ( ) ;
405
-
406
410
// Relations is a double-map structure (maps in map) where for two operations we store how those operations were related
407
411
// to each other. Those relations are evaluated during transformation process. For every transformated pair of operations
408
412
// we keep relations between them.
@@ -428,10 +432,10 @@ class ContextFactory {
428
432
// @param {Array.<module:engine/model/operation/operation~Operation> } operations
429
433
// @param {module:engine/model/operation/operation~Operation|null } [takeFrom=null]
430
434
setOriginalOperations ( operations , takeFrom = null ) {
431
- const originalOperation = takeFrom ? this . _originalOperations . get ( takeFrom ) : null ;
435
+ const originalOperation = takeFrom ? this . originalOperations . get ( takeFrom ) : null ;
432
436
433
437
for ( const operation of operations ) {
434
- this . _originalOperations . set ( operation , originalOperation || operation ) ;
438
+ this . originalOperations . set ( operation , originalOperation || operation ) ;
435
439
}
436
440
}
437
441
@@ -605,7 +609,7 @@ class ContextFactory {
605
609
// For `op`, get its original operation. After all, if `op` is a clone (or even transformed clone) of another
606
610
// operation, literally `op` couldn't be undone. It was just generated. If anything, it was the operation it origins
607
611
// from which was undone. So get that original operation.
608
- const originalOp = this . _originalOperations . get ( op ) ;
612
+ const originalOp = this . originalOperations . get ( op ) ;
609
613
610
614
// And check with the document if the original operation was undone.
611
615
return originalOp . wasUndone || this . _history . isUndoneOperation ( originalOp ) ;
@@ -637,15 +641,15 @@ class ContextFactory {
637
641
// @returns {String|null }
638
642
_getRelation ( opA , opB ) {
639
643
// Get the original operation. Similarly as in `wasUndone()` it is used as an universal identifier for stored data.
640
- const origB = this . _originalOperations . get ( opB ) ;
644
+ const origB = this . originalOperations . get ( opB ) ;
641
645
const undoneB = this . _history . getUndoneOperation ( origB ) ;
642
646
643
647
// If `opB` is not undoing any operation, there is no relation.
644
648
if ( ! undoneB ) {
645
649
return null ;
646
650
}
647
651
648
- const origA = this . _originalOperations . get ( opA ) ;
652
+ const origA = this . originalOperations . get ( opA ) ;
649
653
const relationsA = this . _relations . get ( origA ) ;
650
654
651
655
// Get all relations for `opA`, and check if there is a relation with `opB`-undone-counterpart. If so, return it.
@@ -664,8 +668,8 @@ class ContextFactory {
664
668
// @param {String } relation
665
669
_setRelation ( opA , opB , relation ) {
666
670
// As always, setting is for original operations, not the clones/transformed operations.
667
- const origA = this . _originalOperations . get ( opA ) ;
668
- const origB = this . _originalOperations . get ( opB ) ;
671
+ const origA = this . originalOperations . get ( opA ) ;
672
+ const origB = this . originalOperations . get ( opB ) ;
669
673
670
674
let relationsA = this . _relations . get ( origA ) ;
671
675
0 commit comments