Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Merge 38b6f53 into 0821d90
Browse files Browse the repository at this point in the history
  • Loading branch information
scofalik committed Oct 1, 2018
2 parents 0821d90 + 38b6f53 commit c94141f
Show file tree
Hide file tree
Showing 30 changed files with 569 additions and 2,764 deletions.
17 changes: 2 additions & 15 deletions src/dev-utils/enableenginedebug.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ import MoveOperation from '../model/operation/moveoperation';
import NoOperation from '../model/operation/nooperation';
import RenameOperation from '../model/operation/renameoperation';
import RootAttributeOperation from '../model/operation/rootattributeoperation';
import WrapOperation from '../model/operation/wrapoperation';
import UnwrapOperation from '../model/operation/unwrapoperation';
import SplitOperation from '../model/operation/splitoperation';
import MergeOperation from '../model/operation/mergeoperation';
import Model from '../model/model';
Expand Down Expand Up @@ -357,19 +355,8 @@ function enableLoggingTools() {
} );

sandbox.mock( SplitOperation.prototype, 'toString', function() {
return getClassName( this ) + `( ${ this.baseVersion } ): ` +
`${ this.position } ( ${ this.howMany } )${ this.graveyardPosition ? ', ' + this.graveyardPosition : '' }`;
} );

sandbox.mock( WrapOperation.prototype, 'toString', function() {
const range = ModelRange.createFromPositionAndShift( this.position, this.howMany );

return getClassName( this ) + `( ${ this.baseVersion } ): ` +
`${ range } with ${ this.element ? this.element : this.graveyardPosition }`;
} );

sandbox.mock( UnwrapOperation.prototype, 'toString', function() {
return getClassName( this ) + `( ${ this.baseVersion } ): ${ this.position } ( ${ this.howMany } ), ${ this.graveyardPosition }`;
return getClassName( this ) + `( ${ this.baseVersion } ): ${ this.splitPosition } ` +
`( ${ this.howMany } ) -> ${ this.insertionPosition }${ this.graveyardPosition ? ' with ' + this.graveyardPosition : '' }`;
} );

sandbox.mock( ViewText.prototype, 'toString', function() {
Expand Down
54 changes: 6 additions & 48 deletions src/model/differ.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,23 +181,21 @@ export default class Differ {
break;
}
case 'split': {
const splitElement = operation.position.parent;
const splitElement = operation.splitPosition.parent;

// Mark that children of the split element were removed.
if ( !this._isInInsertedElement( splitElement ) ) {
this._markRemove( splitElement, operation.position.offset, operation.howMany );
this._markRemove( splitElement, operation.splitPosition.offset, operation.howMany );
}

// Mark that the new element (split copy) was inserted.
if ( !this._isInInsertedElement( splitElement.parent ) ) {
this._markInsert( splitElement.parent, operation.insertionPosition.offset, 1 );
if ( !this._isInInsertedElement( operation.insertionPosition.parent ) ) {
this._markInsert( operation.insertionPosition.parent, operation.insertionPosition.offset, 1 );
}

// If the split took the element from the graveyard, mark that the element from the graveyard was removed.
if ( operation.graveyardPosition ) {
const graveyardParent = operation.graveyardPosition.parent;

this._markRemove( graveyardParent, operation.graveyardPosition.offset, 1 );
this._markRemove( operation.graveyardPosition.parent, operation.graveyardPosition.offset, 1 );
}

break;
Expand All @@ -211,13 +209,9 @@ export default class Differ {
}

// Mark that the merged element was inserted into graveyard.
// The `isInsertedElement` check might not be needed but there is one case in OT where merged element
// is inserted into wrapping element.
const graveyardParent = operation.graveyardPosition.parent;

if ( !this._isInInsertedElement( graveyardParent ) ) {
this._markInsert( graveyardParent, operation.graveyardPosition.offset, 1 );
}
this._markInsert( graveyardParent, operation.graveyardPosition.offset, 1 );

// Mark that children of merged element were inserted at new parent.
const mergedIntoElement = operation.targetPosition.parent;
Expand All @@ -226,42 +220,6 @@ export default class Differ {
this._markInsert( mergedIntoElement, operation.targetPosition.offset, mergedElement.maxOffset );
}

break;
}
case 'wrap': {
// Mark that some elements were removed from their original parent and that a new (wrapper) element
// was added in that parent.
if ( !this._isInInsertedElement( operation.position.parent ) ) {
this._markRemove( operation.position.parent, operation.position.offset, operation.howMany );
this._markInsert( operation.position.parent, operation.position.offset, 1 );
}

// If the wrap took the element from the graveyard, mark that the element from the graveyard was removed.
if ( operation.graveyardPosition ) {
const graveyardParent = operation.graveyardPosition.parent;

this._markRemove( graveyardParent, operation.graveyardPosition.offset, 1 );
}

break;
}
case 'unwrap': {
// Mark that the unwrapped element was removed from its original parent and that new (unwrapped) nodes
// were inserted in that parent.
const elementToUnwrap = operation.position.parent;
const offset = elementToUnwrap.startOffset;
const parent = elementToUnwrap.parent;

if ( !this._isInInsertedElement( parent ) ) {
this._markRemove( parent, offset, 1 );
this._markInsert( parent, offset, elementToUnwrap.maxOffset );
}

// Mark that the unwrapped element was moved to the graveyard.
const graveyardParent = operation.graveyardPosition.parent;

this._markInsert( graveyardParent, operation.graveyardPosition.offset, 1 );

break;
}
}
Expand Down
5 changes: 2 additions & 3 deletions src/model/liverange.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,6 @@ function transform( operation ) {
function doesOperationChangeRangeContent( range, operation ) {
switch ( operation.type ) {
case 'insert':
case 'split':
case 'wrap':
case 'unwrap':
return range.containsPosition( operation.position );
case 'move':
case 'remove':
Expand All @@ -181,6 +178,8 @@ function doesOperationChangeRangeContent( range, operation ) {
return range.containsPosition( operation.sourcePosition ) ||
range.start.isEqual( operation.sourcePosition ) ||
range.containsPosition( operation.targetPosition );
case 'split':
return range.containsPosition( operation.splitPosition ) || range.containsPosition( operation.insertionPosition );
}

return false;
Expand Down
13 changes: 12 additions & 1 deletion src/model/operation/mergeoperation.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,18 @@ export default class MergeOperation extends Operation {
* @returns {module:engine/model/operation/splitoperation~SplitOperation}
*/
getReversed() {
return new SplitOperation( this.targetPosition, this.howMany, this.graveyardPosition, this.baseVersion + 1 );
// Positions in this method are transformed by this merge operation because the split operation bases on
// the context after this merge operation happened (because split operation reverses it).
// So we need to acknowledge that the merge operation happened and those positions changed a little.
const targetPosition = this.targetPosition._getTransformedByMergeOperation( this );

const path = this.sourcePosition.path.slice( 0, -1 );
const insertionPosition = new Position( this.sourcePosition.root, path )._getTransformedByMergeOperation( this );

const split = new SplitOperation( targetPosition, this.howMany, this.graveyardPosition, this.baseVersion + 1 );
split.insertionPosition = insertionPosition;

return split;
}

/**
Expand Down
4 changes: 0 additions & 4 deletions src/model/operation/operationfactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import RenameOperation from '../operation/renameoperation';
import RootAttributeOperation from '../operation/rootattributeoperation';
import SplitOperation from '../operation/splitoperation';
import MergeOperation from '../operation/mergeoperation';
import WrapOperation from '../operation/wrapoperation';
import UnwrapOperation from '../operation/unwrapoperation';

const operations = {};
operations[ AttributeOperation.className ] = AttributeOperation;
Expand All @@ -31,8 +29,6 @@ operations[ RenameOperation.className ] = RenameOperation;
operations[ RootAttributeOperation.className ] = RootAttributeOperation;
operations[ SplitOperation.className ] = SplitOperation;
operations[ MergeOperation.className ] = MergeOperation;
operations[ WrapOperation.className ] = WrapOperation;
operations[ UnwrapOperation.className ] = UnwrapOperation;

/**
* A factory class for creating operations.
Expand Down
Loading

0 comments on commit c94141f

Please sign in to comment.