ソースを参照

Handle block content in pasted table cells.

Maciej Gołaszewski 5 年 前
コミット
be31d7204d

+ 3 - 3
packages/ckeditor5-table/src/tableclipboard.js

@@ -138,9 +138,8 @@ export default class TableClipboard extends Plugin {
 		const model = this.editor.model;
 
 		model.change( writer => {
+			// Pasted table extends selection area.
 			if ( selectionHeight < insertHeight || selectionWidth < insertWidth ) {
-				// @if CK_DEBUG // console.log( 'Pasted table extends selection area.' );
-
 				table = cropTableToDimensions( table, 0, 0, selectionHeight - 1, selectionWidth - 1, tableUtils, writer );
 			}
 
@@ -200,7 +199,8 @@ export default class TableClipboard extends Plugin {
 				updateNumericAttribute( 'colspan', cellToInsert.getAttribute( 'colspan' ), targetCell, writer, 1 );
 				updateNumericAttribute( 'rowspan', cellToInsert.getAttribute( 'rowspan' ), targetCell, writer, 1 );
 
-				for ( const child of cellToInsert.getChildren() ) {
+				// TODO: use Element._clone to copy full structure.
+				for ( const child of Array.from( cellToInsert.getChildren() ) ) {
 					writer.insert( child, targetCell, 'end' );
 				}
 

+ 79 - 17
packages/ckeditor5-table/tests/tableclipboard-paste.js

@@ -15,23 +15,26 @@ import { assertSelectedCells, modelTable, viewTable } from './_utils/utils';
 import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 
 import TableClipboard from '../src/tableclipboard';
+import ImageEditing from '@ckeditor/ckeditor5-image/src/image/imageediting';
+import ImageCaptionEditing from '@ckeditor/ckeditor5-image/src/imagecaption/imagecaptionediting';
 
 describe( 'table clipboard', () => {
 	let editor, model, modelRoot, tableSelection, viewDocument, element;
 
-	describe( 'Clipboard integration - paste (selection scenarios)', () => {
-		beforeEach( async () => {
-			element = document.createElement( 'div' );
-			document.body.appendChild( element );
+	beforeEach( () => {
+		element = document.createElement( 'div' );
+		document.body.appendChild( element );
+	} );
 
-			editor = await ClassicTestEditor.create( element, {
-				plugins: [ TableEditing, TableClipboard, Paragraph, Clipboard ]
-			} );
+	afterEach( async () => {
+		await editor.destroy();
 
-			model = editor.model;
-			modelRoot = model.document.getRoot();
-			viewDocument = editor.editing.view.document;
-			tableSelection = editor.plugins.get( 'TableSelection' );
+		element.remove();
+	} );
+
+	describe( 'Clipboard integration - paste (selection scenarios)', () => {
+		beforeEach( async () => {
+			await createEditor();
 
 			setModelData( model, modelTable( [
 				[ '00[]', '01', '02', '03' ],
@@ -41,12 +44,6 @@ describe( 'table clipboard', () => {
 			] ) );
 		} );
 
-		afterEach( async () => {
-			await editor.destroy();
-
-			element.remove();
-		} );
-
 		it( 'should be disabled in a readonly mode', () => {
 			editor.isReadOnly = true;
 
@@ -1228,6 +1225,71 @@ describe( 'table clipboard', () => {
 		} );
 	} );
 
+	describe( 'Clipboard integration - paste (content scenarios)', () => {
+		it( 'handles multiple paragraphs', async () => {
+			await createEditor();
+
+			setModelData( model, modelTable( [
+				[ '00', '01', '02' ],
+				[ '01', '11', '12' ],
+				[ '02', '21', '22' ]
+			] ) );
+
+			tableSelection.setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+			);
+
+			pasteTable( [
+				[ '<p>a</p><p>a</p><p>a</p>', 'ab' ],
+				[ 'ba', 'bb' ]
+			] );
+
+			assertEqualMarkup( getModelData( model, { withoutSelection: true } ), modelTable( [
+				[ '<paragraph>a</paragraph><paragraph>a</paragraph><paragraph>a</paragraph>', 'ab', '02' ],
+				[ 'ba', 'bb', '12' ],
+				[ '02', '21', '22' ]
+			] ) );
+		} );
+
+		it( 'handles image in table cell', async () => {
+			await createEditor( [ ImageEditing, ImageCaptionEditing ] );
+
+			setModelData( model, modelTable( [
+				[ '00', '01', '02' ],
+				[ '01', '11', '12' ],
+				[ '02', '21', '22' ]
+			] ) );
+
+			tableSelection.setCellSelection(
+				modelRoot.getNodeByPath( [ 0, 0, 0 ] ),
+				modelRoot.getNodeByPath( [ 0, 1, 1 ] )
+			);
+
+			pasteTable( [
+				[ '<img src="/assets/sample.jpg">', 'ab' ],
+				[ 'ba', 'bb' ]
+			] );
+
+			assertEqualMarkup( getModelData( model, { withoutSelection: true } ), modelTable( [
+				[ '<image src="/assets/sample.jpg"><caption></caption></image>', 'ab', '02' ],
+				[ 'ba', 'bb', '12' ],
+				[ '02', '21', '22' ]
+			] ) );
+		} );
+	} );
+
+	async function createEditor( extraPlugins = [] ) {
+		editor = await ClassicTestEditor.create( element, {
+			plugins: [ TableEditing, TableClipboard, Paragraph, Clipboard, ...extraPlugins ]
+		} );
+
+		model = editor.model;
+		modelRoot = model.document.getRoot();
+		viewDocument = editor.editing.view.document;
+		tableSelection = editor.plugins.get( 'TableSelection' );
+	}
+
 	function pasteTable( tableData ) {
 		const data = {
 			dataTransfer: createDataTransfer(),