diff --git a/src/tableselection.js b/src/tableselection.js index 0e8fe2ab..63c22ad0 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! } /** @@ -293,6 +294,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 5d893ab3..cfbcbdcc 100644 --- a/tests/tableselection.js +++ b/tests/tableselection.js @@ -34,6 +34,51 @@ describe( 'table selection', () => { await editor.destroy(); } ); + describe( 'init()', () => { + beforeEach( async () => { + editor = await createEditor(); + model = editor.model; + modelRoot = model.document.getRoot(); + tableSelection = editor.plugins.get( TableSelection ); + + setModelData( model, modelTable( [ + [ '11[]', '12', '13' ], + [ '21', '22', '23' ], + [ '31', '32', '33' ] + ] ) ); + } ); + + describe( 'plugin disabling support', () => { + 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 + ); + + tableSelection.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', () => { + tableSelection.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', () => { beforeEach( async () => { // Disables attaching drag mouse events.