Sfoglia il codice sorgente

Merge pull request #69 from ckeditor/t/68

Fix: Images pasted with additional HTML content will not be handled by the upload plugin. Closes #68.
Piotrek Koszuliński 8 anni fa
parent
commit
6f86111cd1

+ 14 - 0
packages/ckeditor5-upload/src/imageuploadengine.js

@@ -46,6 +46,12 @@ export default class ImageUploadEngine extends Plugin {
 
 		// Execute imageUpload command when image is dropped or pasted.
 		editor.editing.view.on( 'clipboardInput', ( evt, data ) => {
+			// Skip if non empty HTML data is included.
+			// https://github.com/ckeditor/ckeditor5-upload/issues/68
+			if ( isHtmlIncluded( data.dataTransfer ) ) {
+				return;
+			}
+
 			let targetModelSelection = new ModelSelection(
 				data.targetRanges.map( viewRange => editor.editing.mapper.toModelRange( viewRange ) )
 			);
@@ -194,3 +200,11 @@ export default class ImageUploadEngine extends Plugin {
 		}
 	}
 }
+
+// Returns true if non-empty `text/html` is included in data transfer.
+//
+// @param {module:clipboard/datatransfer~DataTransfer} dataTransfer
+// @returns {Boolean}
+export function isHtmlIncluded( dataTransfer ) {
+	return dataTransfer.types.indexOf( 'text/html' ) > -1 && dataTransfer.getData( 'text/html' ) !== '';
+}

+ 22 - 4
packages/ckeditor5-upload/tests/imageuploadengine.js

@@ -74,7 +74,7 @@ describe( 'ImageUploadEngine', () => {
 	it( 'should execute imageUpload command when image is pasted', () => {
 		const spy = sinon.spy( editor, 'execute' );
 		const fileMock = createNativeFileMock();
-		const dataTransfer = new DataTransfer( { files: [ fileMock ] } );
+		const dataTransfer = new DataTransfer( { files: [ fileMock ], types: [ 'Files' ] } );
 		setModelData( doc, '<paragraph>[]foo</paragraph>' );
 
 		const targetRange = Range.createFromParentsAndOffsets( doc.getRoot(), 1, doc.getRoot(), 1 );
@@ -94,7 +94,7 @@ describe( 'ImageUploadEngine', () => {
 	it( 'should execute imageUpload command with an optimized position when image is pasted', () => {
 		const spy = sinon.spy( editor, 'execute' );
 		const fileMock = createNativeFileMock();
-		const dataTransfer = new DataTransfer( { files: [ fileMock ] } );
+		const dataTransfer = new DataTransfer( { files: [ fileMock ], types: [ 'Files' ] } );
 		setModelData( doc, '<paragraph>[]foo</paragraph>' );
 
 		const paragraph = doc.getRoot().getChild( 0 );
@@ -115,7 +115,7 @@ describe( 'ImageUploadEngine', () => {
 	it( 'should execute imageUpload command when multiple files image are pasted', () => {
 		const spy = sinon.spy( editor, 'execute' );
 		const files = [ createNativeFileMock(), createNativeFileMock() ];
-		const dataTransfer = new DataTransfer( { files } );
+		const dataTransfer = new DataTransfer( { files, types: [ 'Files' ] } );
 		setModelData( doc, '<paragraph>[]foo</paragraph>' );
 
 		const targetRange = Range.createFromParentsAndOffsets( doc.getRoot(), 1, doc.getRoot(), 1 );
@@ -143,7 +143,7 @@ describe( 'ImageUploadEngine', () => {
 			type: 'media/mp3',
 			size: 1024
 		};
-		const dataTransfer = new DataTransfer( { files: [ fileMock ] } );
+		const dataTransfer = new DataTransfer( { files: [ fileMock ], types: [ 'Files' ] } );
 
 		setModelData( doc, '<paragraph>foo[]</paragraph>' );
 
@@ -155,6 +155,24 @@ describe( 'ImageUploadEngine', () => {
 		sinon.assert.notCalled( spy );
 	} );
 
+	it( 'should not execute imageUpload command when there is non-empty HTML content pasted', () => {
+		const spy = sinon.spy( editor, 'execute' );
+		const fileMock = createNativeFileMock();
+		const dataTransfer = new DataTransfer( {
+			files: [ fileMock ],
+			types: [ 'Files', 'text/html' ],
+			getData: type => type === 'text/html' ? '<p>SomeData</p>' : ''
+		} );
+		setModelData( doc, '<paragraph>[]foo</paragraph>' );
+
+		const targetRange = Range.createFromParentsAndOffsets( doc.getRoot(), 1, doc.getRoot(), 1 );
+		const targetViewRange = editor.editing.mapper.toViewRange( targetRange );
+
+		viewDocument.fire( 'clipboardInput', { dataTransfer, targetRanges: [ targetViewRange ] } );
+
+		sinon.assert.notCalled( spy );
+	} );
+
 	it( 'should not convert image\'s uploadId attribute if is consumed already', () => {
 		editor.editing.modelToView.on( 'addAttribute:uploadId:image', ( evt, data, consumable ) => {
 			consumable.consume( data.item, eventNameToConsumableType( evt.name ) );