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

Commit

Permalink
Merge pull request #1498 from ckeditor/t/1488
Browse files Browse the repository at this point in the history
Internal: Added `MergeOperation#howMany` and `SplitOperation#howMany`. Improvements in `Position` and `Range` transforming functions. Improvements in OT algorithms. Closes #1488. Closes #1492. Closes #1499.
  • Loading branch information
Piotr Jasiun committed Aug 9, 2018
2 parents 74f00e9 + da9b4ac commit e334195
Show file tree
Hide file tree
Showing 13 changed files with 512 additions and 216 deletions.
18 changes: 14 additions & 4 deletions src/model/operation/mergeoperation.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ export default class MergeOperation extends Operation {
*
* @param {module:engine/model/position~Position} sourcePosition Position inside the merged element. All nodes from that
* element after that position will be moved to {@link ~#targetPosition}.
* @param {Number} howMany Summary offset size of nodes which will be moved from the merged element to the new parent.
* @param {module:engine/model/position~Position} targetPosition Position which the nodes from the merged elements will be moved to.
* @param {module:engine/model/position~Position} graveyardPosition Position in graveyard to which the merged element will be moved.
* @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation
* can be applied or `null` if the operation operates on detached (non-document) tree.
*/
constructor( sourcePosition, targetPosition, graveyardPosition, baseVersion ) {
constructor( sourcePosition, howMany, targetPosition, graveyardPosition, baseVersion ) {
super( baseVersion );

/**
Expand All @@ -56,6 +57,8 @@ export default class MergeOperation extends Operation {
// is it? think about reversed split operations, undo, etc.

this.graveyardPosition = Position.createFromPosition( graveyardPosition );

this.howMany = howMany;
}

/**
Expand Down Expand Up @@ -94,7 +97,7 @@ export default class MergeOperation extends Operation {
* @returns {module:engine/model/operation/mergeoperation~MergeOperation} Clone of this operation.
*/
clone() {
return new this.constructor( this.sourcePosition, this.targetPosition, this.graveyardPosition, this.baseVersion );
return new this.constructor( this.sourcePosition, this.howMany, this.targetPosition, this.graveyardPosition, this.baseVersion );
}

/**
Expand All @@ -103,7 +106,7 @@ export default class MergeOperation extends Operation {
* @returns {module:engine/model/operation/splitoperation~SplitOperation}
*/
getReversed() {
return new SplitOperation( this.targetPosition, this.graveyardPosition, this.baseVersion + 1 );
return new SplitOperation( this.targetPosition, this.howMany, this.graveyardPosition, this.baseVersion + 1 );
}

/**
Expand All @@ -128,6 +131,13 @@ export default class MergeOperation extends Operation {
* @error merge-operation-target-position-invalid
*/
throw new CKEditorError( 'merge-operation-target-position-invalid: Merge target position is invalid.' );
} else if ( this.howMany != sourceElement.maxOffset ) {
/**
* Merge operation specifies wrong number of nodes to move.
*
* @error merge-operation-how-many-invalid
*/
throw new CKEditorError( 'merge-operation-how-many-invalid: Merge operation specifies wrong number of nodes to move.' );
}
}

Expand Down Expand Up @@ -161,6 +171,6 @@ export default class MergeOperation extends Operation {
const targetPosition = Position.fromJSON( json.targetPosition, document );
const graveyardPosition = Position.fromJSON( json.graveyardPosition, document );

return new this( sourcePosition, targetPosition, graveyardPosition, json.baseVersion );
return new this( sourcePosition, json.howMany, targetPosition, graveyardPosition, json.baseVersion );
}
}
18 changes: 14 additions & 4 deletions src/model/operation/splitoperation.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ export default class SplitOperation extends Operation {
* Creates a split operation.
*
* @param {module:engine/model/position~Position} position Position at which an element should be split.
* @param {Number}
* @param {module:engine/model/position~Position|null} graveyardPosition Position in graveyard before the element which
* should be used as a parent of the nodes after `position`. If it is not set, a copy of the the `position` parent will be used.
* @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation
* can be applied or `null` if the operation operates on detached (non-document) tree.
*/
constructor( position, graveyardPosition, baseVersion ) {
constructor( position, howMany, graveyardPosition, baseVersion ) {
super( baseVersion );

/**
Expand All @@ -47,6 +48,8 @@ export default class SplitOperation extends Operation {
if ( this.graveyardPosition ) {
this.graveyardPosition.stickiness = 'toNext';
}

this.howMany = howMany;
}

/**
Expand Down Expand Up @@ -104,7 +107,7 @@ export default class SplitOperation extends Operation {
* @returns {module:engine/model/operation/splitoperation~SplitOperation} Clone of this operation.
*/
clone() {
return new this.constructor( this.position, this.graveyardPosition, this.baseVersion );
return new this.constructor( this.position, this.howMany, this.graveyardPosition, this.baseVersion );
}

/**
Expand All @@ -116,7 +119,7 @@ export default class SplitOperation extends Operation {
const graveyard = this.position.root.document.graveyard;
const graveyardPosition = new Position( graveyard, [ 0 ] );

return new MergeOperation( this.moveTargetPosition, this.position, graveyardPosition, this.baseVersion + 1 );
return new MergeOperation( this.moveTargetPosition, this.howMany, this.position, graveyardPosition, this.baseVersion + 1 );
}

/**
Expand All @@ -134,6 +137,13 @@ export default class SplitOperation extends Operation {
* @error split-operation-position-invalid
*/
throw new CKEditorError( 'split-operation-position-invalid: Split position is invalid.' );
} else if ( this.howMany != element.maxOffset - this.position.offset ) {
/**
* Split operation specifies wrong number of nodes to move.
*
* @error split-operation-how-many-invalid
*/
throw new CKEditorError( 'split-operation-how-many-invalid: Split operation specifies wrong number of nodes to move.' );
}
}

Expand Down Expand Up @@ -174,6 +184,6 @@ export default class SplitOperation extends Operation {
const position = Position.fromJSON( json.position, document );
const graveyardPosition = json.graveyardPosition ? Position.fromJSON( json.graveyardPosition, document ) : null;

return new this( position, graveyardPosition, json.baseVersion );
return new this( position, json.howMany, graveyardPosition, json.baseVersion );
}
}

0 comments on commit e334195

Please sign in to comment.