浏览代码

Refactor the `TableUtils#insertColumns()` method.

Maciej Gołaszewski 7 年之前
父节点
当前提交
62a1d0d8b6
共有 2 个文件被更改,包括 76 次插入64 次删除
  1. 38 52
      packages/ckeditor5-table/src/tableutils.js
  2. 38 12
      packages/ckeditor5-table/tests/tableutils.js

+ 38 - 52
packages/ckeditor5-table/src/tableutils.js

@@ -69,10 +69,10 @@ export default class TableUtils extends Plugin {
 		model.change( writer => {
 			const tableColumns = getColumns( table );
 
-			// Inserting at the end of a table
-			if ( tableColumns <= insertAt ) {
+			// Inserting at the end and at the begging of a table doesn't require to calculate anything special.
+			if ( insertAt === 0 || tableColumns <= insertAt ) {
 				for ( const tableRow of table.getChildren() ) {
-					createCells( columns, writer, Position.createAt( tableRow, 'end' ) );
+					createCells( columns, writer, Position.createAt( tableRow, insertAt ? 'end' : 0 ) );
 				}
 
 				return;
@@ -84,35 +84,20 @@ export default class TableUtils extends Plugin {
 				writer.setAttribute( 'headingColumns', headingColumns + columns, table );
 			}
 
-			const tableIterator = new TableWalker( table );
+			for ( const { column, cell: tableCell, colspan } of [ ...new TableWalker( table ) ] ) {
+				// Check if currently analyzed cell overlaps insert position.
+				const isBeforeInsertAt = column < insertAt;
+				const expandsOverInsertAt = column + colspan > insertAt;
 
-			let currentRow = -1;
-			let currentRowInserted = false;
-
-			for ( const tableCellInfo of tableIterator ) {
-				const { row, column, cell: tableCell, colspan } = tableCellInfo;
-
-				if ( currentRow !== row ) {
-					currentRow = row;
-					currentRowInserted = false;
-				}
-
-				const shouldExpandSpan = colspan > 1 &&
-					( column !== insertAt ) &&
-					( column <= insertAt ) &&
-					( column <= insertAt + columns ) &&
-					( column + colspan > insertAt );
-
-				if ( shouldExpandSpan ) {
+				if ( isBeforeInsertAt && expandsOverInsertAt ) {
+					// And if so expand that table cell.
 					writer.setAttribute( 'colspan', colspan + columns, tableCell );
 				}
 
-				if ( column === insertAt || ( column < insertAt + columns && column > insertAt && !currentRowInserted ) ) {
+				if ( column === insertAt ) {
 					const insertPosition = Position.createBefore( tableCell );
 
 					createCells( columns, writer, insertPosition );
-
-					currentRowInserted = true;
 				}
 			}
 		} );
@@ -120,7 +105,6 @@ export default class TableUtils extends Plugin {
 
 	splitCellHorizontally( tableCell, cellNumber = 2 ) {
 		const model = this.editor.model;
-
 		const table = getParentTable( tableCell );
 
 		model.change( writer => {
@@ -131,35 +115,11 @@ export default class TableUtils extends Plugin {
 			const cellColspan = cellData.colspan;
 			const cellRowspan = cellData.rowspan;
 
-			const splitOnly = cellColspan >= cellNumber;
+			const isOnlySplit = cellColspan >= cellNumber;
 
 			const cellsToInsert = cellNumber - 1;
 
-			if ( !splitOnly ) {
-				const cellsToUpdate = tableMap.filter( value => {
-					const cell = value.cell;
-
-					if ( cell === tableCell ) {
-						return false;
-					}
-
-					const colspan = value.colspan;
-					const column = value.column;
-
-					return column === cellColumn || ( column < cellColumn && column + colspan - 1 >= cellColumn );
-				} );
-
-				for ( const tableWalkerValue of cellsToUpdate ) {
-					const colspan = tableWalkerValue.colspan;
-					const cell = tableWalkerValue.cell;
-
-					writer.setAttribute( 'colspan', colspan + cellNumber - 1, cell );
-				}
-
-				for ( let i = 0; i < cellsToInsert; i++ ) {
-					writer.insertElement( 'tableCell', Position.createAfter( tableCell ) );
-				}
-			} else {
+			if ( isOnlySplit ) {
 				const colspanOfInsertedCells = Math.floor( cellColspan / cellNumber );
 				const newColspan = ( cellColspan - colspanOfInsertedCells * cellNumber ) + colspanOfInsertedCells;
 
@@ -178,6 +138,32 @@ export default class TableUtils extends Plugin {
 				for ( let i = 0; i < cellsToInsert; i++ ) {
 					writer.insertElement( 'tableCell', attributes, Position.createAfter( tableCell ) );
 				}
+
+				return;
+			}
+
+			const cellsToUpdate = tableMap.filter( value => {
+				const cell = value.cell;
+
+				if ( cell === tableCell ) {
+					return false;
+				}
+
+				const colspan = value.colspan;
+				const column = value.column;
+
+				return column === cellColumn || ( column < cellColumn && column + colspan - 1 >= cellColumn );
+			} );
+
+			for ( const tableWalkerValue of cellsToUpdate ) {
+				const colspan = tableWalkerValue.colspan;
+				const cell = tableWalkerValue.cell;
+
+				writer.setAttribute( 'colspan', colspan + cellNumber - 1, cell );
+			}
+
+			for ( let i = 0; i < cellsToInsert; i++ ) {
+				writer.insertElement( 'tableCell', Position.createAfter( tableCell ) );
 			}
 		} );
 	}

+ 38 - 12
packages/ckeditor5-table/tests/tableutils.js

@@ -225,6 +225,7 @@ describe( 'TableUtils', () => {
 				[ '21', '', '22' ]
 			] ) );
 		} );
+
 		it( 'should insert column in given table with default values', () => {
 			setData( model, modelTable( [
 				[ '11[]', '12' ],
@@ -253,17 +254,41 @@ describe( 'TableUtils', () => {
 			] ) );
 		} );
 
-		it( 'should insert columns at table end', () => {
+		it( 'should insert columns at the end of a row', () => {
 			setData( model, modelTable( [
-				[ '11[]', '12' ],
-				[ '21', '22' ]
+				[ '00[]', '01' ],
+				[ { colspan: 2, contents: '10' } ],
+				[ '20', { rowspan: 2, contents: '21' } ],
+				[ '30' ]
 			] ) );
 
 			tableUtils.insertColumns( root.getNodeByPath( [ 0 ] ), { at: 2, columns: 2 } );
 
 			expect( formatTable( getData( model ) ) ).to.equal( formattedModelTable( [
-				[ '11[]', '12', '', '' ],
-				[ '21', '22', '', '' ]
+				[ '00[]', '01', '', '' ],
+				[ { colspan: 2, contents: '10' }, '', '' ],
+				[ '20', { rowspan: 2, contents: '21' }, '', '' ],
+				[ '30', '', '' ]
+			] ) );
+		} );
+
+		it( 'should insert columns at the beginning of a row', () => {
+			setData( model, modelTable( [
+				[ '00[]', '01' ],
+				[ { colspan: 2, contents: '10' } ],
+				[ '20', { rowspan: 2, contents: '21' } ],
+				[ { rowspan: 2, contents: '30' } ],
+				[ '41' ]
+			] ) );
+
+			tableUtils.insertColumns( root.getNodeByPath( [ 0 ] ), { at: 0, columns: 2 } );
+
+			expect( formatTable( getData( model ) ) ).to.equal( formattedModelTable( [
+				[ '', '', '00[]', '01' ],
+				[ '', '', { colspan: 2, contents: '10' } ],
+				[ '', '', '20', { rowspan: 2, contents: '21' } ],
+				[ '', '', { rowspan: 2, contents: '30' } ],
+				[ '', '', '41' ]
 			] ) );
 		} );
 
@@ -299,7 +324,7 @@ describe( 'TableUtils', () => {
 			], { headingColumns: 2 } ) );
 		} );
 
-		it( 'should skip spanned columns', () => {
+		it( 'should expand spanned columns', () => {
 			setData( model, modelTable( [
 				[ '11[]', '12' ],
 				[ { colspan: 2, contents: '21' } ],
@@ -331,18 +356,19 @@ describe( 'TableUtils', () => {
 			], { headingColumns: 6 } ) );
 		} );
 
-		// TODO fix me
-		it.skip( 'should skip row spanned cells', () => {
+		it( 'should skip row spanned cells', () => {
 			setData( model, modelTable( [
-				[ { colspan: 2, rowspan: 2, contents: '11[]' }, '13' ],
-				[ '23' ]
+				[ { colspan: 2, rowspan: 2, contents: '00[]' }, '02' ],
+				[ '12' ],
+				[ '20', '21', '22' ]
 			], { headingColumns: 2 } ) );
 
 			tableUtils.insertColumns( root.getNodeByPath( [ 0 ] ), { at: 1, columns: 2 } );
 
 			expect( formatTable( getData( model ) ) ).to.equal( formattedModelTable( [
-				[ { colspan: 4, rowspan: 2, contents: '11[]' }, '13' ],
-				[ '23' ]
+				[ { colspan: 4, rowspan: 2, contents: '00[]' }, '02' ],
+				[ '12' ],
+				[ '20', '', '', '21', '22' ]
 			], { headingColumns: 4 } ) );
 		} );
 	} );