瀏覽代碼

Recalculate table geometry on each table row removal.

Maciej Gołaszewski 5 年之前
父節點
當前提交
43ff963aed

+ 13 - 18
packages/ckeditor5-table/src/commands/removerowcommand.js

@@ -10,7 +10,7 @@
 import Command from '@ckeditor/ckeditor5-core/src/command';
 
 import TableWalker from '../tablewalker';
-import { updateNumericAttribute } from './utils';
+import { findAncestor, updateNumericAttribute } from './utils';
 import { getSelectionAffectedTableCells } from '../utils';
 
 /**
@@ -51,18 +51,19 @@ export default class RemoveRowCommand extends Command {
 	 * @inheritDoc
 	 */
 	execute() {
-		const referenceCells = getSelectionAffectedTableCells( this.editor.model.document.selection );
+		const model = this.editor.model;
+		const referenceCells = getSelectionAffectedTableCells( model.document.selection );
 		const removedRowIndexes = getRowIndexes( referenceCells );
 
 		const firstCell = referenceCells[ 0 ];
-		const table = firstCell.parent.parent;
-		const tableMap = [ ...new TableWalker( table, { endRow: removedRowIndexes.last } ) ];
-		const batch = this.editor.model.createBatch();
-		const columnIndexToFocus = getColumnIndexToFocus( tableMap, firstCell );
+		const table = findAncestor( 'table', firstCell );
+
+		const batch = model.createBatch();
+		const columnIndexToFocus = this.editor.plugins.get( 'TableUtils' ).getCellLocation( firstCell ).column;
 
 		// Doing multiple model.enqueueChange() calls, to get around ckeditor/ckeditor5#6391.
 		// Ideally we want to do this in a single model.change() block.
-		this.editor.model.enqueueChange( batch, writer => {
+		model.enqueueChange( batch, writer => {
 			// This prevents the "model-selection-range-intersects" error, caused by removing row selected cells.
 			writer.setSelection( writer.createSelection( table, 'on' ) );
 		} );
@@ -70,15 +71,15 @@ export default class RemoveRowCommand extends Command {
 		let cellToFocus;
 
 		for ( let i = removedRowIndexes.last; i >= removedRowIndexes.first; i-- ) {
-			this.editor.model.enqueueChange( batch, writer => {
+			model.enqueueChange( batch, writer => {
 				const removedRowIndex = i;
-				this._removeRow( removedRowIndex, table, writer, tableMap );
+				this._removeRow( removedRowIndex, table, writer );
 
 				cellToFocus = getCellToFocus( table, removedRowIndex, columnIndexToFocus );
 			} );
 		}
 
-		this.editor.model.enqueueChange( batch, writer => {
+		model.enqueueChange( batch, writer => {
 			writer.setSelection( writer.createPositionAt( cellToFocus, 0 ) );
 		} );
 	}
@@ -90,12 +91,12 @@ export default class RemoveRowCommand extends Command {
 	 * @param {Number} removedRowIndex Index of the row that should be removed.
 	 * @param {module:engine/model/element~Element} table
 	 * @param {module:engine/model/writer~Writer} writer
-	 * @param {module:engine/model/element~Element[]} tableMap Table map retrieved from {@link module:table/tablewalker~TableWalker}.
 	 */
-	_removeRow( removedRowIndex, table, writer, tableMap ) {
+	_removeRow( removedRowIndex, table, writer ) {
 		const cellsToMove = new Map();
 		const tableRow = table.getChild( removedRowIndex );
 		const headingRows = table.getAttribute( 'headingRows' ) || 0;
+		const tableMap = [ ...new TableWalker( table, { endRow: removedRowIndex } ) ];
 
 		if ( headingRows && removedRowIndex < headingRows ) {
 			updateNumericAttribute( 'headingRows', headingRows - 1, table, writer, 0 );
@@ -166,9 +167,3 @@ function getCellToFocus( table, removedRowIndex, columnToFocus ) {
 
 	return cellToFocus;
 }
-
-// Returns the index of column that should be focused after rows are removed.
-function getColumnIndexToFocus( tableMap, firstCell ) {
-	const firstCellData = tableMap.find( value => value.cell === firstCell );
-	return firstCellData.column;
-}

+ 21 - 0
packages/ckeditor5-table/tests/commands/removerowcommand.js

@@ -258,6 +258,27 @@ describe( 'RemoveRowCommand', () => {
 					[ '[]20', '21' ]
 				] ) );
 			} );
+
+			it( 'should properly calculate truncated rowspans', () => {
+				setData( model, modelTable( [
+					[ '00', { contents: '01', rowspan: 3 } ],
+					[ '10' ],
+					[ '20' ]
+				] ) );
+
+				const tableSelection = editor.plugins.get( TableSelection );
+				const modelRoot = model.document.getRoot();
+				tableSelection._setCellSelection(
+					modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+					modelRoot.getNodeByPath( [ 0, 1, 0 ] )
+				);
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '[]20', '01' ]
+				] ) );
+			} );
 		} );
 
 		describe( 'with entire row selected', () => {