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

Commit

Permalink
Added ablity to change marker type at runtime.
Browse files Browse the repository at this point in the history
  • Loading branch information
ma2ciek committed Feb 5, 2018
1 parent edfeb99 commit 652db9d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 15 deletions.
10 changes: 1 addition & 9 deletions src/model/markercollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,7 @@ export default class MarkerCollection {
if ( oldMarker ) {
const oldRange = oldMarker.getRange();

if ( managedUsingOperations !== oldMarker.managedUsingOperations ) {
/**
* Marker's type should be consistent. Provide correct `managedUsingOperations` parameter.
*/
throw new CKEditorError( 'marker-set-incorrect-marker-type:' +
' Marker\'s type should be consistent. Provide correct `managedUsingOperations` parameter.' );
}

if ( oldRange.isEqual( range ) ) {
if ( oldRange.isEqual( range ) && managedUsingOperations === oldMarker.managedUsingOperations ) {
return oldMarker;
}

Expand Down
10 changes: 8 additions & 2 deletions src/model/writer.js
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,8 @@ export default class Writer {
}
}

const currentMarker = this.model.markers.get( markerName );

if ( !usingOperation ) {
if ( !newRange ) {
/**
Expand All @@ -846,11 +848,15 @@ export default class Writer {
throw new CKEditorError( 'writer-setMarker-no-range: Range parameter is required when adding a new marker.' );
}

// If marker changes to marker that do not use operations then we need to create additional operation
// that removes that marker first.
if ( currentMarker && currentMarker.managedUsingOperations && !usingOperation ) {
applyMarkerOperation( this, markerName, currentMarker.getRange(), null );
}

return this.model.markers._set( markerName, newRange, usingOperation );
}

const currentMarker = this.model.markers.get( markerName );

if ( !newRange && !currentMarker ) {
throw new CKEditorError( 'writer-setMarker-no-range: Range parameter is required when adding a new marker.' );
}
Expand Down
35 changes: 31 additions & 4 deletions tests/model/writer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2076,12 +2076,39 @@ describe( 'Writer', () => {
} ).to.throw( CKEditorError, /^writer-setMarker-no-range/ );
} );

it( 'should throw if marker is updated incorrectly', () => {
it( 'should create additional operation when marker type changes to not managed using operation', () => {
const spy = sinon.spy();
model.on( 'applyOperation', spy );

setMarker( 'name', range, { usingOperation: true } );
const marker = setMarker( 'name', range );
const op1 = batch.deltas[ 0 ].operations[ 0 ];
const op2 = batch.deltas[ 1 ].operations[ 0 ];

expect( spy.calledTwice ).to.be.true;
expect( spy.firstCall.args[ 1 ][ 0 ].type ).to.equal( 'marker' );
expect( spy.secondCall.args[ 1 ][ 0 ].type ).to.equal( 'marker' );

expect( op1.oldRange ).to.be.null;
expect( op1.newRange.isEqual( range ) ).to.be.true;

expect( op2.oldRange.isEqual( range ) ).to.be.true;
expect( op2.newRange ).to.be.null;

expect( marker.managedUsingOperations ).to.be.false;
} );

it( 'should enable changing marker to be not managed using operation', () => {
const spy = sinon.spy();
model.on( 'applyOperation', spy );

setMarker( 'name', range );
const marker = setMarker( 'name', range, { usingOperation: true } );

expect( () => {
setMarker( 'name', range, { usingOperation: true } );
} ).to.throw( CKEditorError, /^marker-set-incorrect-marker-type/ );
expect( spy.calledOnce ).to.be.true;
expect( spy.firstCall.args[ 1 ][ 0 ].type ).to.equal( 'marker' );

expect( marker.managedUsingOperations ).to.be.true;
} );

it( 'should throw when trying to use detached writer', () => {
Expand Down

0 comments on commit 652db9d

Please sign in to comment.