Forráskód Böngészése

Fixed: Splitting table cell with rowspan should reduce this attribute properly.

Maciej Gołaszewski 7 éve
szülő
commit
de91cff96e

+ 63 - 7
packages/ckeditor5-table/src/tableutils.js

@@ -19,6 +19,13 @@ import { getParentTable, updateNumericAttribute } from './commands/utils';
  * @extends module:core/plugin~Plugin
  */
 export default class TableUtils extends Plugin {
+	/**
+	 * @inheritDoc
+	 */
+	static get pluginName() {
+		return 'TableUtils';
+	}
+
 	/**
 	 * Returns table cell location in table.
 	 *
@@ -248,18 +255,67 @@ export default class TableUtils extends Plugin {
 		const table = getParentTable( tableCell );
 		const rowIndex = table.getChildIndex( tableCell.parent );
 
+		const rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );
+		const colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );
+
+		const splitOnly = rowspan >= numberOfCells;
+
 		model.change( writer => {
-			const tableMap = [ ...new TableWalker( table, { startRow: 0, endRow: rowIndex } ) ];
+			if ( splitOnly ) {
+				const rowspanOfCellsToInsert = Math.floor( rowspan / numberOfCells );
+
+				const cellsToInsert = numberOfCells - 1;
 
-			for ( const { cell, rowspan, row } of tableMap ) {
-				if ( cell !== tableCell && row + rowspan > rowIndex ) {
-					const rowspan = parseInt( cell.getAttribute( 'rowspan' ) || 1 );
+				const newRowspan = rowspan - cellsToInsert * rowspanOfCellsToInsert;
 
-					writer.setAttribute( 'rowspan', rowspan + numberOfCells - 1, cell );
+				const tableMap = [ ...new TableWalker( table, {
+					startRow: rowIndex,
+					endRow: rowIndex + rowspan - 1,
+					includeSpanned: true
+				} ) ];
+
+				updateNumericAttribute( 'rowspan', newRowspan, tableCell, writer );
+
+				let cellColumn = 0;
+
+				const attributes = {};
+
+				if ( rowspanOfCellsToInsert > 1 ) {
+					attributes.rowspan = rowspanOfCellsToInsert;
+				}
+
+				if ( colspan > 1 ) {
+					attributes.colspan = colspan;
 				}
-			}
 
-			createEmptyRows( writer, table, rowIndex + 1, numberOfCells - 1, 1 );
+				for ( const { cell, column, row, cellIndex } of tableMap ) {
+					if ( cell === tableCell ) {
+						cellColumn = column;
+					}
+
+					const isAfterSplitCell = row >= rowIndex + newRowspan;
+					const isOnSameColumn = column === cellColumn;
+					const isInEvenlySplitRow = ( row + rowIndex + newRowspan ) % rowspanOfCellsToInsert === 0;
+
+					if ( isAfterSplitCell && isOnSameColumn && isInEvenlySplitRow ) {
+						const position = Position.createFromParentAndOffset( table.getChild( row ), cellIndex );
+
+						writer.insertElement( 'tableCell', attributes, position );
+					}
+				}
+			} else {
+				const tableMap = [ ...new TableWalker( table, { startRow: 0, endRow: rowIndex } ) ];
+
+				for ( const { cell, rowspan, row } of tableMap ) {
+					if ( cell !== tableCell && row + rowspan > rowIndex ) {
+						const rowspanToSet = rowspan + numberOfCells - 1;
+
+						writer.setAttribute( 'rowspan', rowspanToSet, cell );
+					}
+				}
+
+				createEmptyRows( writer, table, rowIndex + 1, numberOfCells - 1, 1 );
+			}
 		} );
 	}
 

+ 70 - 0
packages/ckeditor5-table/tests/tableutils.js

@@ -71,6 +71,12 @@ describe( 'TableUtils', () => {
 		return editor.destroy();
 	} );
 
+	describe( '#pluginName', () => {
+		it( 'should provide plugin name', () => {
+			expect( TableUtils.pluginName ).to.equal( 'TableUtils' );
+		} );
+	} );
+
 	describe( 'getCellLocation()', () => {
 		it( 'should return proper table cell location', () => {
 			setData( model, modelTable( [
@@ -558,6 +564,70 @@ describe( 'TableUtils', () => {
 				[ '20', '21' ]
 			] ) );
 		} );
+
+		it( 'should unsplit rowspanned cell', () => {
+			setData( model, modelTable( [
+				[ '00', { rowspan: 2, contents: '01[]' } ],
+				[ '10' ],
+				[ '20', '21' ]
+			] ) );
+
+			const tableCell = root.getNodeByPath( [ 0, 0, 1 ] );
+
+			tableUtils.splitCellVertically( tableCell, 2 );
+
+			expect( formatTable( getData( model ) ) ).to.equal( formattedModelTable( [
+				[ '00', '01[]' ],
+				[ '10', '' ],
+				[ '20', '21' ]
+			] ) );
+		} );
+
+		it( 'should copy colspan while splitting rowspanned cell', () => {
+			setData( model, modelTable( [
+				[ '00', { rowspan: 2, colspan: 2, contents: '01[]' } ],
+				[ '10' ],
+				[ '20', '21', '22' ]
+			] ) );
+
+			const tableCell = root.getNodeByPath( [ 0, 0, 1 ] );
+
+			tableUtils.splitCellVertically( tableCell, 2 );
+
+			expect( formatTable( getData( model ) ) ).to.equal( formattedModelTable( [
+				[ '00', { colspan: 2, contents: '01[]' } ],
+				[ '10', { colspan: 2, contents: '' } ],
+				[ '20', '21', '22' ]
+			] ) );
+		} );
+
+		it( 'should evenly distribute rowspan attribute', () => {
+			setData( model, modelTable( [
+				[ '00', { rowspan: 7, contents: '01[]' } ],
+				[ '10' ],
+				[ '20' ],
+				[ '30' ],
+				[ '40' ],
+				[ '50' ],
+				[ '60' ],
+				[ '70', '71' ]
+			] ) );
+
+			const tableCell = root.getNodeByPath( [ 0, 0, 1 ] );
+
+			tableUtils.splitCellVertically( tableCell, 3 );
+
+			expect( formatTable( getData( model ) ) ).to.equal( formattedModelTable( [
+				[ '00', { rowspan: 3, contents: '01[]' } ],
+				[ '10' ],
+				[ '20' ],
+				[ '30', { rowspan: 2, contents: '' } ],
+				[ '40' ],
+				[ '50', { rowspan: 2, contents: '' } ],
+				[ '60' ],
+				[ '70', '71' ]
+			] ) );
+		} );
 	} );
 
 	describe( 'getColumns()', () => {