浏览代码

Fix: Broken table layout when merging cell with a cell above.

Maciej Gołaszewski 7 年之前
父节点
当前提交
312ad09a02

+ 15 - 5
packages/ckeditor5-table/src/commands/mergecellcommand.js

@@ -158,16 +158,26 @@ function getVerticalCell( tableCell, direction ) {
 		return;
 	}
 
-	const rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );
-	const mergeRow = direction == 'down' ? rowIndex + rowspan : rowIndex;
+	const currentCellRowSpan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );
+	const rowOfCellToMerge = direction == 'down' ? rowIndex + currentCellRowSpan : rowIndex;
 
-	const tableMap = [ ...new TableWalker( table, { endRow: mergeRow } ) ];
+	const tableMap = [ ...new TableWalker( table, { endRow: rowOfCellToMerge } ) ];
 
 	const currentCellData = tableMap.find( value => value.cell === tableCell );
 	const mergeColumn = currentCellData.column;
 
-	const cellToMergeData = tableMap.find( ( { row, column } ) => {
-		return column === mergeColumn && ( direction == 'down' ? mergeRow === row : mergeRow === rowspan + row );
+	const cellToMergeData = tableMap.find( ( { row, rowspan, column } ) => {
+		if ( column !== mergeColumn ) {
+			return false;
+		}
+
+		if ( direction == 'down' ) {
+			// If merging a cell below the mergeRow is already calculated.
+			return row === rowOfCellToMerge;
+		} else {
+			// If merging a cell above calculate if it spans to mergeRow.
+			return rowOfCellToMerge === row + rowspan;
+		}
 	} );
 
 	return cellToMergeData && cellToMergeData.cell;

+ 32 - 3
packages/ckeditor5-table/tests/commands/mergecellcommand.js

@@ -4,7 +4,7 @@
  */
 
 import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
-import { setData, getData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
+import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import { upcastElementToElement } from '@ckeditor/ckeditor5-engine/src/conversion/upcast-converters';
 
 import MergeCellCommand from '../../src/commands/mergecellcommand';
@@ -483,6 +483,17 @@ describe( 'MergeCellCommand', () => {
 				expect( command.value ).to.equal( root.getNodeByPath( [ 0, 0, 0 ] ) );
 			} );
 
+			it( 'should be set to mergeable cell in rows with spanned cells', () => {
+				setData( model, modelTable( [
+					[ { rowspan: 3, contents: '00' }, '11', '12', '13' ],
+					[ { rowspan: 2, contents: '21' }, '22', '23' ],
+					[ '32', { rowspan: 2, contents: '33[]' } ],
+					[ { colspan: 2, contents: '40' }, '42' ]
+				] ) );
+
+				expect( command.value ).to.equal( root.getNodeByPath( [ 0, 1, 2 ] ) );
+			} );
+
 			it( 'should be undefined if in a cell that potential mergeable cell has different rowspan', () => {
 				setData( model, modelTable( [
 					[ { colspan: 2, contents: '00' }, '02' ],
@@ -500,10 +511,10 @@ describe( 'MergeCellCommand', () => {
 		} );
 
 		describe( 'execute()', () => {
-			it( 'should merge table cells ', () => {
+			it( 'should merge table cells', () => {
 				setData( model, modelTable( [
 					[ '00', '01' ],
-					[ '10', '11[]' ]
+					[ '10', '[]11' ]
 				] ) );
 
 				command.execute();
@@ -513,6 +524,24 @@ describe( 'MergeCellCommand', () => {
 					[ '10' ]
 				] ) );
 			} );
+
+			it( 'should properly merge cells in rows with spaned cells', () => {
+				setData( model, modelTable( [
+					[ { rowspan: 3, contents: '00' }, '11', '12', '13' ],
+					[ { rowspan: 2, contents: '21' }, '22', '23' ],
+					[ '32', { rowspan: 2, contents: '33[]' } ],
+					[ { colspan: 2, contents: '40' }, '42' ]
+				] ) );
+
+				command.execute();
+
+				expect( formatTable( getData( model ) ) ).to.equal( formattedModelTable( [
+					[ { rowspan: 3, contents: '00' }, '11', '12', '13' ],
+					[ { rowspan: 2, contents: '21' }, '22', { rowspan: 3, contents: '[2333]' } ],
+					[ '32' ],
+					[ { colspan: 2, contents: '40' }, '42' ]
+				] ) );
+			} );
 		} );
 	} );
 } );