diff --git a/src/commands/inserttablecommand.js b/src/commands/inserttablecommand.js index 54e74216..ceffda92 100644 --- a/src/commands/inserttablecommand.js +++ b/src/commands/inserttablecommand.js @@ -9,6 +9,7 @@ import Command from '@ckeditor/ckeditor5-core/src/command'; import Position from '@ckeditor/ckeditor5-engine/src/model/position'; +import { findOptimalInsertionPosition } from '@ckeditor/ckeditor5-widget/src/utils'; import TableUtils from '../tableutils'; /** @@ -54,13 +55,12 @@ export default class InsertTableCommand extends Command { const rows = parseInt( options.rows ) || 2; const columns = parseInt( options.columns ) || 2; - const firstPosition = selection.getFirstPosition(); - - const isRoot = firstPosition.parent === firstPosition.root; - const insertPosition = isRoot ? Position.createAt( firstPosition ) : Position.createAfter( firstPosition.parent ); + const insertPosition = findOptimalInsertionPosition( selection ); model.change( writer => { - const table = tableUtils.createTable( insertPosition, rows, columns ); + const table = tableUtils.createTable( writer, rows, columns ); + + model.insertContent( table, insertPosition ); writer.setSelection( Position.createAt( table.getChild( 0 ).getChild( 0 ).getChild( 0 ) ) ); } ); diff --git a/src/tableutils.js b/src/tableutils.js index 16a6e60f..116249f1 100644 --- a/src/tableutils.js +++ b/src/tableutils.js @@ -69,25 +69,28 @@ export default class TableUtils extends Plugin { } /** - * Creates an empty table at a given position. + * Creates an empty table with proper structure. The table needs to be inserted into the model, + * ie. using {@link module:engine/model/model~Model#insertContent} function. * - * @param {module:engine/model/position~Position} position The position where the table will be inserted. + * model.change( ( writer ) => { + * // Create a table of 2 rows and 7 columns: + * const table = tableUtils.createTable( writer, 2, 7); + * + * // Insert table to the model at the best position taking current selection: + * model.insertContent( table ); + * } + * + * @param {module:engine/model/writer~Writer} writer The model writer. * @param {Number} rows The number of rows to create. * @param {Number} columns The number of columns to create. * @returns {module:engine/model/element~Element} The created table element. */ - createTable( position, rows, columns ) { - const model = this.editor.model; + createTable( writer, rows, columns ) { + const table = writer.createElement( 'table' ); - return model.change( writer => { - const table = writer.createElement( 'table' ); + createEmptyRows( writer, table, 0, rows, columns ); - writer.insert( table, position ); - - createEmptyRows( writer, table, 0, rows, columns ); - - return table; - } ); + return table; } /** diff --git a/tests/commands/inserttablecommand.js b/tests/commands/inserttablecommand.js index c60b430c..96aad384 100644 --- a/tests/commands/inserttablecommand.js +++ b/tests/commands/inserttablecommand.js @@ -72,7 +72,7 @@ describe( 'InsertTableCommand', () => { ] ) ); } ); - it( 'should insert table with two rows and two columns after non-empty paragraph', () => { + it( 'should insert table with two rows and two columns after non-empty paragraph if selection is at the end', () => { setData( model, 'foo[]' ); command.execute(); @@ -100,6 +100,34 @@ describe( 'InsertTableCommand', () => { ] ) ); } ); + + it( 'should insert table before after non-empty paragraph if selection is inside', () => { + setData( model, 'f[]oo' ); + + command.execute(); + + expect( formatTable( getData( model ) ) ).to.equal( + formattedModelTable( [ + [ '[]', '' ], + [ '', '' ] + ] ) + + 'foo' + ); + } ); + + it( 'should replace empty paragraph with table', () => { + setData( model, '[]' ); + + command.execute( { rows: 3, columns: 4 } ); + + expect( formatTable( getData( model ) ) ).to.equal( + formattedModelTable( [ + [ '[]', '', '', '' ], + [ '', '', '', '' ], + [ '', '', '', '' ] + ] ) + ); + } ); } ); } ); } );