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

Handle pasting over table with colspans.

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

+ 30 - 6
packages/ckeditor5-table/src/tableclipboard.js

@@ -134,11 +134,21 @@ export default class TableClipboard extends Plugin {
 						insertionMap.set( `${ row }x${ column }`, cell );
 					}
 
-					const tableMap = [ ...new TableWalker( contentTable, { startRow: rowIndexes.first, endRow: rowIndexes.last } ) ];
+					const tableMap = [ ...new TableWalker( contentTable, {
+						startRow: rowIndexes.first,
+						endRow: rowIndexes.last,
+						includeSpanned: true
+					} ) ];
 
-					for ( const { column, row, cell } of tableMap ) {
+					let previousCell;
+
+					const cellsToSelect = [];
+
+					for ( const { column, row, cell, isSpanned } of tableMap ) {
 						// TODO: crete issue for table walker startColumn, endColumn.
 						if ( column < columnIndexes.first || column > columnIndexes.last ) {
+							previousCell = cell;
+
 							continue;
 						}
 
@@ -146,19 +156,33 @@ export default class TableClipboard extends Plugin {
 						const cellToInsert = insertionMap.get( toGet );
 
 						if ( !cellToInsert ) {
-							writer.remove( writer.createRangeOn( cell ) );
+							if ( !isSpanned ) {
+								writer.remove( writer.createRangeOn( cell ) );
+							}
 
 							continue;
 						}
 
-						writer.remove( writer.createRangeIn( cell ) );
+						let targetCell = cell;
 
-						updateNumericAttribute( 'colspan', cellToInsert.getAttribute( 'colspan' ), cell, writer, 1 );
+						if ( isSpanned ) {
+							targetCell = writer.createElement( 'tableCell' );
+							writer.insert( targetCell, writer.createPositionAfter( previousCell ) );
+						} else {
+							writer.remove( writer.createRangeIn( cell ) );
+						}
+
+						updateNumericAttribute( 'colspan', cellToInsert.getAttribute( 'colspan' ), targetCell, writer, 1 );
 
 						for ( const child of cellToInsert.getChildren() ) {
-							writer.insert( child, cell, 'end' );
+							writer.insert( child, targetCell, 'end' );
 						}
+
+						cellsToSelect.push( targetCell );
+						previousCell = targetCell;
 					}
+
+					writer.setSelection( cellsToSelect.map( cell => writer.createRangeOn( cell ) ) );
 				} );
 
 				return;

+ 76 - 0
packages/ckeditor5-table/tests/tableclipboard.js

@@ -671,6 +671,82 @@ describe( 'table clipboard', () => {
 						/* eslint-enable no-multi-spaces */
 					} );
 				} );
+
+				describe( 'content table has spans', () => {
+					it( 'handles pasting simple table over table with colspans (no colspan exceeds selection)', () => {
+						setModelData( model, modelTable( [
+							[ '00[]', '01', '02', '03' ],
+							[ { colspan: 3, contents: '10' }, '13' ],
+							[ { colspan: 2, contents: '20' }, '22', '23' ],
+							[ '30', '31', { colspan: 2, contents: '31' } ]
+						] ) );
+
+						tableSelection._setCellSelection(
+							modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+							modelRoot.getNodeByPath( [ 0, 2, 1 ] )
+						);
+
+						pasteTable( [
+							[ 'aa', 'ab', 'ac' ],
+							[ 'ba', 'bb', 'bc' ],
+							[ 'ca', 'cb', 'cc' ]
+						] );
+
+						assertEqualMarkup( getModelData( model, { withoutSelection: true } ), modelTable( [
+							[ 'aa', 'ab', 'ac', '03' ],
+							[ 'ba', 'bb', 'bc', '13' ],
+							[ 'ca', 'cb', 'cc', '23' ],
+							[ '30', '31', { colspan: 2, contents: '31' } ]
+						] ) );
+
+						/* eslint-disable no-multi-spaces */
+						assertSelectedCells( model, [
+							[ 1, 1, 1, 0 ],
+							[ 1, 1, 1, 0 ],
+							[ 1, 1, 1, 0 ],
+							[ 0, 0, 0    ]
+						] );
+						/* eslint-enable no-multi-spaces */
+					} );
+				} );
+
+				describe( 'content and paste tables have spans', () => {
+					it( 'handles pasting simple table over table with colspans (no colspan exceeds selection)', () => {
+						setModelData( model, modelTable( [
+							[ '00[]', '01', '02', '03' ],
+							[ { colspan: 3, contents: '10' }, '13' ],
+							[ { colspan: 2, contents: '20' }, '22', '23' ],
+							[ '30', '31', { colspan: 2, contents: '31' } ]
+						] ) );
+
+						tableSelection._setCellSelection(
+							modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+							modelRoot.getNodeByPath( [ 0, 2, 1 ] )
+						);
+
+						pasteTable( [
+							[ 'aa', { colspan: 2, contents: 'ab' } ],
+							[ { colspan: 3, contents: 'ba' } ],
+							[ 'ca', 'cb', 'cc' ]
+						] );
+
+						assertEqualMarkup( getModelData( model, { withoutSelection: true } ), modelTable( [
+							[ 'aa', { colspan: 2, contents: 'ab' }, '03' ],
+							[ { colspan: 3, contents: 'ba' }, '13' ],
+							[ 'ca', 'cb', 'cc', '23' ],
+							[ '30', '31', { colspan: 2, contents: '31' } ]
+						] ) );
+
+						/* eslint-disable no-multi-spaces */
+						assertSelectedCells( model, [
+							[ 1, 1,    0 ],
+							[ 1,       0 ],
+							[ 1, 1, 1, 0 ],
+							[ 0, 0, 0    ]
+						] );
+						/* eslint-enable no-multi-spaces */
+					} );
+				} );
 			} );
 		} );
 	} );