From 8a9ffac72c98c0f5fb7de3001e8cc1a71c4a0011 Mon Sep 17 00:00:00 2001 From: Kuba Niegowski Date: Mon, 16 Nov 2020 18:59:42 +0100 Subject: [PATCH 1/8] DocumentSelection#markers not refreshed in post-fixing loop. On model markers change only changed markers are checked for DocumentSelection#markers collection. --- .../ckeditor5-engine/src/model/document.js | 2 +- .../src/model/documentselection.js | 49 ++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/packages/ckeditor5-engine/src/model/document.js b/packages/ckeditor5-engine/src/model/document.js index dabe7298c8c..63d246a6c68 100644 --- a/packages/ckeditor5-engine/src/model/document.js +++ b/packages/ckeditor5-engine/src/model/document.js @@ -399,7 +399,7 @@ export default class Document { // It might be good to refresh the selection after each operation but at the moment it leads // to losing attributes for composition or and spell checking // https://github.com/ckeditor/ckeditor5-typing/issues/188 - this.selection.refresh(); + this.selection.refreshAttributes(); wasFixed = callback( writer ); diff --git a/packages/ckeditor5-engine/src/model/documentselection.js b/packages/ckeditor5-engine/src/model/documentselection.js index 02ced517ff7..9704a114f81 100644 --- a/packages/ckeditor5-engine/src/model/documentselection.js +++ b/packages/ckeditor5-engine/src/model/documentselection.js @@ -364,6 +364,13 @@ export default class DocumentSelection { this._selection._updateAttributes( false ); } + /** + * Refreshes selection markers according to the current position in the model. + */ + refreshAttributes() { + this._selection._updateAttributes( false ); + } + /** * Checks whether this object is of the given type. * @@ -662,7 +669,9 @@ class LiveSelection extends Selection { } ); // Update markers data stored by the selection after each marker change. - this.listenTo( this._model.markers, 'update', () => this._updateMarkers() ); + this.listenTo( this._model.markers, 'update', ( evt, marker, oldRange, newRange ) => { + this._updateMarker( marker, oldRange, newRange ); + } ); // Ensure selection is up to date after each change block. this.listenTo( this._document, 'change', ( evt, batch ) => { @@ -882,6 +891,44 @@ class LiveSelection extends Selection { } } + _updateMarker( marker, oldRange, newRange ) { + if ( oldRange && newRange && oldRange.isEqual( newRange ) ) { + return; + } + + let changed = false; + + const oldMarkers = Array.from( this.markers ); + const markerRange = marker.getRange(); + + if ( oldRange && !newRange && this.markers.has( marker ) ) { + this.markers.remove( marker ); + changed = true; + } + + if ( !changed ) { + let contained = false; + + for ( const selectionRange of this.getRanges() ) { + if ( markerRange.containsRange( selectionRange, !selectionRange.isCollapsed ) ) { + contained = true; + + break; + } + } + + if ( contained && !this.markers.has( marker ) ) { + this.markers.add( marker ); + + changed = true; + } + } + + if ( changed ) { + this.fire( 'change:marker', { oldMarkers, directChange: false } ); + } + } + // Updates this selection attributes according to its ranges and the {@link module:engine/model/document~Document model document}. // // @protected From 42902073cae7e2e9171716657995e0c7b3347812 Mon Sep 17 00:00:00 2001 From: Kuba Niegowski Date: Thu, 19 Nov 2020 12:26:58 +0100 Subject: [PATCH 2/8] DocumentSelection#markers collection is only populated for registered marker groups. --- .../ckeditor5-engine/src/model/document.js | 2 +- .../src/model/documentselection.js | 44 +++- .../tests/model/documentselection.js | 220 ++++++++++++++---- 3 files changed, 214 insertions(+), 52 deletions(-) diff --git a/packages/ckeditor5-engine/src/model/document.js b/packages/ckeditor5-engine/src/model/document.js index 63d246a6c68..dabe7298c8c 100644 --- a/packages/ckeditor5-engine/src/model/document.js +++ b/packages/ckeditor5-engine/src/model/document.js @@ -399,7 +399,7 @@ export default class Document { // It might be good to refresh the selection after each operation but at the moment it leads // to losing attributes for composition or and spell checking // https://github.com/ckeditor/ckeditor5-typing/issues/188 - this.selection.refreshAttributes(); + this.selection.refresh(); wasFixed = callback( writer ); diff --git a/packages/ckeditor5-engine/src/model/documentselection.js b/packages/ckeditor5-engine/src/model/documentselection.js index 9704a114f81..6724b5110e0 100644 --- a/packages/ckeditor5-engine/src/model/documentselection.js +++ b/packages/ckeditor5-engine/src/model/documentselection.js @@ -151,11 +151,13 @@ export default class DocumentSelection { } /** - * A collection of selection markers. + * A collection of selection {@link module:engine/model/markercollection~Marker markers}. * Marker is a selection marker when selection range is inside the marker range. * + * **Note**: Only markers from {@link ~DocumentSelection#observeMarkersGroup observed markers groups} are collected. + * * @readonly - * @type {module:utils/collection~Collection.} + * @type {module:utils/collection~Collection} */ get markers() { return this._selection.markers; @@ -365,10 +367,14 @@ export default class DocumentSelection { } /** - * Refreshes selection markers according to the current position in the model. + * Registers marker group prefix to be collected in {@link ~DocumentSelection#markers selection markers collection}. + * + * See also {@link module:engine/model/markercollection~MarkerCollection#getMarkersGroup `MarkerCollection#getMarkersGroup()`}. + * + * @param {String} prefix Marker group prefix. */ - refreshAttributes() { - this._selection._updateAttributes( false ); + observeMarkersGroup( prefix ) { + this._selection.observeMarkersGroup( prefix ); } /** @@ -626,6 +632,11 @@ class LiveSelection extends Selection { // @type {Set} this._overriddenGravityRegister = new Set(); + // Prefixes of marker names that should affect this `LiveSelection#markers` collection. + // @private + // @type {Array.} + this._observedMarkerGroups = []; + // Ensure selection is correct after each operation. this.listenTo( this._model, 'applyOperation', ( evt, args ) => { const operation = args[ 0 ]; @@ -807,6 +818,11 @@ class LiveSelection extends Selection { } } + observeMarkersGroup( prefix ) { + this._observedMarkerGroups.push( prefix ); + this._updateMarkers(); + } + _popRange() { this._ranges.pop().detach(); } @@ -855,10 +871,20 @@ class LiveSelection extends Selection { } _updateMarkers() { + if ( !this._observedMarkerGroups.length ) { + return; + } + const markers = []; let changed = false; for ( const marker of this._model.markers ) { + const markerGroup = marker.name.split( ':', 1 )[ 0 ]; + + if ( !this._observedMarkerGroups.includes( markerGroup ) ) { + continue; + } + const markerRange = marker.getRange(); for ( const selectionRange of this.getRanges() ) { @@ -892,7 +918,13 @@ class LiveSelection extends Selection { } _updateMarker( marker, oldRange, newRange ) { - if ( oldRange && newRange && oldRange.isEqual( newRange ) ) { + if ( !this._observedMarkerGroups.length ) { + return; + } + + const markerGroup = marker.name.split( ':', 1 )[ 0 ]; + + if ( !this._observedMarkerGroups.includes( markerGroup ) ) { return; } diff --git a/packages/ckeditor5-engine/tests/model/documentselection.js b/packages/ckeditor5-engine/tests/model/documentselection.js index 3718eadb277..0bdc94d5d9d 100644 --- a/packages/ckeditor5-engine/tests/model/documentselection.js +++ b/packages/ckeditor5-engine/tests/model/documentselection.js @@ -205,13 +205,15 @@ describe( 'DocumentSelection', () => { } ); it( 'should add markers to the collection when selection is inside the marker range', () => { + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createRange( writer.createPositionFromPath( root, [ 2, 2 ] ), writer.createPositionFromPath( root, [ 2, 4 ] ) ) ); - writer.addMarker( 'marker-1', { + writer.addMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( root, [ 0, 0 ] ), writer.createPositionFromPath( root, [ 2, 2 ] ) @@ -219,7 +221,7 @@ describe( 'DocumentSelection', () => { usingOperation: false } ); - writer.addMarker( 'marker-2', { + writer.addMarker( 'marker:2', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 2 ] ), writer.createPositionFromPath( root, [ 2, 4 ] ) @@ -227,7 +229,7 @@ describe( 'DocumentSelection', () => { usingOperation: false } ); - writer.addMarker( 'marker-3', { + writer.addMarker( 'marker:3', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 1 ] ), writer.createPositionFromPath( root, [ 2, 5 ] ) @@ -235,7 +237,7 @@ describe( 'DocumentSelection', () => { usingOperation: false } ); - writer.addMarker( 'marker-4', { + writer.addMarker( 'marker:4', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 4 ] ), writer.createPositionFromPath( root, [ 3, 0 ] ) @@ -244,17 +246,19 @@ describe( 'DocumentSelection', () => { } ); } ); - expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'marker-2', 'marker-3' ] ); + expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'marker:2', 'marker:3' ] ); } ); it( 'should update markers after selection change', () => { + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createRange( writer.createPositionFromPath( root, [ 2, 1 ] ), writer.createPositionFromPath( root, [ 2, 2 ] ) ) ); - writer.addMarker( 'marker-1', { + writer.addMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 0 ] ), writer.createPositionFromPath( root, [ 2, 6 ] ) @@ -262,7 +266,7 @@ describe( 'DocumentSelection', () => { usingOperation: false } ); - writer.addMarker( 'marker-2', { + writer.addMarker( 'marker:2', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 0 ] ), writer.createPositionFromPath( root, [ 2, 3 ] ) @@ -270,7 +274,7 @@ describe( 'DocumentSelection', () => { usingOperation: false } ); - writer.addMarker( 'marker-3', { + writer.addMarker( 'marker:3', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 3 ] ), writer.createPositionFromPath( root, [ 2, 6 ] ) @@ -279,7 +283,7 @@ describe( 'DocumentSelection', () => { } ); } ); - expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'marker-1', 'marker-2' ] ); + expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'marker:1', 'marker:2' ] ); model.change( writer => { writer.setSelection( writer.createRange( @@ -288,17 +292,19 @@ describe( 'DocumentSelection', () => { ) ); } ); - expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'marker-1', 'marker-3' ] ); + expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'marker:1', 'marker:3' ] ); } ); it( 'should update markers after markers change', () => { + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createRange( writer.createPositionFromPath( root, [ 2, 1 ] ), writer.createPositionFromPath( root, [ 2, 2 ] ) ) ); - writer.addMarker( 'marker-1', { + writer.addMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 0 ] ), writer.createPositionFromPath( root, [ 2, 6 ] ) @@ -306,7 +312,7 @@ describe( 'DocumentSelection', () => { usingOperation: false } ); - writer.addMarker( 'marker-2', { + writer.addMarker( 'marker:2', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 0 ] ), writer.createPositionFromPath( root, [ 2, 3 ] ) @@ -314,7 +320,7 @@ describe( 'DocumentSelection', () => { usingOperation: false } ); - writer.addMarker( 'marker-3', { + writer.addMarker( 'marker:3', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 3 ] ), writer.createPositionFromPath( root, [ 2, 6 ] ) @@ -323,12 +329,12 @@ describe( 'DocumentSelection', () => { } ); } ); - expect( selection.markers.map( marker => marker.name ), 1 ).to.have.members( [ 'marker-1', 'marker-2' ] ); + expect( selection.markers.map( marker => marker.name ), 1 ).to.have.members( [ 'marker:1', 'marker:2' ] ); model.change( writer => { - writer.removeMarker( 'marker-1' ); + writer.removeMarker( 'marker:1' ); - writer.updateMarker( 'marker-2', { + writer.updateMarker( 'marker:2', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 3 ] ), writer.createPositionFromPath( root, [ 2, 6 ] ) @@ -336,7 +342,7 @@ describe( 'DocumentSelection', () => { usingOperation: false } ); - writer.updateMarker( 'marker-3', { + writer.updateMarker( 'marker:3', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 0 ] ), writer.createPositionFromPath( root, [ 2, 3 ] ) @@ -345,17 +351,19 @@ describe( 'DocumentSelection', () => { } ); } ); - expect( selection.markers.map( marker => marker.name ), 2 ).to.have.members( [ 'marker-3' ] ); + expect( selection.markers.map( marker => marker.name ), 2 ).to.have.members( [ 'marker:3' ] ); } ); it( 'should not add marker when collapsed selection is on the marker left bound', () => { + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createRange( writer.createPositionFromPath( root, [ 2, 2 ] ), writer.createPositionFromPath( root, [ 2, 4 ] ) ) ); - writer.addMarker( 'marker', { + writer.addMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 2 ] ) ), @@ -367,12 +375,14 @@ describe( 'DocumentSelection', () => { } ); it( 'should not add marker when collapsed selection is on the marker right bound', () => { + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createRange( writer.createPositionFromPath( root, [ 2, 4 ] ) ) ); - writer.addMarker( 'marker', { + writer.addMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 2 ] ), writer.createPositionFromPath( root, [ 2, 4 ] ) @@ -385,13 +395,15 @@ describe( 'DocumentSelection', () => { } ); it( 'should add marker when non-collapsed selection is inside a marker and touches the left bound', () => { + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createRange( writer.createPositionFromPath( root, [ 2, 1 ] ), writer.createPositionFromPath( root, [ 2, 3 ] ) ) ); - writer.addMarker( 'marker', { + writer.addMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 1 ] ), writer.createPositionFromPath( root, [ 2, 5 ] ) @@ -400,17 +412,19 @@ describe( 'DocumentSelection', () => { } ); } ); - expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'marker' ] ); + expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'marker:1' ] ); } ); it( 'should add marker when non-collapsed selection is inside a marker and touches the right bound', () => { + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createRange( writer.createPositionFromPath( root, [ 2, 2 ] ), writer.createPositionFromPath( root, [ 2, 5 ] ) ) ); - writer.addMarker( 'marker', { + writer.addMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 1 ] ), writer.createPositionFromPath( root, [ 2, 5 ] ) @@ -419,10 +433,12 @@ describe( 'DocumentSelection', () => { } ); } ); - expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'marker' ] ); + expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'marker:1' ] ); } ); it( 'should add marker of selected widget', () => { + selection.observeMarkersGroup( 'marker' ); + root._insertChild( 0, new Element( 'widget' ) ); model.change( writer => { @@ -431,7 +447,7 @@ describe( 'DocumentSelection', () => { writer.createPositionFromPath( root, [ 1 ] ) ) ); - writer.addMarker( 'marker', { + writer.addMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( root, [ 0 ] ), writer.createPositionFromPath( root, [ 1 ] ) @@ -440,14 +456,102 @@ describe( 'DocumentSelection', () => { } ); } ); - expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'marker' ] ); + expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'marker:1' ] ); + } ); + + it( 'should not add markers to the collection when markers observing is not enabled', () => { + model.change( writer => { + writer.setSelection( writer.createRange( + writer.createPositionFromPath( root, [ 2, 2 ] ), + writer.createPositionFromPath( root, [ 2, 4 ] ) + ) ); + + writer.addMarker( 'marker:1', { + range: writer.createRange( + writer.createPositionFromPath( root, [ 0, 0 ] ), + writer.createPositionFromPath( root, [ 2, 2 ] ) + ), + usingOperation: false + } ); + + writer.addMarker( 'marker:2', { + range: writer.createRange( + writer.createPositionFromPath( root, [ 2, 2 ] ), + writer.createPositionFromPath( root, [ 2, 4 ] ) + ), + usingOperation: false + } ); + + writer.addMarker( 'marker:3', { + range: writer.createRange( + writer.createPositionFromPath( root, [ 2, 1 ] ), + writer.createPositionFromPath( root, [ 2, 5 ] ) + ), + usingOperation: false + } ); + + writer.addMarker( 'marker:4', { + range: writer.createRange( + writer.createPositionFromPath( root, [ 2, 4 ] ), + writer.createPositionFromPath( root, [ 3, 0 ] ) + ), + usingOperation: false + } ); + } ); + + expect( selection.markers ).to.length( 0 ); + } ); + + it( 'should add markers to the collection when markers only for observed marker groups', () => { + selection.observeMarkersGroup( 'marker' ); + + model.change( writer => { + writer.setSelection( writer.createRange( + writer.createPositionFromPath( root, [ 2, 2 ] ), + writer.createPositionFromPath( root, [ 2, 4 ] ) + ) ); + + writer.addMarker( 'marker:1', { + range: writer.createRange( + writer.createPositionFromPath( root, [ 0, 0 ] ), + writer.createPositionFromPath( root, [ 2, 2 ] ) + ), + usingOperation: false + } ); + + writer.addMarker( 'marker:2', { + range: writer.createRange( + writer.createPositionFromPath( root, [ 2, 2 ] ), + writer.createPositionFromPath( root, [ 2, 4 ] ) + ), + usingOperation: false + } ); + + writer.addMarker( 'otherGroup:3', { + range: writer.createRange( + writer.createPositionFromPath( root, [ 2, 1 ] ), + writer.createPositionFromPath( root, [ 2, 5 ] ) + ), + usingOperation: false + } ); + + writer.addMarker( 'otherGroup:4', { + range: writer.createRange( + writer.createPositionFromPath( root, [ 2, 4 ] ), + writer.createPositionFromPath( root, [ 3, 0 ] ) + ), + usingOperation: false + } ); + } ); + + expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'marker:2' ] ); } ); describe( 'should fire change:marker event when', () => { // Set marker to range 0-4. beforeEach( () => { model.change( writer => { - writer.addMarker( 'marker-1', { + writer.addMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 0 ] ), writer.createPositionFromPath( root, [ 2, 4 ] ) @@ -460,6 +564,8 @@ describe( 'DocumentSelection', () => { it( 'selection ranges change (marker added to the selection)', () => { const spy = sinon.spy(); + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { // The selection has no markers before the change. model.document.selection.on( 'change:marker', ( evt, data ) => { @@ -480,6 +586,8 @@ describe( 'DocumentSelection', () => { it( 'selection ranges change (marker removed from the selection)', () => { const spy = sinon.spy(); + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createRange( writer.createPositionFromPath( root, [ 2, 1 ] ), @@ -488,7 +596,7 @@ describe( 'DocumentSelection', () => { // The selection is in a marker before the change. model.document.selection.on( 'change:marker', ( evt, data ) => { - expect( data.oldMarkers.map( marker => marker.name ) ).to.deep.equal( [ 'marker-1' ] ); + expect( data.oldMarkers.map( marker => marker.name ) ).to.deep.equal( [ 'marker:1' ] ); spy(); } ); @@ -502,12 +610,14 @@ describe( 'DocumentSelection', () => { it( 'selection focus changes (marker removed from the selection)', () => { const spy = sinon.spy(); + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createPositionFromPath( root, [ 2, 2 ] ) ); // The selection is in a marker before the change. model.document.selection.on( 'change:marker', ( evt, data ) => { - expect( data.oldMarkers.map( marker => marker.name ) ).to.deep.equal( [ 'marker-1' ] ); + expect( data.oldMarkers.map( marker => marker.name ) ).to.deep.equal( [ 'marker:1' ] ); spy(); } ); @@ -521,6 +631,8 @@ describe( 'DocumentSelection', () => { it( 'a new marker contains the selection', () => { const spy = sinon.spy(); + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createPositionFromPath( root, [ 2, 5 ] ) ); @@ -530,7 +642,7 @@ describe( 'DocumentSelection', () => { spy(); } ); - writer.updateMarker( 'marker-1', { + writer.updateMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 0 ] ), writer.createPositionFromPath( root, [ 2, 6 ] ) @@ -544,16 +656,18 @@ describe( 'DocumentSelection', () => { it( 'a marker stops contains the selection', () => { const spy = sinon.spy(); + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createPositionFromPath( root, [ 2, 3 ] ) ); // The selection is in a marker before the change. model.document.selection.on( 'change:marker', ( evt, data ) => { - expect( data.oldMarkers.map( marker => marker.name ) ).to.deep.equal( [ 'marker-1' ] ); + expect( data.oldMarkers.map( marker => marker.name ) ).to.deep.equal( [ 'marker:1' ] ); spy(); } ); - writer.updateMarker( 'marker-1', { + writer.updateMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 0 ] ), writer.createPositionFromPath( root, [ 2, 1 ] ) @@ -569,7 +683,7 @@ describe( 'DocumentSelection', () => { // Set marker to range 0-4. beforeEach( () => { model.change( writer => { - writer.addMarker( 'marker-1', { + writer.addMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 0 ] ), writer.createPositionFromPath( root, [ 2, 4 ] ) @@ -582,6 +696,8 @@ describe( 'DocumentSelection', () => { it( 'selection ranges change does not change selection markers (no markers)', () => { const spy = sinon.spy(); + selection.observeMarkersGroup( 'marker' ); + model.document.selection.on( 'change:marker', spy ); model.change( writer => { @@ -592,6 +708,8 @@ describe( 'DocumentSelection', () => { } ); it( 'selection ranges change does not change selection markers (same markers)', () => { + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createPositionFromPath( root, [ 2, 2 ] ) ); } ); @@ -608,6 +726,8 @@ describe( 'DocumentSelection', () => { } ); it( 'selection focus change does not change selection markers', () => { + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createPositionFromPath( root, [ 2, 2 ] ) ); } ); @@ -624,6 +744,8 @@ describe( 'DocumentSelection', () => { } ); it( 'changed marker still contains the selection', () => { + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createPositionFromPath( root, [ 2, 2 ] ) ); } ); @@ -633,7 +755,7 @@ describe( 'DocumentSelection', () => { model.document.selection.on( 'change:marker', spy ); model.change( writer => { - writer.updateMarker( 'marker-1', { + writer.updateMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( root, [ 2, 0 ] ), writer.createPositionFromPath( root, [ 2, 5 ] ) @@ -645,6 +767,8 @@ describe( 'DocumentSelection', () => { } ); it( 'removed marker did not contain the selection', () => { + selection.observeMarkersGroup( 'marker' ); + model.change( writer => { writer.setSelection( writer.createPositionFromPath( root, [ 2, 5 ] ) ); } ); @@ -654,7 +778,7 @@ describe( 'DocumentSelection', () => { model.document.selection.on( 'change:marker', spy ); model.change( writer => { - writer.removeMarker( 'marker-1' ); + writer.removeMarker( 'marker:1' ); } ); expect( spy.called ).to.be.false; @@ -1385,15 +1509,17 @@ describe( 'DocumentSelection', () => { const p = doc.getRoot().getChild( 0 ); + selection.observeMarkersGroup( 'marker' ); + doc.registerPostFixer( () => { expect( model.document.selection.getAttribute( 'foo' ) ).to.equal( 'bar' ); - expect( Array.from( model.document.selection.markers, m => m.name ) ).to.deep.equal( [ 'marker' ] ); + expect( Array.from( model.document.selection.markers, m => m.name ) ).to.deep.equal( [ 'marker:1' ] ); } ); model.change( writer => { writer.insertText( 'abcdef', { foo: 'bar' }, p ); - writer.addMarker( 'marker', { + writer.addMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( p, [ 1 ] ), writer.createPositionFromPath( p, [ 5 ] ) @@ -1410,10 +1536,12 @@ describe( 'DocumentSelection', () => { const p = doc.getRoot().getChild( 0 ); + selection.observeMarkersGroup( 'marker' ); + doc.registerPostFixer( writer => { writer.setAttribute( 'foo', 'biz', p.getChild( 0 ) ); - writer.removeMarker( 'marker-1' ); - writer.addMarker( 'marker-2', { + writer.removeMarker( 'marker:1' ); + writer.addMarker( 'marker:2', { range: writer.createRange( writer.createPositionFromPath( p, [ 1 ] ), writer.createPositionFromPath( p, [ 5 ] ) @@ -1424,13 +1552,13 @@ describe( 'DocumentSelection', () => { doc.registerPostFixer( () => { expect( model.document.selection.getAttribute( 'foo' ) ).to.equal( 'biz' ); - expect( Array.from( model.document.selection.markers, m => m.name ) ).to.deep.equal( [ 'marker-2' ] ); + expect( Array.from( model.document.selection.markers, m => m.name ) ).to.deep.equal( [ 'marker:2' ] ); } ); model.change( writer => { writer.insertText( 'abcdef', { foo: 'bar' }, p ); - writer.addMarker( 'marker-1', { + writer.addMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( p, [ 1 ] ), writer.createPositionFromPath( p, [ 5 ] ) @@ -1447,16 +1575,18 @@ describe( 'DocumentSelection', () => { const p = doc.getRoot().getChild( 0 ); + selection.observeMarkersGroup( 'marker' ); + doc.on( 'change', () => { expect( model.document.selection.getAttribute( 'foo' ) ).to.equal( 'biz' ); - expect( Array.from( model.document.selection.markers, m => m.name ) ).to.deep.equal( [ 'marker-2' ] ); + expect( Array.from( model.document.selection.markers, m => m.name ) ).to.deep.equal( [ 'marker:2' ] ); done(); } ); doc.registerPostFixer( writer => { writer.setAttribute( 'foo', 'biz', p.getChild( 0 ) ); - writer.removeMarker( 'marker-1' ); - writer.addMarker( 'marker-2', { + writer.removeMarker( 'marker:1' ); + writer.addMarker( 'marker:2', { range: writer.createRange( writer.createPositionFromPath( p, [ 1 ] ), writer.createPositionFromPath( p, [ 5 ] ) @@ -1468,7 +1598,7 @@ describe( 'DocumentSelection', () => { model.change( writer => { writer.insertText( 'abcdef', { foo: 'bar' }, p ); - writer.addMarker( 'marker-1', { + writer.addMarker( 'marker:1', { range: writer.createRange( writer.createPositionFromPath( p, [ 1 ] ), writer.createPositionFromPath( p, [ 5 ] ) From 58ec22b7a68457d42cfd580bf021c57597172704 Mon Sep 17 00:00:00 2001 From: Kuba Niegowski Date: Thu, 19 Nov 2020 12:50:20 +0100 Subject: [PATCH 3/8] Code cleanup. --- .../ckeditor5-engine/src/model/documentselection.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/ckeditor5-engine/src/model/documentselection.js b/packages/ckeditor5-engine/src/model/documentselection.js index 6724b5110e0..0ad46a335c6 100644 --- a/packages/ckeditor5-engine/src/model/documentselection.js +++ b/packages/ckeditor5-engine/src/model/documentselection.js @@ -632,7 +632,7 @@ class LiveSelection extends Selection { // @type {Set} this._overriddenGravityRegister = new Set(); - // Prefixes of marker names that should affect this `LiveSelection#markers` collection. + // Prefixes of marker names that should affect `LiveSelection#markers` collection. // @private // @type {Array.} this._observedMarkerGroups = []; @@ -933,12 +933,10 @@ class LiveSelection extends Selection { const oldMarkers = Array.from( this.markers ); const markerRange = marker.getRange(); - if ( oldRange && !newRange && this.markers.has( marker ) ) { + if ( !newRange && this.markers.has( marker ) ) { this.markers.remove( marker ); changed = true; - } - - if ( !changed ) { + } else { let contained = false; for ( const selectionRange of this.getRanges() ) { @@ -952,6 +950,10 @@ class LiveSelection extends Selection { if ( contained && !this.markers.has( marker ) ) { this.markers.add( marker ); + changed = true; + } else if ( !contained && this.markers.has( marker ) ) { + this.markers.remove( marker ); + changed = true; } } From 6a16e5141e0a176895164de9d54709a0b190cca4 Mon Sep 17 00:00:00 2001 From: Kuba Niegowski Date: Thu, 19 Nov 2020 13:09:33 +0100 Subject: [PATCH 4/8] Code cleanup. --- .../src/model/documentselection.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/ckeditor5-engine/src/model/documentselection.js b/packages/ckeditor5-engine/src/model/documentselection.js index 0ad46a335c6..3e8e52732e6 100644 --- a/packages/ckeditor5-engine/src/model/documentselection.js +++ b/packages/ckeditor5-engine/src/model/documentselection.js @@ -681,7 +681,7 @@ class LiveSelection extends Selection { // Update markers data stored by the selection after each marker change. this.listenTo( this._model.markers, 'update', ( evt, marker, oldRange, newRange ) => { - this._updateMarker( marker, oldRange, newRange ); + this._updateMarker( marker, newRange ); } ); // Ensure selection is up to date after each change block. @@ -917,7 +917,7 @@ class LiveSelection extends Selection { } } - _updateMarker( marker, oldRange, newRange ) { + _updateMarker( marker, markerRange ) { if ( !this._observedMarkerGroups.length ) { return; } @@ -931,11 +931,13 @@ class LiveSelection extends Selection { let changed = false; const oldMarkers = Array.from( this.markers ); - const markerRange = marker.getRange(); + const hasMarker = this.markers.has( marker ); - if ( !newRange && this.markers.has( marker ) ) { - this.markers.remove( marker ); - changed = true; + if ( !markerRange ) { + if ( hasMarker ) { + this.markers.remove( marker ); + changed = true; + } } else { let contained = false; @@ -947,11 +949,11 @@ class LiveSelection extends Selection { } } - if ( contained && !this.markers.has( marker ) ) { + if ( contained && !hasMarker ) { this.markers.add( marker ); changed = true; - } else if ( !contained && this.markers.has( marker ) ) { + } else if ( !contained && hasMarker ) { this.markers.remove( marker ); changed = true; From 613a3ffcf0ad0e70beb2d5b6b6f12107dd1fb99f Mon Sep 17 00:00:00 2001 From: Kuba Niegowski Date: Thu, 19 Nov 2020 13:51:39 +0100 Subject: [PATCH 5/8] Switched from Array to Set to avoid potential duplicates. --- .../src/model/documentselection.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/ckeditor5-engine/src/model/documentselection.js b/packages/ckeditor5-engine/src/model/documentselection.js index 3e8e52732e6..756a663e462 100644 --- a/packages/ckeditor5-engine/src/model/documentselection.js +++ b/packages/ckeditor5-engine/src/model/documentselection.js @@ -634,8 +634,8 @@ class LiveSelection extends Selection { // Prefixes of marker names that should affect `LiveSelection#markers` collection. // @private - // @type {Array.} - this._observedMarkerGroups = []; + // @type {Set} + this._observedMarkerGroups = new Set(); // Ensure selection is correct after each operation. this.listenTo( this._model, 'applyOperation', ( evt, args ) => { @@ -819,7 +819,7 @@ class LiveSelection extends Selection { } observeMarkersGroup( prefix ) { - this._observedMarkerGroups.push( prefix ); + this._observedMarkerGroups.add( prefix ); this._updateMarkers(); } @@ -871,7 +871,7 @@ class LiveSelection extends Selection { } _updateMarkers() { - if ( !this._observedMarkerGroups.length ) { + if ( !this._observedMarkerGroups.size ) { return; } @@ -881,7 +881,7 @@ class LiveSelection extends Selection { for ( const marker of this._model.markers ) { const markerGroup = marker.name.split( ':', 1 )[ 0 ]; - if ( !this._observedMarkerGroups.includes( markerGroup ) ) { + if ( !this._observedMarkerGroups.has( markerGroup ) ) { continue; } @@ -918,13 +918,13 @@ class LiveSelection extends Selection { } _updateMarker( marker, markerRange ) { - if ( !this._observedMarkerGroups.length ) { + if ( !this._observedMarkerGroups.size ) { return; } const markerGroup = marker.name.split( ':', 1 )[ 0 ]; - if ( !this._observedMarkerGroups.includes( markerGroup ) ) { + if ( !this._observedMarkerGroups.has( markerGroup ) ) { return; } From c07e3cdb761300676d73160574aa450cac02df74 Mon Sep 17 00:00:00 2001 From: Kuba Niegowski Date: Thu, 19 Nov 2020 13:52:53 +0100 Subject: [PATCH 6/8] Added code comment. --- packages/ckeditor5-engine/src/model/documentselection.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/ckeditor5-engine/src/model/documentselection.js b/packages/ckeditor5-engine/src/model/documentselection.js index 756a663e462..862cc270a9e 100644 --- a/packages/ckeditor5-engine/src/model/documentselection.js +++ b/packages/ckeditor5-engine/src/model/documentselection.js @@ -680,6 +680,7 @@ class LiveSelection extends Selection { } ); // Update markers data stored by the selection after each marker change. + // This handles only marker changes done through marker operations (not model tree changes). this.listenTo( this._model.markers, 'update', ( evt, marker, oldRange, newRange ) => { this._updateMarker( marker, newRange ); } ); From 2d7438c8ea6d256558197d211c12d15a1f463fd7 Mon Sep 17 00:00:00 2001 From: Kuba Niegowski Date: Thu, 19 Nov 2020 14:11:10 +0100 Subject: [PATCH 7/8] Removed redundant check. --- packages/ckeditor5-engine/src/model/documentselection.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/ckeditor5-engine/src/model/documentselection.js b/packages/ckeditor5-engine/src/model/documentselection.js index 862cc270a9e..27a7b0fdcb0 100644 --- a/packages/ckeditor5-engine/src/model/documentselection.js +++ b/packages/ckeditor5-engine/src/model/documentselection.js @@ -919,10 +919,6 @@ class LiveSelection extends Selection { } _updateMarker( marker, markerRange ) { - if ( !this._observedMarkerGroups.size ) { - return; - } - const markerGroup = marker.name.split( ':', 1 )[ 0 ]; if ( !this._observedMarkerGroups.has( markerGroup ) ) { From ae6486112ef881aeeb929be25fc6551272e240de Mon Sep 17 00:00:00 2001 From: Kuba Niegowski Date: Thu, 19 Nov 2020 14:36:08 +0100 Subject: [PATCH 8/8] Generalized observeMarkersGroup to observeMarkers to indicate the possibility to observe individual markers. --- .../src/model/documentselection.js | 20 ++-- .../tests/model/documentselection.js | 91 ++++++++++++++----- 2 files changed, 78 insertions(+), 33 deletions(-) diff --git a/packages/ckeditor5-engine/src/model/documentselection.js b/packages/ckeditor5-engine/src/model/documentselection.js index 27a7b0fdcb0..82b5f0f359f 100644 --- a/packages/ckeditor5-engine/src/model/documentselection.js +++ b/packages/ckeditor5-engine/src/model/documentselection.js @@ -367,14 +367,14 @@ export default class DocumentSelection { } /** - * Registers marker group prefix to be collected in {@link ~DocumentSelection#markers selection markers collection}. + * Registers marker group prefix or marker name to be collected in {@link ~DocumentSelection#markers selection markers collection}. * * See also {@link module:engine/model/markercollection~MarkerCollection#getMarkersGroup `MarkerCollection#getMarkersGroup()`}. * - * @param {String} prefix Marker group prefix. + * @param {String} prefixOrName Marker group prefix or marker name. */ - observeMarkersGroup( prefix ) { - this._selection.observeMarkersGroup( prefix ); + observeMarkers( prefixOrName ) { + this._selection.observeMarkers( prefixOrName ); } /** @@ -635,7 +635,7 @@ class LiveSelection extends Selection { // Prefixes of marker names that should affect `LiveSelection#markers` collection. // @private // @type {Set} - this._observedMarkerGroups = new Set(); + this._observedMarkers = new Set(); // Ensure selection is correct after each operation. this.listenTo( this._model, 'applyOperation', ( evt, args ) => { @@ -819,8 +819,8 @@ class LiveSelection extends Selection { } } - observeMarkersGroup( prefix ) { - this._observedMarkerGroups.add( prefix ); + observeMarkers( prefixOrName ) { + this._observedMarkers.add( prefixOrName ); this._updateMarkers(); } @@ -872,7 +872,7 @@ class LiveSelection extends Selection { } _updateMarkers() { - if ( !this._observedMarkerGroups.size ) { + if ( !this._observedMarkers.size ) { return; } @@ -882,7 +882,7 @@ class LiveSelection extends Selection { for ( const marker of this._model.markers ) { const markerGroup = marker.name.split( ':', 1 )[ 0 ]; - if ( !this._observedMarkerGroups.has( markerGroup ) ) { + if ( !this._observedMarkers.has( markerGroup ) ) { continue; } @@ -921,7 +921,7 @@ class LiveSelection extends Selection { _updateMarker( marker, markerRange ) { const markerGroup = marker.name.split( ':', 1 )[ 0 ]; - if ( !this._observedMarkerGroups.has( markerGroup ) ) { + if ( !this._observedMarkers.has( markerGroup ) ) { return; } diff --git a/packages/ckeditor5-engine/tests/model/documentselection.js b/packages/ckeditor5-engine/tests/model/documentselection.js index 0bdc94d5d9d..fef5d8b68d0 100644 --- a/packages/ckeditor5-engine/tests/model/documentselection.js +++ b/packages/ckeditor5-engine/tests/model/documentselection.js @@ -205,7 +205,7 @@ describe( 'DocumentSelection', () => { } ); it( 'should add markers to the collection when selection is inside the marker range', () => { - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createRange( @@ -250,7 +250,7 @@ describe( 'DocumentSelection', () => { } ); it( 'should update markers after selection change', () => { - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createRange( @@ -296,7 +296,7 @@ describe( 'DocumentSelection', () => { } ); it( 'should update markers after markers change', () => { - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createRange( @@ -355,7 +355,7 @@ describe( 'DocumentSelection', () => { } ); it( 'should not add marker when collapsed selection is on the marker left bound', () => { - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createRange( @@ -375,7 +375,7 @@ describe( 'DocumentSelection', () => { } ); it( 'should not add marker when collapsed selection is on the marker right bound', () => { - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createRange( @@ -395,7 +395,7 @@ describe( 'DocumentSelection', () => { } ); it( 'should add marker when non-collapsed selection is inside a marker and touches the left bound', () => { - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createRange( @@ -416,7 +416,7 @@ describe( 'DocumentSelection', () => { } ); it( 'should add marker when non-collapsed selection is inside a marker and touches the right bound', () => { - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createRange( @@ -437,7 +437,7 @@ describe( 'DocumentSelection', () => { } ); it( 'should add marker of selected widget', () => { - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); root._insertChild( 0, new Element( 'widget' ) ); @@ -502,8 +502,8 @@ describe( 'DocumentSelection', () => { expect( selection.markers ).to.length( 0 ); } ); - it( 'should add markers to the collection when markers only for observed marker groups', () => { - selection.observeMarkersGroup( 'marker' ); + it( 'should add markers to the collection only for observed marker groups', () => { + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createRange( @@ -547,6 +547,51 @@ describe( 'DocumentSelection', () => { expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'marker:2' ] ); } ); + it( 'should add marker to the collection only for observed marker name', () => { + selection.observeMarkers( 'testMarker' ); + + model.change( writer => { + writer.setSelection( writer.createRange( + writer.createPositionFromPath( root, [ 2, 2 ] ), + writer.createPositionFromPath( root, [ 2, 4 ] ) + ) ); + + writer.addMarker( 'marker:1', { + range: writer.createRange( + writer.createPositionFromPath( root, [ 0, 0 ] ), + writer.createPositionFromPath( root, [ 2, 2 ] ) + ), + usingOperation: false + } ); + + writer.addMarker( 'testMarker', { + range: writer.createRange( + writer.createPositionFromPath( root, [ 2, 2 ] ), + writer.createPositionFromPath( root, [ 2, 4 ] ) + ), + usingOperation: false + } ); + + writer.addMarker( 'otherMarker', { + range: writer.createRange( + writer.createPositionFromPath( root, [ 2, 1 ] ), + writer.createPositionFromPath( root, [ 2, 5 ] ) + ), + usingOperation: false + } ); + + writer.addMarker( 'otherGroup:1', { + range: writer.createRange( + writer.createPositionFromPath( root, [ 2, 1 ] ), + writer.createPositionFromPath( root, [ 2, 5 ] ) + ), + usingOperation: false + } ); + } ); + + expect( selection.markers.map( marker => marker.name ) ).to.have.members( [ 'testMarker' ] ); + } ); + describe( 'should fire change:marker event when', () => { // Set marker to range 0-4. beforeEach( () => { @@ -564,7 +609,7 @@ describe( 'DocumentSelection', () => { it( 'selection ranges change (marker added to the selection)', () => { const spy = sinon.spy(); - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { // The selection has no markers before the change. @@ -586,7 +631,7 @@ describe( 'DocumentSelection', () => { it( 'selection ranges change (marker removed from the selection)', () => { const spy = sinon.spy(); - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createRange( @@ -610,7 +655,7 @@ describe( 'DocumentSelection', () => { it( 'selection focus changes (marker removed from the selection)', () => { const spy = sinon.spy(); - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createPositionFromPath( root, [ 2, 2 ] ) ); @@ -631,7 +676,7 @@ describe( 'DocumentSelection', () => { it( 'a new marker contains the selection', () => { const spy = sinon.spy(); - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createPositionFromPath( root, [ 2, 5 ] ) ); @@ -656,7 +701,7 @@ describe( 'DocumentSelection', () => { it( 'a marker stops contains the selection', () => { const spy = sinon.spy(); - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createPositionFromPath( root, [ 2, 3 ] ) ); @@ -696,7 +741,7 @@ describe( 'DocumentSelection', () => { it( 'selection ranges change does not change selection markers (no markers)', () => { const spy = sinon.spy(); - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.document.selection.on( 'change:marker', spy ); @@ -708,7 +753,7 @@ describe( 'DocumentSelection', () => { } ); it( 'selection ranges change does not change selection markers (same markers)', () => { - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createPositionFromPath( root, [ 2, 2 ] ) ); @@ -726,7 +771,7 @@ describe( 'DocumentSelection', () => { } ); it( 'selection focus change does not change selection markers', () => { - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createPositionFromPath( root, [ 2, 2 ] ) ); @@ -744,7 +789,7 @@ describe( 'DocumentSelection', () => { } ); it( 'changed marker still contains the selection', () => { - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createPositionFromPath( root, [ 2, 2 ] ) ); @@ -767,7 +812,7 @@ describe( 'DocumentSelection', () => { } ); it( 'removed marker did not contain the selection', () => { - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); model.change( writer => { writer.setSelection( writer.createPositionFromPath( root, [ 2, 5 ] ) ); @@ -1509,7 +1554,7 @@ describe( 'DocumentSelection', () => { const p = doc.getRoot().getChild( 0 ); - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); doc.registerPostFixer( () => { expect( model.document.selection.getAttribute( 'foo' ) ).to.equal( 'bar' ); @@ -1536,7 +1581,7 @@ describe( 'DocumentSelection', () => { const p = doc.getRoot().getChild( 0 ); - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); doc.registerPostFixer( writer => { writer.setAttribute( 'foo', 'biz', p.getChild( 0 ) ); @@ -1575,7 +1620,7 @@ describe( 'DocumentSelection', () => { const p = doc.getRoot().getChild( 0 ); - selection.observeMarkersGroup( 'marker' ); + selection.observeMarkers( 'marker' ); doc.on( 'change', () => { expect( model.document.selection.getAttribute( 'foo' ) ).to.equal( 'biz' );