diff --git a/CHANGES.md b/CHANGES.md index f61821b9536..1c4a63b6967 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,12 @@ Fixed Issues: * [#3524](https://github.com/ckeditor/ckeditor4/issues/3524): Fixed: [Easy Image](https://ckeditor.com/cke4/addon/easyimage) plugin throws an error when any image with not supported data type is pasted into editor. * [#3552](https://github.com/ckeditor/ckeditor4/issues/3352): Fixed: Incorrect value of [`CKEDITOR.plugins.widget.repository#selected`](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_plugins_widget_repository.html#property-selected) after selecting whole editor's content. * [#3586](https://github.com/ckeditor/ckeditor4/issues/3586): Fixed: Content pasted from Excel is not correctly recognised by [Paste from Word](https://ckeditor.com/cke4/addon/pastefromword) plugin. +* [#3585](https://github.com/ckeditor/ckeditor4/issues/3585): [Firefox] Fixed: Excel content is pasted as an image. +* [#3625](https://github.com/ckeditor/ckeditor4/issues/3625): [Firefox] Fixed: PowerPoint content is pasted as an image. + +API Changes: + +* [#3634](https://github.com/ckeditor/ckeditor4/issues/3634): Added the [`CKEDITOR.plugins.clipboard.dataTransfer#getTypes()`](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_plugins_clipboard_dataTransfer.html#method-getTypes) method. ## CKEditor 4.13 diff --git a/plugins/clipboard/plugin.js b/plugins/clipboard/plugin.js index 86867f002bb..136904a0f7b 100644 --- a/plugins/clipboard/plugin.js +++ b/plugins/clipboard/plugin.js @@ -158,7 +158,7 @@ dataTransfer = dataObj.dataTransfer; // If data empty check for image content inside data transfer. https://dev.ckeditor.com/ticket/16705 - if ( !data && dataObj.method == 'paste' && dataTransfer && dataTransfer.getFilesCount() == 1 && latestId != dataTransfer.id ) { + if ( !data && dataObj.method == 'paste' && isFileData( dataTransfer ) ) { var file = dataTransfer.getFile( 0 ); if ( CKEDITOR.tools.indexOf( supportedImageTypes, file.type ) != -1 ) { @@ -190,6 +190,20 @@ }, null, null, 1 ); } + // Only dataTransfer objects containing only file should be considered + // to image pasting (#3585, #3625). + function isFileData( dataTransfer ) { + if ( !dataTransfer || latestId === dataTransfer.id ) { + return false; + } + + var types = dataTransfer.getTypes(), + isFileOnly = types.length === 1 && types[ 0 ] === 'Files', + containsFile = dataTransfer.getFilesCount() === 1; + + return isFileOnly && containsFile; + } + editor.on( 'paste', function( evt ) { // Init `dataTransfer` if `paste` event was fired without it, so it will be always available. if ( !evt.data.dataTransfer ) { @@ -2712,6 +2726,20 @@ return true; }, + /** + * Returns all MIME types inside the clipboard data. + * + * @since 4.13.1 + * @returns {String[]} + */ + getTypes: function() { + if ( !this.$ || !this.$.types ) { + return []; + } + + return [].slice.call( this.$.types ); + }, + /** * When the content of the clipboard is pasted in Chrome, the clipboard data object has an empty `files` property, * but it is possible to get the file as `items[0].getAsFile();` (https://dev.ckeditor.com/ticket/12961). diff --git a/tests/plugins/clipboard/datatransfer.js b/tests/plugins/clipboard/datatransfer.js index e3932d4684d..3b4190df196 100644 --- a/tests/plugins/clipboard/datatransfer.js +++ b/tests/plugins/clipboard/datatransfer.js @@ -1212,5 +1212,45 @@ bender.test( { var dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer( nativeData ); assert.areSame( '
Paste inside me
+Paste image here: ^@
' ); }, - assertPaste: function( type, expected ) { + // (#3585, #3625) + 'test pasting image alongside other content': function() { + FileReader.setFileMockType( 'image/png' ); + FileReader.setReadResult( 'load' ); + + bender.tools.selection.setWithHtml( this.editor, '{}
' ); + this.assertPaste( 'image/png', 'whateva^@
', [ + { type: 'text/html', data: 'whateva' } + ] ); + }, + + assertPaste: function( type, expected, additionalData ) { this.editor.once( 'paste', function() { resume( function() { assert.isInnerHtmlMatching( expected, bender.tools.selection.getWithHtml( this.editor ), { @@ -149,7 +167,7 @@ } ); }, this, null, 9999 ); - mockPasteFile( this.editor, type ); + mockPasteFile( this.editor, type, additionalData ); wait(); }