浏览代码

Added: Make insert row command aware of previous rowspans.

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

+ 1 - 1
packages/ckeditor5-table/src/converters/downcasttable.js

@@ -367,7 +367,7 @@ function removeTableSectionIfEmpty( sectionName, tableElement, conversionApi ) {
 	}
 }
 
-function getNumericAttribute( element, attribute, defaultValue ) {
+export function getNumericAttribute( element, attribute, defaultValue ) {
 	return element.hasAttribute( attribute ) ? parseInt( element.getAttribute( attribute ) ) : defaultValue;
 }
 

+ 41 - 7
packages/ckeditor5-table/src/insertrowcommand.js

@@ -8,6 +8,7 @@
  */
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
+import { CellSpans, getNumericAttribute } from './converters/downcasttable';
 
 /**
  * The insert row command.
@@ -50,21 +51,54 @@ export default class InsertRowCommand extends Command {
 
 		const columns = getColumns( table );
 
+		const cellSpans = new CellSpans();
+
 		model.change( writer => {
 			if ( headingRows > insertAt ) {
 				writer.setAttribute( 'headingRows', headingRows + rows, table );
 			}
 
-			// TODO: test me - I'm wrong
-			for ( let rowIndex = 0; rowIndex < rows; rowIndex++ ) {
-				const row = writer.createElement( 'tableRow' );
+			let tableRow;
+
+			for ( let rowIndex = 0; rowIndex < insertAt + rows; rowIndex++ ) {
+				if ( rowIndex < insertAt ) {
+					tableRow = table.getChild( rowIndex );
+
+					// Record spans, update rowspans
+					let columnIndex = 0;
+
+					for ( const tableCell of Array.from( tableRow.getChildren() ) ) {
+						columnIndex = cellSpans.getNextFreeColumnIndex( rowIndex, columnIndex );
+
+						const colspan = getNumericAttribute( tableCell, 'colspan', 1 );
+						let rowspan = getNumericAttribute( tableCell, 'rowspan', 1 );
+
+						if ( rowspan > 1 ) {
+							// check whether rowspan overlaps inserts:
+							if ( rowIndex < insertAt && rowIndex + rowspan > insertAt ) {
+								rowspan = rowspan + rows;
+
+								writer.setAttribute( 'rowspan', rowspan, tableCell );
+							}
+
+							cellSpans.recordSpans( rowIndex, columnIndex, rowspan, colspan );
+						}
+
+						columnIndex = columnIndex + colspan;
+					}
+				} else {
+					// Create new rows
+					tableRow = writer.createElement( 'tableRow' );
+
+					writer.insert( tableRow, table, insertAt );
 
-				writer.insert( row, table, insertAt );
+					for ( let columnIndex = 0; columnIndex < columns; columnIndex++ ) {
+						columnIndex = cellSpans.getNextFreeColumnIndex( rowIndex, columnIndex );
 
-				for ( let column = 0; column < columns; column++ ) {
-					const cell = writer.createElement( 'tableCell' );
+						const cell = writer.createElement( 'tableCell' );
 
-					writer.insert( cell, row, 'end' );
+						writer.insert( cell, tableRow, 'end' );
+					}
 				}
 			}
 		} );

+ 0 - 21
packages/ckeditor5-table/tests/converters/downcasttable.js

@@ -402,27 +402,6 @@ describe( 'downcastTable()', () => {
 				[ { contents: '', isHeading: true }, '' ]
 			] ) );
 		} );
-
-		it( 'should properly create row headings when previous has colspan', () => {
-			setModelData( model, modelTable( [
-				[ { rowspan: 2, colspan: 2, contents: '11' }, '13', '14' ]
-			], { headingColumns: 3 } ) );
-
-			const table = root.getChild( 0 );
-
-			model.change( writer => {
-				const firstRow = writer.createElement( 'tableRow' );
-
-				writer.insert( firstRow, table, 1 );
-				writer.insert( writer.createElement( 'tableCell' ), firstRow, 'end' );
-				writer.insert( writer.createElement( 'tableCell' ), firstRow, 'end' );
-			} );
-
-			expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal( viewTable( [
-				[ { colspan: 2, rowspan: 2, contents: '11', isHeading: true }, { isHeading: true, contents: '13' }, '14' ],
-				[ { contents: '', isHeading: true }, '' ]
-			] ) );
-		} );
 	} );
 
 	describe( 'downcastInsertCell()', () => {

+ 38 - 0
packages/ckeditor5-table/tests/insertrowcommand.js

@@ -147,5 +147,43 @@ describe( 'InsertRowCommand', () => {
 				[ '31', '32' ]
 			], { headingRows: 2 } ) );
 		} );
+
+		it( 'should expand rowspan of a cell that overlaps inserted rows', () => {
+			setData( model, modelTable( [
+				[ { colspan: 2, contents: '11[]' }, '13', '14' ],
+				[ { colspan: 2, rowspan: 4, contents: '21' }, '23', '24' ],
+				[ '33', '34' ]
+			], { headingColumns: 3, headingRows: 1 } ) );
+
+			command.execute( { at: 2, rows: 3 } );
+
+			expect( formatModelTable( getData( model ) ) ).to.equal( formattedModelTable( [
+				[ { colspan: 2, contents: '11[]' }, '13', '14' ],
+				[ { colspan: 2, rowspan: 7, contents: '21' }, '23', '24' ],
+				[ '', '' ],
+				[ '', '' ],
+				[ '', '' ],
+				[ '33', '34' ]
+			], { headingColumns: 3, headingRows: 1 } ) );
+		} );
+
+		it( 'should not expand rowspan of a cell that does not overlaps inserted rows', () => {
+			setData( model, modelTable( [
+				[ { rowspan: 2, contents: '11[]' }, '12', '13' ],
+				[ '22', '23', '24' ],
+				[ '33', '34' ]
+			], { headingColumns: 3, headingRows: 1 } ) );
+
+			command.execute( { at: 2, rows: 3 } );
+
+			expect( formatModelTable( getData( model ) ) ).to.equal( formattedModelTable( [
+				[ { rowspan: 2, contents: '11[]' }, '12', '13' ],
+				[ '22', '23', '24' ],
+				[ '', '', '' ],
+				[ '', '', '' ],
+				[ '', '', '' ],
+				[ '33', '34' ]
+			], { headingColumns: 3, headingRows: 1 } ) );
+		} );
 	} );
 } );