Procházet zdrojové kódy

Merging cells and removing empty rows in one batch.

Kuba Niegowski před 5 roky
rodič
revize
9275e84902

+ 7 - 3
packages/ckeditor5-table/src/commands/mergecellcommand.js

@@ -80,11 +80,15 @@ export default class MergeCellCommand extends Command {
 		const model = this.editor.model;
 		const doc = model.document;
 		const tableCell = getTableCellsContainingSelection( doc.selection )[ 0 ];
+		const table = findAncestor( 'table', tableCell );
+
 		const cellToMerge = this.value;
 		const direction = this.direction;
-		const table = findAncestor( 'table', tableCell );
 
-		model.change( writer => {
+		// Use single batch to modify table in steps but in one undo step.
+		const batch = model.createBatch();
+
+		model.enqueueChange( batch, writer => {
 			const isMergeNext = direction == 'right' || direction == 'down';
 
 			// The merge mechanism is always the same so sort cells to be merged.
@@ -107,7 +111,7 @@ export default class MergeCellCommand extends Command {
 			// Remove empty row after merging.
 			if ( !removedTableCellRow.childCount ) {
 				const tableUtils = this.editor.plugins.get( 'TableUtils' );
-				tableUtils.removeRows( table, { at: table.getChildIndex( removedTableCellRow ) } );
+				tableUtils.removeRows( table, { at: table.getChildIndex( removedTableCellRow ), batch } );
 			}
 		} );
 	}

+ 5 - 2
packages/ckeditor5-table/src/commands/mergecellscommand.js

@@ -40,7 +40,10 @@ export default class MergeCellsCommand extends Command {
 		const model = this.editor.model;
 		const tableUtils = this.editor.plugins.get( TableUtils );
 
-		model.change( writer => {
+		// Use single batch to modify table in steps but in one undo step.
+		const batch = model.createBatch();
+
+		model.enqueueChange( batch, writer => {
 			const selectedTableCells = getSelectedTableCells( model.document.selection );
 
 			// All cells will be merged into the first one.
@@ -69,7 +72,7 @@ export default class MergeCellsCommand extends Command {
 				}
 			}
 
-			emptyRows.reverse().forEach( row => tableUtils.removeRows( table, { at: row } ) );
+			emptyRows.reverse().forEach( row => tableUtils.removeRows( table, { at: row, batch } ) );
 
 			writer.setSelection( firstTableCell, 'in' );
 		} );

+ 94 - 0
packages/ckeditor5-table/tests/commands/mergecellcommand.js

@@ -701,6 +701,53 @@ describe( 'MergeCellCommand', () => {
 					[ '40', '41' ]
 				] ) );
 			} );
+
+			it( 'should adjust heading rows if empty row was removed ', () => {
+				// +----+----+
+				// | 00 | 01 |
+				// +    +----+
+				// |    | 11 |
+				// +----+----+ <-- heading rows
+				// | 20 | 21 |
+				// +----+----+
+				setData( model, modelTable( [
+					[ { contents: '00', rowspan: 2 }, '[]01' ],
+					[ '11' ],
+					[ '20', '21' ]
+				], { headingRows: 2 } ) );
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00', '<paragraph>[01</paragraph><paragraph>11]</paragraph>' ],
+					[ '20', '21' ]
+				], { headingRows: 1 } ) );
+			} );
+
+			it( 'should create one undo step (1 batch)', () => {
+				// +----+----+
+				// | 00 | 01 |
+				// +    +----+
+				// |    | 11 |
+				// +----+----+ <-- heading rows
+				// | 20 | 21 |
+				// +----+----+
+				setData( model, modelTable( [
+					[ { contents: '00', rowspan: 2 }, '[]01' ],
+					[ '11' ],
+					[ '20', '21' ]
+				], { headingRows: 2 } ) );
+
+				const createdBatches = new Set();
+
+				model.on( 'applyOperation', ( evt, [ operation ] ) => {
+					createdBatches.add( operation.batch );
+				} );
+
+				command.execute();
+
+				expect( createdBatches.size ).to.equal( 1 );
+			} );
 		} );
 	} );
 
@@ -959,6 +1006,53 @@ describe( 'MergeCellCommand', () => {
 					[ '40', '41' ]
 				] ) );
 			} );
+
+			it( 'should adjust heading rows if empty row was removed ', () => {
+				// +----+----+
+				// | 00 | 01 |
+				// +    +----+
+				// |    | 11 |
+				// +----+----+ <-- heading rows
+				// | 20 | 21 |
+				// +----+----+
+				setData( model, modelTable( [
+					[ { contents: '00', rowspan: 2 }, '01' ],
+					[ '[]11' ],
+					[ '20', '21' ]
+				], { headingRows: 2 } ) );
+
+				command.execute();
+
+				assertEqualMarkup( getData( model ), modelTable( [
+					[ '00', '<paragraph>[01</paragraph><paragraph>11]</paragraph>' ],
+					[ '20', '21' ]
+				], { headingRows: 1 } ) );
+			} );
+
+			it( 'should create one undo step (1 batch)', () => {
+				// +----+----+
+				// | 00 | 01 |
+				// +    +----+
+				// |    | 11 |
+				// +----+----+ <-- heading rows
+				// | 20 | 21 |
+				// +----+----+
+				setData( model, modelTable( [
+					[ { contents: '00', rowspan: 2 }, '01' ],
+					[ '[]11' ],
+					[ '20', '21' ]
+				], { headingRows: 2 } ) );
+
+				const createdBatches = new Set();
+
+				model.on( 'applyOperation', ( evt, [ operation ] ) => {
+					createdBatches.add( operation.batch );
+				} );
+
+				command.execute();
+
+				expect( createdBatches.size ).to.equal( 1 );
+			} );
 		} );
 	} );
 } );

+ 23 - 0
packages/ckeditor5-table/tests/commands/mergecellscommand.js

@@ -536,6 +536,29 @@ describe( 'MergeCellsCommand', () => {
 				], { headingRows: 1 } ) );
 			} );
 
+			it( 'should create one undo step (1 batch)', () => {
+				setData( model, modelTable( [
+					[ '00' ],
+					[ '10' ],
+					[ '20' ]
+				], { headingRows: 2 } ) );
+
+				selectNodes( [
+					[ 0, 0, 0 ],
+					[ 0, 1, 0 ]
+				] );
+
+				const createdBatches = new Set();
+
+				model.on( 'applyOperation', ( evt, [ operation ] ) => {
+					createdBatches.add( operation.batch );
+				} );
+
+				command.execute();
+
+				expect( createdBatches.size ).to.equal( 1 );
+			} );
+
 			it( 'should decrease rowspan if cell overlaps removed row', () => {
 				setData( model, modelTable( [
 					[ '00', { rowspan: 2, contents: '01' }, { rowspan: 3, contents: '02' } ],