diff --git a/src/tableselection.js b/src/tableselection.js index 65185c14..284a213c 100644 --- a/src/tableselection.js +++ b/src/tableselection.js @@ -58,6 +58,7 @@ export default class TableSelection extends Plugin { this._defineSelectionConverter(); this._enableShiftClickSelection(); this._enableMouseDragSelection(); + this._enablePluginDisabling(); // sic! } /** @@ -292,6 +293,34 @@ export default class TableSelection extends Plugin { }, { priority: 'highest' } ); } + /** + * Creates a listener that reacts to changes in {@link #isEnabled} and, if the plugin was disabled, + * it collapses the multi-cell selection to a regular selection placed inside a table cell. + * + * This listener helps features that disable the table selection plugin bring the selection + * to a clear state they can work with (for instance, because they don't support multiple cell selection). + */ + _enablePluginDisabling() { + const editor = this.editor; + + this.on( 'change:isEnabled', () => { + if ( !this.isEnabled ) { + const selectedCells = this.getSelectedTableCells(); + + if ( !selectedCells ) { + return; + } + + editor.model.change( writer => { + const position = writer.createPositionAt( selectedCells[ 0 ], 0 ); + const range = editor.model.schema.getNearestSelectionRange( position ); + + writer.setSelection( range ); + } ); + } + } ); + } + /** * It overrides the default `model.deleteContent()` behavior over a selected table fragment. * diff --git a/tests/tableselection.js b/tests/tableselection.js index e60875e8..22bfacb6 100644 --- a/tests/tableselection.js +++ b/tests/tableselection.js @@ -37,6 +37,45 @@ describe( 'table selection', () => { afterEach( async () => { await editor.destroy(); } ); + + describe( 'init()', () => { + describe( 'plugin disabling support', () => { + let plugin; + + beforeEach( () => { + plugin = editor.plugins.get( TableSelection ); + } ); + + it( 'should collapse multi-cell selection when the plugin gets disabled', () => { + const firstCell = modelRoot.getNodeByPath( [ 0, 0, 0 ] ); + const lastCell = modelRoot.getNodeByPath( [ 0, 1, 1 ] ); + + tableSelection._setCellSelection( + firstCell, + lastCell + ); + + plugin.forceDisabled( 'foo' ); + + const ranges = [ ...model.document.selection.getRanges() ]; + + expect( ranges ).to.have.length( 1 ); + expect( ranges[ 0 ].isCollapsed ).to.be.true; + expect( ranges[ 0 ].start.path ).to.deep.equal( [ 0, 0, 0, 0, 0 ] ); + } ); + + it( 'should do nothing if there were no multi-cell selections', () => { + plugin.forceDisabled( 'foo' ); + + const ranges = [ ...model.document.selection.getRanges() ]; + + expect( ranges ).to.have.length( 1 ); + expect( ranges[ 0 ].isCollapsed ).to.be.true; + expect( ranges[ 0 ].start.path ).to.deep.equal( [ 0, 0, 0, 0, 2 ] ); + } ); + } ); + } ); + describe( 'selection by shift+click', () => { it( 'should...', () => { // tableSelection.startSelectingFrom( modelRoot.getNodeByPath( [ 0, 0, 0 ] ) );