浏览代码

Handle paste only when alone table is pasted.

Maciej Gołaszewski 5 年之前
父节点
当前提交
d002dc9aa7

+ 8 - 7
packages/ckeditor5-table/src/tableclipboard.js

@@ -109,7 +109,7 @@ export default class TableClipboard extends Plugin {
 		}
 
 		// We might need to crop table before inserting so reference might change.
-		let pastedTable = getTableFromContent( content );
+		let pastedTable = getTableIfOnlyTableInContent( content );
 
 		if ( !pastedTable ) {
 			return;
@@ -244,18 +244,19 @@ export default class TableClipboard extends Plugin {
 	}
 }
 
-function getTableFromContent( content ) {
+function getTableIfOnlyTableInContent( content ) {
+	// Table passed directly.
 	if ( content.is( 'table' ) ) {
 		return content;
 	}
 
-	for ( const child of content.getChildren() ) {
-		if ( child.is( 'table' ) ) {
-			return child;
-		}
+	// We do not support mixed content when pasting table into table.
+	// See: https://github.com/ckeditor/ckeditor5/issues/6817.
+	if ( content.childCount > 1 || !content.getChild( 0 ).is( 'table' ) ) {
+		return null;
 	}
 
-	return null;
+	return content.getChild( 0 );
 }
 
 // Returns two-dimensional array that is addressed by [ row ][ column ] that stores cells anchored at given location.

+ 80 - 2
packages/ckeditor5-table/tests/tableclipboard-paste.js

@@ -124,7 +124,85 @@ describe( 'table clipboard', () => {
 			] ) );
 		} );
 
-		it( 'should alter model.insertContent if selectable is  document selection', () => {
+		it( 'should not alter model.insertContent if mixed content is pasted (table + paragraph)', () => {
+			tableSelection.setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+			);
+
+			const table = viewTable( [
+				[ 'aa', 'ab' ],
+				[ 'ba', 'bb' ] ] );
+
+			const data = {
+				dataTransfer: createDataTransfer(),
+				preventDefault: sinon.spy(),
+				stopPropagation: sinon.spy()
+			};
+			data.dataTransfer.setData( 'text/html', `${ table }<p>foo</p>` );
+			viewDocument.fire( 'paste', data );
+
+			assertEqualMarkup( getModelData( model, { withoutSelection: true } ), modelTable( [
+				[ 'foo', '', '02', '03' ],
+				[ '', '', '12', '13' ],
+				[ '20', '21', '22', '23' ],
+				[ '30', '31', '32', '33' ]
+			] ) );
+		} );
+
+		it( 'should not alter model.insertContent if mixed content is pasted (paragraph + table)', () => {
+			tableSelection.setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+			);
+
+			const table = viewTable( [
+				[ 'aa', 'ab' ],
+				[ 'ba', 'bb' ] ] );
+
+			const data = {
+				dataTransfer: createDataTransfer(),
+				preventDefault: sinon.spy(),
+				stopPropagation: sinon.spy()
+			};
+			data.dataTransfer.setData( 'text/html', `<p>foo</p>${ table }` );
+			viewDocument.fire( 'paste', data );
+
+			assertEqualMarkup( getModelData( model, { withoutSelection: true } ), modelTable( [
+				[ 'foo', '', '02', '03' ],
+				[ '', '', '12', '13' ],
+				[ '20', '21', '22', '23' ],
+				[ '30', '31', '32', '33' ]
+			] ) );
+		} );
+
+		it( 'should not alter model.insertContent if mixed content is pasted (table + table)', () => {
+			tableSelection.setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+			);
+
+			const table = viewTable( [
+				[ 'aa', 'ab' ],
+				[ 'ba', 'bb' ] ] );
+
+			const data = {
+				dataTransfer: createDataTransfer(),
+				preventDefault: sinon.spy(),
+				stopPropagation: sinon.spy()
+			};
+			data.dataTransfer.setData( 'text/html', `${ table }${ table }` );
+			viewDocument.fire( 'paste', data );
+
+			assertEqualMarkup( getModelData( model, { withoutSelection: true } ), modelTable( [
+				[ '', '', '02', '03' ],
+				[ '', '', '12', '13' ],
+				[ '20', '21', '22', '23' ],
+				[ '30', '31', '32', '33' ]
+			] ) );
+		} );
+
+		it( 'should alter model.insertContent if selectable is a document selection', () => {
 			tableSelection.setCellSelection(
 				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
 				modelRoot.getNodeByPath( [ 0, 1, 1 ] )
@@ -1409,7 +1487,7 @@ describe( 'table clipboard', () => {
 	} );
 
 	describe( 'Clipboard integration - paste (content scenarios)', () => {
-		it( 'handles multiple paragraphs', async () => {
+		it( 'handles multiple paragraphs in table cell', async () => {
 			await createEditor();
 
 			setModelData( model, modelTable( [