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

Commit

Permalink
Feature: Introduced conversion.Mapper#flushUnboundMarkers.
Browse files Browse the repository at this point in the history
  • Loading branch information
scofalik committed Aug 16, 2019
1 parent 4eb6210 commit 3f4f603
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 39 deletions.
4 changes: 1 addition & 3 deletions src/conversion/downcastdispatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,13 @@ export default class DowncastDispatcher {
}
}

for ( const markerName of this.conversionApi.mapper._unboundMarkers ) {
for ( const markerName of this.conversionApi.mapper.flushUnboundMarkerNames() ) {
const markerRange = markers.get( markerName ).getRange();

this.convertMarkerRemove( markerName, markerRange, writer );
this.convertMarkerAdd( markerName, markerRange, writer );
}

this.conversionApi.mapper._unboundMarkers.clear();

// After the view is updated, convert markers which have changed.
for ( const change of differ.getMarkersToAdd() ) {
this.convertMarkerAdd( change.name, change.range, writer );
Expand Down
48 changes: 30 additions & 18 deletions src/conversion/mapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,13 @@ export default class Mapper {
this._elementToMarkerNames = new Map();

/**
* Stores markers which has changed due to unbinding a view element (so it is assumed that the view element has been removed,
* moved or renamed). In some cases such markers need to be refreshed (re-rendered).
* Stores marker names of markers which has changed due to unbinding a view element (so it is assumed that the view element
* has been removed, moved or renamed).
*
* @protected
* @private
* @member {Set.<module:engine/model/markercollection~Marker>}
*/
this._unboundMarkers = new Set();
this._unboundMarkerNames = new Set();

// Default mapper algorithm for mapping model position to view position.
this.on( 'modelToViewPosition', ( evt, data ) => {
Expand Down Expand Up @@ -153,7 +153,7 @@ export default class Mapper {

if ( this._elementToMarkerNames.has( viewElement ) ) {
for ( const markerName of this._elementToMarkerNames.get( viewElement ) ) {
this._unboundMarkers.add( markerName );
this._unboundMarkerNames.add( markerName );
}
}

Expand Down Expand Up @@ -208,29 +208,41 @@ export default class Mapper {
* @param {String} name Marker name.
*/
unbindElementFromMarkerName( element, name ) {
const elements = this._markerNameToElements.get( name );

if ( !elements ) {
return;
}
const nameToElements = this._markerNameToElements.get( name );

elements.delete( element );
if ( nameToElements ) {
nameToElements.delete( element );

if ( elements.size == 0 ) {
this._markerNameToElements.delete( name );
if ( nameToElements.size == 0 ) {
this._markerNameToElements.delete( name );
}
}

const names = this._elementToMarkerNames.get( element );
const elementToNames = this._elementToMarkerNames.get( element );

if ( names ) {
names.delete( name );
if ( elementToNames ) {
elementToNames.delete( name );

if ( names.size == 0 ) {
if ( elementToNames.size == 0 ) {
this._elementToMarkerNames.delete( element );
}
}
}

/**
* Returns all marker names of markers which has changed due to unbinding a view element (so it is assumed that the view element
* has been removed, moved or renamed) since the last flush. After returning, the marker names list is cleared.
*
* @returns {Array.<String>}
*/
flushUnboundMarkerNames() {
const markerNames = Array.from( this._unboundMarkerNames );

this._unboundMarkerNames.clear();

return markerNames;
}

/**
* Removes all model to view and view to model bindings.
*/
Expand All @@ -239,7 +251,7 @@ export default class Mapper {
this._viewToModelMapping = new WeakMap();
this._markerNameToElements = new Map();
this._elementToMarkerNames = new Map();
this._unboundMarkers = new Set();
this._unboundMarkerNames = new Set();
}

/**
Expand Down
42 changes: 24 additions & 18 deletions tests/conversion/mapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ describe( 'Mapper', () => {
expect( Array.from( mapper.markerNameToElements( 'foo' ) ) ).to.deep.equal( [ viewA, viewD ] );

mapper.unbindViewElement( viewD );
expect( Array.from( mapper._unboundMarkers ) ).to.deep.equal( [ 'foo', 'bar' ] );

mapper.clearBindings();

expect( mapper.toModelElement( viewA ) ).to.be.undefined;
Expand All @@ -65,7 +63,7 @@ describe( 'Mapper', () => {
expect( mapper.toViewElement( modelC ) ).to.be.undefined;

expect( mapper.markerNameToElements( 'foo' ) ).to.be.null;
expect( Array.from( mapper._unboundMarkers ) ).to.deep.equal( [] );
expect( mapper.flushUnboundMarkerNames() ).to.deep.equal( [] );
} );
} );

Expand Down Expand Up @@ -139,21 +137,6 @@ describe( 'Mapper', () => {
expect( mapper.toModelElement( viewA ) ).to.be.undefined;
expect( mapper.toViewElement( modelA ) ).to.equal( viewB );
} );

it( 'should add marker names to _unboundMarkers set', () => {
const viewA = new ViewElement( 'a' );
const modelA = new ModelElement( 'a' );

const mapper = new Mapper();
mapper.bindElements( modelA, viewA );

mapper.bindElementToMarker( viewA, 'foo' );
mapper.bindElementToMarker( viewA, 'bar' );

mapper.unbindViewElement( viewA );

expect( Array.from( mapper._unboundMarkers ) ).to.deep.equal( [ 'foo', 'bar' ] );
} );
} );

describe( 'Standard mapping', () => {
Expand Down Expand Up @@ -784,4 +767,27 @@ describe( 'Mapper', () => {
expect( viewMappedAncestor ).to.equal( viewP );
} );
} );

describe( 'flushUnboundMarkerNames()', () => {
it( 'should return marker names of markers which elements has been unbound and clear that list', () => {
const viewA = new ViewElement( 'a' );
const viewB = new ViewElement( 'b' );

const mapper = new Mapper();

mapper.bindElementToMarker( viewA, 'foo' );
mapper.bindElementToMarker( viewA, 'bar' );
mapper.bindElementToMarker( viewB, 'bar' );

mapper.unbindViewElement( viewA );

expect( mapper.flushUnboundMarkerNames() ).to.deep.equal( [ 'foo', 'bar' ] );
expect( mapper.flushUnboundMarkerNames() ).to.deep.equal( [] );

mapper.unbindViewElement( viewB );

expect( mapper.flushUnboundMarkerNames() ).to.deep.equal( [ 'bar' ] );
expect( mapper.flushUnboundMarkerNames() ).to.deep.equal( [] );
} );
} );
} );

0 comments on commit 3f4f603

Please sign in to comment.