Explorar el Código

Refactor cropTableToDimensions().

Maciej Gołaszewski hace 5 años
padre
commit
3ac58ce999
Se han modificado 1 ficheros con 50 adiciones y 88 borrados
  1. 50 88
      packages/ckeditor5-table/src/tableselection/croptable.js

+ 50 - 88
packages/ckeditor5-table/src/tableselection/croptable.js

@@ -7,7 +7,7 @@
  * @module table/tableselection/croptable
  */
 
-import { findAncestor } from '../commands/utils';
+import { findAncestor, updateNumericAttribute } from '../commands/utils';
 import TableWalker from '../tablewalker';
 
 /**
@@ -27,16 +27,48 @@ import TableWalker from '../tablewalker';
  * @returns {module:engine/model/element~Element}
  */
 export function cropTableToDimensions( sourceTable, startRow, startColumn, endRow, endColumn, tableUtils, writer ) {
-	const tableCopy = makeTableCopy( sourceTable, startRow, startColumn, endRow, endColumn, writer, tableUtils );
+	const croppedTable = writer.createElement( 'table' );
 
-	const selectionWidth = endColumn - startColumn + 1;
-	const selectionHeight = endRow - startRow + 1;
+	// Create needed rows.
+	for ( let i = 0; i < endRow - startRow + 1; i++ ) {
+		writer.insertElement( 'tableRow', croppedTable, 'end' );
+	}
+
+	const tableMap = [ ...new TableWalker( sourceTable, { startRow, endRow, includeSpanned: true } ) ];
+
+	for ( const { row: sourceRow, column: sourceColumn, cell: tableCell, isSpanned } of tableMap ) {
+		if ( sourceColumn < startColumn || sourceColumn > endColumn ) {
+			continue;
+		}
+
+		const insertRow = sourceRow - startRow;
+		const insertColumn = sourceColumn - startColumn;
+
+		const row = croppedTable.getChild( insertRow );
+
+		if ( isSpanned ) {
+			const { row: anchorRow, column: anchorColumn } = tableUtils.getCellLocation( tableCell );
+
+			if ( anchorRow < startRow || anchorColumn < startColumn ) {
+				const tableCell = writer.createElement( 'tableCell' );
+				const paragraph = writer.createElement( 'paragraph' );
+
+				writer.insert( paragraph, tableCell, 0 );
+				writer.insertText( '', paragraph, 0 );
 
-	trimTable( tableCopy, selectionWidth, selectionHeight, writer, tableUtils );
+				writer.append( tableCell, row );
+			}
+		} else {
+			const tableCellCopy = tableCell._clone( true );
 
-	addHeadingsToTableCopy( tableCopy, sourceTable, startRow, startColumn, writer );
+			writer.append( tableCellCopy, row );
 
-	return tableCopy;
+			trimTableCell( tableCellCopy, tableUtils, writer, insertRow, insertColumn, startRow, startColumn, endRow, endColumn );
+		}
+	}
+	addHeadingsToTableCopy( croppedTable, sourceTable, startRow, startColumn, writer );
+
+	return croppedTable;
 }
 
 /**
@@ -69,93 +101,23 @@ export function cropTableToSelection( selectedTableCellsIterator, tableUtils, wr
 	return cropTableToDimensions( sourceTable, startRow, startColumn, endRow, endColumn, tableUtils, writer );
 }
 
-// Creates a table copy from a selected table cells.
-//
-// It fills "gaps" in copied table - ie when cell outside copied range was spanning over selection.
-function makeTableCopy( sourceTable, startRow, startColumn, endRow, endColumn, writer, tableUtils ) {
-	const tableCopy = writer.createElement( 'table' );
-
-	const rowToCopyMap = new Map();
-	const copyToOriginalColumnMap = new Map();
-
-	for ( const { column, cell: tableCell } of [ ...new TableWalker( sourceTable, { startRow, endRow } ) ] ) {
-		if ( column < startColumn || column > endColumn ) {
-			continue;
-		}
-
-		const row = findAncestor( 'tableRow', tableCell );
-
-		if ( !rowToCopyMap.has( row ) ) {
-			const rowCopy = row._clone();
-			writer.append( rowCopy, tableCopy );
-			rowToCopyMap.set( row, rowCopy );
-		}
-
-		const tableCellCopy = tableCell._clone( true );
-
-		copyToOriginalColumnMap.set( tableCellCopy, column );
-
-		writer.append( tableCellCopy, rowToCopyMap.get( row ) );
-	}
-
-	addMissingTableCells( tableCopy, startColumn, copyToOriginalColumnMap, writer, tableUtils );
-
-	return tableCopy;
-}
-
-// Fills gaps for spanned cell from outside the selection range.
-function addMissingTableCells( tableCopy, startColumn, copyToOriginalColumnMap, writer, tableUtils ) {
-	for ( const row of tableCopy.getChildren() ) {
-		for ( const tableCell of Array.from( row.getChildren() ) ) {
-			const { column } = tableUtils.getCellLocation( tableCell );
-
-			const originalColumn = copyToOriginalColumnMap.get( tableCell );
-			const shiftedColumn = originalColumn - startColumn;
+function trimTableCell( tableCell, tableUtils, writer, row, column, startRow, startColumn, endRow, endColumn ) {
+	const colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );
+	const rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );
 
-			if ( column !== shiftedColumn ) {
-				for ( let i = 0; i < shiftedColumn - column; i++ ) {
-					const prepCell = writer.createElement( 'tableCell' );
-					writer.insert( prepCell, writer.createPositionBefore( tableCell ) );
+	const width = endColumn - startColumn + 1;
+	const height = endRow - startRow + 1;
 
-					const paragraph = writer.createElement( 'paragraph' );
+	if ( column + colspan > width ) {
+		const newSpan = width - column;
 
-					writer.insert( paragraph, prepCell, 0 );
-					writer.insertText( '', paragraph, 0 );
-				}
-			}
-		}
+		updateNumericAttribute( 'colspan', newSpan, tableCell, writer, 1 );
 	}
-}
-
-// Trims table to a given dimensions.
-function trimTable( table, width, height, writer, tableUtils ) {
-	for ( const row of table.getChildren() ) {
-		for ( const tableCell of row.getChildren() ) {
-			const colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );
-			const rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );
-
-			const { row, column } = tableUtils.getCellLocation( tableCell );
 
-			if ( column + colspan > width ) {
-				const newSpan = width - column;
+	if ( row + rowspan > height ) {
+		const newSpan = height - row;
 
-				if ( newSpan > 1 ) {
-					writer.setAttribute( 'colspan', newSpan, tableCell );
-				} else {
-					writer.removeAttribute( 'colspan', tableCell );
-				}
-			}
-
-			if ( row + rowspan > height ) {
-				const newSpan = height - row;
-
-				if ( newSpan > 1 ) {
-					writer.setAttribute( 'rowspan', newSpan, tableCell );
-				} else {
-					writer.removeAttribute( 'rowspan', tableCell );
-				}
-			}
-		}
+		updateNumericAttribute( 'rowspan', newSpan, tableCell, writer, 1 );
 	}
 }