8
0
Просмотр исходного кода

Handle horizontal split when making rectangular selection.

Maciej Gołaszewski 5 лет назад
Родитель
Сommit
22cb400123

+ 2 - 2
packages/ckeditor5-table/src/commands/setheaderrowcommand.js

@@ -109,7 +109,7 @@ export default class SetHeaderRowCommand extends Command {
 // @param {Number} headingRowsToSet New heading rows attribute.
 // @param {Number} currentHeadingRows Current heading rows attribute.
 // @returns {Array.<module:engine/model/element~Element>}
-function getOverlappingCells( table, headingRowsToSet, currentHeadingRows ) {
+export function getOverlappingCells( table, headingRowsToSet, currentHeadingRows ) {
 	const cellsToSplit = [];
 
 	const startAnalysisRow = headingRowsToSet > currentHeadingRows ? currentHeadingRows : 0;
@@ -132,7 +132,7 @@ function getOverlappingCells( table, headingRowsToSet, currentHeadingRows ) {
 // @param {module:engine/model/element~Element} tableCell
 // @param {Number} headingRows
 // @param {module:engine/model/writer~Writer} writer
-function splitHorizontally( tableCell, headingRows, writer ) {
+export function splitHorizontally( tableCell, headingRows, writer ) {
 	const tableRow = tableCell.parent;
 	const table = tableRow.parent;
 	const rowIndex = tableRow.index;

+ 43 - 20
packages/ckeditor5-table/src/tableclipboard.js

@@ -14,6 +14,7 @@ import TableWalker from './tablewalker';
 import { getColumnIndexes, getRowIndexes, isSelectionRectangular } from './utils';
 import { findAncestor } from './commands/utils';
 import { cropTableToDimensions } from './tableselection/croptable';
+import { getOverlappingCells, splitHorizontally } from './commands/setheaderrowcommand';
 import TableUtils from './tableutils';
 
 /**
@@ -127,34 +128,36 @@ export default class TableClipboard extends Plugin {
 
 		const tableUtils = this.editor.plugins.get( TableUtils );
 
-		// Currently not handled. The selected table content should be trimmed to a rectangular selection.
-		// See: https://github.com/ckeditor/ckeditor5/issues/6122.
-		if ( !isSelectionRectangular( selectedTableCells, tableUtils ) ) {
-			// @if CK_DEBUG // console.log( 'NOT IMPLEMENTED YET: Selection is not rectangular (non-mergeable).' );
+		const model = this.editor.model;
 
-			return;
-		}
+		model.change( writer => {
+			// Currently not handled. The selected table content should be trimmed to a rectangular selection.
+			// See: https://github.com/ckeditor/ckeditor5/issues/6122.
+			if ( !isSelectionRectangular( selectedTableCells, tableUtils ) ) {
+				// @if CK_DEBUG // console.log( 'NOT IMPLEMENTED YET: Selection is not rectangular (non-mergeable).' );
 
-		const { last: lastColumnOfSelection, first: firstColumnOfSelection } = getColumnIndexes( selectedTableCells );
-		const { first: firstRowOfSelection, last: lastRowOfSelection } = getRowIndexes( selectedTableCells );
+				prepareLandingPlace( selectedTableCells, writer );
 
-		const selectionHeight = lastRowOfSelection - firstRowOfSelection + 1;
-		const selectionWidth = lastColumnOfSelection - firstColumnOfSelection + 1;
+				// return;
+			}
 
-		const pasteHeight = tableUtils.getRows( pastedTable );
-		const pasteWidth = tableUtils.getColumns( pastedTable );
+			const { last: lastColumnOfSelection, first: firstColumnOfSelection } = getColumnIndexes( selectedTableCells );
+			const { first: firstRowOfSelection, last: lastRowOfSelection } = getRowIndexes( selectedTableCells );
 
-		// The if below is temporal and will be removed when handling this case.
-		// See: https://github.com/ckeditor/ckeditor5/issues/6769.
-		if ( selectionHeight > pasteHeight || selectionWidth > pasteWidth ) {
-			// @if CK_DEBUG // console.log( 'NOT IMPLEMENTED YET: Pasted table is smaller than selection area.' );
+			const selectionHeight = lastRowOfSelection - firstRowOfSelection + 1;
+			const selectionWidth = lastColumnOfSelection - firstColumnOfSelection + 1;
 
-			return;
-		}
+			const pasteHeight = tableUtils.getRows( pastedTable );
+			const pasteWidth = tableUtils.getColumns( pastedTable );
 
-		const model = this.editor.model;
+			// The if below is temporal and will be removed when handling this case.
+			// See: https://github.com/ckeditor/ckeditor5/issues/6769.
+			if ( selectionHeight > pasteHeight || selectionWidth > pasteWidth ) {
+				// @if CK_DEBUG // console.log( 'NOT IMPLEMENTED YET: Pasted table is smaller than selection area.' );
+
+				return;
+			}
 
-		model.change( writer => {
 			// Crop pasted table if it extends selection area.
 			if ( selectionHeight < pasteHeight || selectionWidth < pasteWidth ) {
 				const cropDimensions = {
@@ -299,3 +302,23 @@ function createLocationMap( table, width, height ) {
 
 	return map;
 }
+
+function prepareLandingPlace( selectedTableCells, writer ) {
+	const table = findAncestor( 'table', selectedTableCells[ 0 ] );
+
+	const { first: firstRow, last: lastRow } = getRowIndexes( selectedTableCells );
+
+	if ( firstRow > 0 ) {
+		const cellsToSplitHorizontallyAtFirstRow = getOverlappingCells( table, firstRow, 0 );
+
+		for ( const cell of cellsToSplitHorizontallyAtFirstRow ) {
+			splitHorizontally( cell, firstRow, writer );
+		}
+	}
+
+	const cellsToSplitHorizontallyAtLastRow = getOverlappingCells( table, lastRow + 1, firstRow );
+
+	for ( const cell of cellsToSplitHorizontallyAtLastRow ) {
+		splitHorizontally( cell, lastRow + 1, writer );
+	}
+}