8
0
Prechádzať zdrojové kódy

It should fix table by prepending cells.

Maciej Gołaszewski 5 rokov pred
rodič
commit
a95ec404a3

+ 28 - 3
packages/ckeditor5-table/src/tableselection.js

@@ -214,6 +214,7 @@ export default class TableSelection extends Plugin {
 			writer.insert( table, fragment, 0 );
 
 			const rowsMap = new Map();
+			const columnsIndexesMap = new Map();
 
 			for ( const tableCell of this.getSelectedTableCells() ) {
 				const row = tableCell.parent;
@@ -224,14 +225,38 @@ export default class TableSelection extends Plugin {
 					rowsMap.set( row, newRow );
 				}
 
-				writer.append( tableCell._clone( true ), rowsMap.get( row ) );
-			}
+				const clonedCell = tableCell._clone( true );
+				columnsIndexesMap.set( clonedCell, this._tableUtils.getCellLocation( tableCell ) );
 
-			// Fix table;
+				writer.append( clonedCell, rowsMap.get( row ) );
+			}
 
 			const { row: startRow, column: startColumn } = this._tableUtils.getCellLocation( this._startElement );
 			const { row: endRow, column: endColumn } = this._tableUtils.getCellLocation( this._endElement );
 
+			// Prepend cells.
+			for ( const row of table.getChildren() ) {
+				for ( const tableCell of Array.from( row.getChildren() ) ) {
+					const { column } = this._tableUtils.getCellLocation( tableCell );
+					const { column: originalColumn } = columnsIndexesMap.get( tableCell );
+
+					const shiftedColumn = originalColumn - startColumn;
+
+					if ( column !== shiftedColumn ) {
+						for ( let i = 0; i < shiftedColumn - column; i++ ) {
+							const prepCell = writer.createElement( 'tableCell' );
+							writer.insert( prepCell, writer.createPositionBefore( tableCell ) );
+
+							const paragraph = writer.createElement( 'paragraph' );
+
+							writer.insert( paragraph, prepCell, 0 );
+							writer.insertText( '', paragraph, 0 );
+						}
+					}
+				}
+			}
+
+			// Trim table.
 			const width = endColumn - startColumn + 1;
 			const height = endRow - startRow + 1;
 

+ 55 - 4
packages/ckeditor5-table/tests/tableselection-clipboard.js

@@ -82,7 +82,7 @@ describe( 'table selection', () => {
 				} );
 			} );
 
-			it( 'should fix selected table (cell has colspan that exceeds rectangular selection by 1)', done => {
+			it( 'should trim selected table to a selection rectangle (inner cell with colspan, no colspan after trim)', done => {
 				setModelData( model, modelTable( [
 					[ '11[]', '12', '13' ],
 					[ '21', { contents: '22', colspan: 2 } ],
@@ -108,7 +108,7 @@ describe( 'table selection', () => {
 				} );
 			} );
 
-			it( 'should fix selected table (cell has colspan that exceeds rectangular selection but spans over selection)', done => {
+			it( 'should trim selected table to a selection rectangle (inner cell with colspan, has colspan after trim)', done => {
 				setModelData( model, modelTable( [
 					[ '11[]', '12', '13' ],
 					[ { contents: '21', colspan: 3 } ],
@@ -134,7 +134,7 @@ describe( 'table selection', () => {
 				} );
 			} );
 
-			it( 'should fix selected table (cell has rowspan that exceeds rectangular selection by 1)', done => {
+			it( 'should trim selected table to a selection rectangle (inner cell with rowspan, no colspan after trim)', done => {
 				setModelData( model, modelTable( [
 					[ '11[]', '12', '13' ],
 					[ '21', { contents: '22', rowspan: 2 }, '23' ],
@@ -159,7 +159,7 @@ describe( 'table selection', () => {
 				} );
 			} );
 
-			it( 'should fix selected table (cell has rowspan that exceeds rectangular selection but spans over selection)', done => {
+			it( 'should trim selected table to a selection rectangle (inner cell with rowspan, has rowspan after trim)', done => {
 				setModelData( model, modelTable( [
 					[ '11[]', { contents: '12', rowspan: 3 }, '13' ],
 					[ '21', '23' ],
@@ -183,6 +183,57 @@ describe( 'table selection', () => {
 					preventDefault: sinon.spy()
 				} );
 			} );
+
+			it( 'should prepend spanned columns with empty cells (outside cell with colspan)', done => {
+				setModelData( model, modelTable( [
+					[ '11[]', '12', '13' ],
+					[ { contents: '21', colspan: 2 }, '23' ],
+					[ '31', '32', '33' ]
+				] ) );
+
+				tableSelection.startSelectingFrom( modelRoot.getNodeByPath( [ 0, 0, 1 ] ) );
+				tableSelection.setSelectingTo( modelRoot.getNodeByPath( [ 0, 2, 2 ] ) );
+
+				viewDocument.on( 'clipboardOutput', ( evt, data ) => {
+					expect( stringifyView( data.content ) ).to.equal( viewTable( [
+						[ '12', '13' ],
+						[ '', '23' ],
+						[ '32', '33' ]
+					] ) );
+
+					done();
+				} );
+
+				viewDocument.fire( 'copy', {
+					dataTransfer: createDataTransfer(),
+					preventDefault: sinon.spy()
+				} );
+			} );
+
+			it( 'should prepend spanned columns with empty cells (outside cell with rowspan)', done => {
+				setModelData( model, modelTable( [
+					[ '11[]', { contents: '12', rowspan: 2 }, '13' ],
+					[ '21', '23' ],
+					[ '31', '32', '33' ]
+				] ) );
+
+				tableSelection.startSelectingFrom( modelRoot.getNodeByPath( [ 0, 1, 0 ] ) );
+				tableSelection.setSelectingTo( modelRoot.getNodeByPath( [ 0, 2, 2 ] ) );
+
+				viewDocument.on( 'clipboardOutput', ( evt, data ) => {
+					expect( stringifyView( data.content ) ).to.equal( viewTable( [
+						[ '21', '', '23' ],
+						[ '31', '32', '33' ]
+					] ) );
+
+					done();
+				} );
+
+				viewDocument.fire( 'copy', {
+					dataTransfer: createDataTransfer(),
+					preventDefault: sinon.spy()
+				} );
+			} );
 		} );
 
 		describe( 'cut', () => {