Skip to content

Commit

Permalink
Merge pull request #3639 from ckeditor/t/3585
Browse files Browse the repository at this point in the history
Fix incorrect pasting images on Firefox
  • Loading branch information
f1ames authored Dec 3, 2019
2 parents 2f7937f + d734887 commit fa31eed
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 4 deletions.
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
30 changes: 29 additions & 1 deletion plugins/clipboard/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) {
Expand Down Expand Up @@ -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 ) {
Expand Down Expand Up @@ -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).
Expand Down
40 changes: 40 additions & 0 deletions tests/plugins/clipboard/datatransfer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1212,5 +1212,45 @@ bender.test( {
var dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer( nativeData );

assert.areSame( '<li>foo</li>', dataTransfer.getData( 'text/html' ) );
},

// (#3634)
'test getTypes (custom types)': function() {
if ( !CKEDITOR.plugins.clipboard.isCustomDataTypesSupported || CKEDITOR.env.edge ) {
assert.ignore();
}

var expectedTypes = [ 'whatever/cke', 'custom/type' ],
nativeData,
dataTransfer;

nativeData = bender.tools.mockNativeDataTransfer();
nativeData.setData( 'whatever/cke', 'Test' );
nativeData.setData( 'custom/type', 'lorem ipsum' );

dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer( nativeData );

arrayAssert.itemsAreSame( expectedTypes, dataTransfer.getTypes() );
},

// (#3634)
'test getTypes (non-custom types)': function() {
var expectedTypes = [ 'Text' ],
nativeData,
dataTransfer;

nativeData = bender.tools.mockNativeDataTransfer();
nativeData.setData( 'Text', 'Test' );

dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer( nativeData );

arrayAssert.itemsAreSame( expectedTypes, dataTransfer.getTypes() );
},

// (#3634)
'test getTypes when there is no native data transfer': function() {
var dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer();

arrayAssert.itemsAreSame( [], dataTransfer.getTypes() );
}
} );
Binary file not shown.
Binary file not shown.
7 changes: 7 additions & 0 deletions tests/plugins/clipboard/manual/pasteimagehtml.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div id="editor">
<p>Paste inside me</p>
</div>

<script>
CKEDITOR.replace( 'editor' );
</script>
22 changes: 22 additions & 0 deletions tests/plugins/clipboard/manual/pasteimagehtml.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@bender-ui: collapsed
@bender-tags: 3585, 3625, 4.13.1, bug, clipboard
@bender-ckeditor-plugins: wysiwygarea, toolbar, undo, basicstyles, image, clipboard, sourcearea

## Scenario
1. Copy content from document.
2. Paste into the editor.

### Expected

Content is pasted as text/HTML.

### Unexpected

Content is pasted as image.

Documents to check:

* [PowerPoint one](_assets/pasteimagehtml.pptx),
* [Excel one](_assets/pasteimagehtml.xlsx).

Note: formatting is not important in this test. Only the type of pasted content is important.
24 changes: 21 additions & 3 deletions tests/plugins/clipboard/pasteimage.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,21 @@
} )();

// Mock paste file from clipboard.
function mockPasteFile( editor, type ) {
function mockPasteFile( editor, type, additionalData ) {
var nativeData = bender.tools.mockNativeDataTransfer(),
dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer( nativeData );

nativeData.files.push( {
name: 'mock.file',
type: type
} );
nativeData.types.push( 'Files' );

if ( additionalData ) {
CKEDITOR.tools.array.forEach( additionalData, function( data ) {
nativeData.setData( data.type, data.data );
} );
}

dataTransfer.cacheData();

Expand Down Expand Up @@ -137,7 +144,18 @@
'<p>Paste image here: ^@</p>' );
},

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, '<p>{}</p>' );
this.assertPaste( 'image/png', '<p><strong>whateva^</strong>@</p><p></p>', [
{ type: 'text/html', data: '<strong>whateva</strong>' }
] );
},

assertPaste: function( type, expected, additionalData ) {
this.editor.once( 'paste', function() {
resume( function() {
assert.isInnerHtmlMatching( expected, bender.tools.selection.getWithHtml( this.editor ), {
Expand All @@ -149,7 +167,7 @@
} );
}, this, null, 9999 );

mockPasteFile( this.editor, type );
mockPasteFile( this.editor, type, additionalData );

wait();
}
Expand Down

0 comments on commit fa31eed

Please sign in to comment.