diff --git a/CHANGES.md b/CHANGES.md index 024c5a0ae02..c89ee7971e9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ Fixed Issues: * [#13887](https://dev.ckeditor.com/ticket/13887): Fixed: Link target now supports wider ASCII character range. Thanks to [SamZiemer](https://github.com/SamZiemer)! * [#13790](https://dev.ckeditor.com/ticket/13790): Fixed: Allow for the iframe having been removed already. Thanks to [Stefan Rijnhart](https://github.com/StefanRijnhart)! * [#13803](https://dev.ckeditor.com/ticket/13803): Fixed: Allow the editor to be destroyed before being fully initialized. Thanks to [Cyril Fluck](https://github.com/cyril-sf)! +* [#13883](http://dev.ckeditor.com/ticket/13883): Fixed: Copying table using context menu strips off styles. * [#13872](http://dev.ckeditor.com/ticket/13872): Fixed: Cut is no longer possible in [read-only](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) mode. * [#13879](http://dev.ckeditor.com/ticket/13879): Fixed: Preventing [`editor.drop`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-drop) event. * [#12848](http://dev.ckeditor.com/ticket/12848): Fixed: Opening find dialog in [read-only](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) mode will no longer throw an exception. diff --git a/plugins/clipboard/dialogs/paste.js b/plugins/clipboard/dialogs/paste.js index 3c26b2b6219..77d61cdeee8 100644 --- a/plugins/clipboard/dialogs/paste.js +++ b/plugins/clipboard/dialogs/paste.js @@ -4,7 +4,9 @@ */ CKEDITOR.dialog.add( 'paste', function( editor ) { - var lang = editor.lang.clipboard; + var lang = editor.lang.clipboard, + clipboard = CKEDITOR.plugins.clipboard, + lastDataTransfer; function onPasteFrameLoad( win ) { var doc = new CKEDITOR.dom.document( win.document ), @@ -15,6 +17,22 @@ CKEDITOR.dialog.add( 'paste', function( editor ) { body.setAttribute( 'contenteditable', true ); + // Forward dataTransfer (#13883). + body.on( clipboard.mainPasteEvent, function( evt ) { + var dataTransfer = clipboard.initPasteDataTransfer( evt ); + + if ( !lastDataTransfer ) { + lastDataTransfer = dataTransfer; + } else + // For two paste with the same dataTransfer we can use that dataTransfer (two internal pastes are + // considered as an internal paste). + if ( dataTransfer != lastDataTransfer ) { + // If there were two paste with different DataTransfer objects create a new, empty, data transfer + // and use it (one internal and one external paste are considered as external paste). + lastDataTransfer = clipboard.initPasteDataTransfer(); + } + } ); + // IE before version 8 will leave cursor blinking inside the document after // editor blurred unless we clean up the selection. (#4716) if ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 ) { @@ -57,9 +75,9 @@ CKEDITOR.dialog.add( 'paste', function( editor ) { if ( evt.data ) editor.fire( 'paste', { type: 'auto', - dataValue: evt.data, + dataValue: evt.data.dataValue, method: 'paste', - dataTransfer: CKEDITOR.plugins.clipboard.initPasteDataTransfer() + dataTransfer: evt.data.dataTransfer || clipboard.initPasteDataTransfer() } ); }, null, null, 1000 ); @@ -150,6 +168,9 @@ CKEDITOR.dialog.add( 'paste', function( editor ) { ' aria-describedby="' + dialog.getContentElement( 'general', 'pasteMsg' ).domId + '"' + '>' ); + // Reset last data transfer. + lastDataTransfer = null; + iframe.on( 'load', function( e ) { e.removeListener(); @@ -210,7 +231,11 @@ CKEDITOR.dialog.add( 'paste', function( editor ) { // Opera needs some time to think about what has happened and what it should do now. setTimeout( function() { - editor.fire( 'pasteDialogCommit', html ); + editor.fire( 'pasteDialogCommit', { + dataValue: html, + // Avoid error if there was no paste so lastDataTransfer is null. + dataTransfer: lastDataTransfer || clipboard.initPasteDataTransfer() + } ); }, 0 ); } } diff --git a/plugins/clipboard/plugin.js b/plugins/clipboard/plugin.js index 65a8774e987..e32eb929b3d 100644 --- a/plugins/clipboard/plugin.js +++ b/plugins/clipboard/plugin.js @@ -461,7 +461,12 @@ // 'paste' evt by itself. evt.cancel(); dialogCommited = true; - callback( { type: dataType, dataValue: evt.data, method: 'paste' } ); + callback( { + type: dataType, + dataValue: evt.data.dataValue, + dataTransfer: evt.data.dataTransfer, + method: 'paste' + } ); } function onDialogOpen() { diff --git a/tests/plugins/clipboard/manual/13883.html b/tests/plugins/clipboard/manual/13883.html new file mode 100644 index 00000000000..4001b1450f1 --- /dev/null +++ b/tests/plugins/clipboard/manual/13883.html @@ -0,0 +1,29 @@ + + + diff --git a/tests/plugins/clipboard/manual/13883.md b/tests/plugins/clipboard/manual/13883.md new file mode 100644 index 00000000000..8d9e414e380 --- /dev/null +++ b/tests/plugins/clipboard/manual/13883.md @@ -0,0 +1,48 @@ +@bender-ui: collapsed +@bender-tags: 4.5.5, tc +@bender-ckeditor-plugins: clipboard, contextmenu, toolbar, wysiwygarea + +## Scenario 1: ### + + 1. Select cells using mouse + 2. Ctrl+C + 3. Right-click inside 'Paste here'. + 4. Select Paste + 5. Paste into dialog using Ctrl+V. + 6. click OK + +Expected result: Table should be pasted *WITH* the formating. + +## Scenario 2: ### + +1-4. Same + +5a. Paste into dialog using Ctrl+V. + +5b. Paste into dialog again using Ctrl+V, so there are two tables. + +6 click OK + +Expected result: Same. + +## Scenario 3: ### + +1-4. Same + +5a. Paste into dialog using Ctrl+V. + +5b. Paste some content not from the editor. + +6 click OK + +Expected result: Table should be pasted *WITHOUT* the formating. + +## Scenario 4: ### + +1-4. Same + +5 Leave textarea empty. + +6 click OK + +Expected result: There should be no error. \ No newline at end of file diff --git a/tests/plugins/clipboard/pastedialog.js b/tests/plugins/clipboard/pastedialog.js index 091f17d721d..8c3a32cd71d 100644 --- a/tests/plugins/clipboard/pastedialog.js +++ b/tests/plugins/clipboard/pastedialog.js @@ -150,17 +150,18 @@ }, 'test paste event structure': function() { - var editor = this.editor; + var editor = this.editor, + dataTransfer = CKEDITOR.plugins.clipboard.initPasteDataTransfer(); editor.once( 'paste', function( evt ) { evt.cancel(); assert.areSame( 'foo', evt.data.dataValue, 'dataValue' ); assert.areSame( 'paste', evt.data.method, 'method' ); - assert.isInstanceOf( CKEDITOR.plugins.clipboard.dataTransfer, evt.data.dataTransfer, 'dataTransfer' ); + assert.areSame( dataTransfer, evt.data.dataTransfer, 'dataTransfer' ); } ); - editor.fire( 'pasteDialogCommit', 'foo' ); + editor.fire( 'pasteDialogCommit', { dataValue: 'foo', dataTransfer: dataTransfer } ); } } ); } )(); \ No newline at end of file