Skip to content

Commit

Permalink
Merge branch 't/13528b'
Browse files Browse the repository at this point in the history
  • Loading branch information
Reinmar committed Jul 29, 2015
2 parents cb014cc + 2e19d84 commit 933b853
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -6,6 +6,7 @@ CKEditor 4 Changelog
Fixed Issues:

* [PR#201](https://github.com/ckeditor/ckeditor-dev/pull/201): Fixed: Buttons in the toolbar configurator cause form submission. Thanks to [colemanw](https://github.com/colemanw)!
* [#13528](http://dev.ckeditor.com/ticket/13528): [Firefox@Windows] Fixed: Content copied from Microsoft Word and other external applications is pasted as plain text. Removed the [`CKEDITOR.plugins.clipboard.isHtmlInExternalDataTransfer`] property as the check must be dynamic.
* [#13434](http://dev.ckeditor.com/ticket/13434): Fixed: Dialog state indicator broken in Right–To–Left environments.
* [#13451](http://dev.ckeditor.com/ticket/13451): [IE8-9] Fixed: One drag&drop operation may affect following ones.
* [#13129](http://dev.ckeditor.com/ticket/13129) Fixed: Block widget blurred after a drop followed by an undo.
Expand Down
50 changes: 36 additions & 14 deletions plugins/clipboard/plugin.js
Expand Up @@ -1028,8 +1028,7 @@
type: 'auto',
method: 'paste',
dataTransfer: clipboard.initPasteDataTransfer( evt )
},
external = eventData.dataTransfer.getTransferType( editor ) === CKEDITOR.DATA_TRANSFER_EXTERNAL;
};

eventData.dataTransfer.cacheData();

Expand All @@ -1041,7 +1040,7 @@
var beforePasteNotCanceled = editor.fire( 'beforePaste', eventData ) !== false;

// Do not use paste bin if the browser let us get HTML or files from dataTranfer.
if ( beforePasteNotCanceled && ( clipboard.isHtmlInExternalDataTransfer || !external ) && !eventData.dataTransfer.isEmpty() ) {
if ( beforePasteNotCanceled && clipboard.canClipboardApiBeTrusted( eventData.dataTransfer, editor ) ) {
evt.data.preventDefault();
setTimeout( function() {
firePasteEvents( editor, eventData );
Expand Down Expand Up @@ -1489,17 +1488,6 @@
*/
isFileApiSupported: !CKEDITOR.env.ie || CKEDITOR.env.version > 9,


/**
* True if external data transfer contains HTML data.
*
* @since 4.5
* @readonly
* @property {Boolean}
*/
isHtmlInExternalDataTransfer: !CKEDITOR.env.ie && !CKEDITOR.env.safari,


/**
* Main native paste event editable should listen to.
*
Expand All @@ -1515,6 +1503,40 @@
*/
mainPasteEvent: ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) ? 'beforepaste' : 'paste',

/**
* Returns `true` if we can expect that the browser provides HTML data through the Clipboard API.
* If not, then it returns `false` and as a result CKEditor will use the paste bin. Read more in
* the [Clipboard Integration](http://docs.ckeditor.com/#!/guide/dev_clipboard-section-clipboard-api) guide.
*
* @since 4.5.2
* @returns {Boolean}
*/
canClipboardApiBeTrusted: function( dataTransfer, editor ) {
// If it's an internal or cross-editor data transfer, then it means that custom cut/copy/paste support works
// and that the data were put manually on the data transfer so we can be sure that it's available.
if ( dataTransfer.getTransferType( editor ) != CKEDITOR.DATA_TRANSFER_EXTERNAL ) {
return true;
}

// In Chrome we can trust Clipboard API, with the exception of Chrome on Android (in both - mobile and desktop modes), where
// clipboard API is not available so we need to check it (#13187).
if ( CKEDITOR.env.chrome && !dataTransfer.isEmpty() ) {
return true;
}

// Because of a Firefox bug HTML data are not available in some cases (e.g. paste from Word), in such cases we
// need to use the pastebin (#13528, https://bugzilla.mozilla.org/show_bug.cgi?id=1183686).
if ( CKEDITOR.env.gecko && ( dataTransfer.getData( 'text/html' ) || dataTransfer.getFilesCount() ) ) {
return true;
}

// In Safari and IE HTML data is not available though the Clipboard API.
// In Edge things are a bit messy at the moment -
// https://connect.microsoft.com/IE/feedback/details/1572456/edge-clipboard-api-text-html-content-messed-up-in-event-clipboarddata
// It is safer to use the paste bin in unknown cases.
return false;
},

/**
* Returns the element that should be used as the target for the drop event.
*
Expand Down
1 change: 1 addition & 0 deletions tests/plugins/clipboard/manual/draganddrop.md
@@ -1,4 +1,5 @@
@bender-ui: collapsed
@bender-tags: 4.5.0, 4.5.2, tc
@bender-ckeditor-plugins: wysiwygarea, toolbar, undo, basicstyles, image2, font, stylescombo, basicstyles, format, maximize, blockquote, list, table, resize, elementspath, justify, clipboard, floatingspace, sourcearea, htmlwriter, link

* test internal D&D in the editor,
Expand Down
8 changes: 5 additions & 3 deletions tests/plugins/clipboard/manual/paste.md
@@ -1,6 +1,6 @@
@bender-ui: collapsed
@bender-tags: 4.5.0, tc
@bender-ckeditor-plugins: wysiwygarea, toolbar, undo, basicstyles, image2, font, stylescombo, basicstyles, format, maximize, blockquote, list, table, resize, elementspath, justify, clipboard, floatingspace, sourcearea, htmlwriter, link, uploadimage, image2
@bender-tags: 4.5.0, 4.5.2, tc
@bender-ckeditor-plugins: wysiwygarea, toolbar, undo, basicstyles, image2, font, stylescombo, basicstyles, format, maximize, blockquote, list, table, resize, elementspath, justify, clipboard, floatingspace, sourcearea, htmlwriter, link, uploadimage, image2, pastefromword
@bender-include: ../../uploadwidget/manual/_helpers/xhr.js

## Scenarios:
Expand All @@ -11,7 +11,8 @@
* copy and paste file (works only on Firefox),
* copy and paste part of the image from the image editor,
* copy and paste internal HTML,
* copy and paste text from another editor.
* copy and paste text from another editor,
* copy and paste HTML from other browser (the same OS).

## Notes:

Expand All @@ -28,6 +29,7 @@

### Firefox

* There's no `text/html` data for external paste. Hence, pastebin is used. Hence, data type always equals `html` (see: [`config.clipboard_defaultContentType`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-clipboard_defaultContentType)).
* Paste is always recognized as external.

### IE
Expand Down
108 changes: 106 additions & 2 deletions tests/plugins/clipboard/paste.js
Expand Up @@ -1243,7 +1243,7 @@
},

'paste with HTML in clipboardData': function() {
if ( !CKEDITOR.plugins.clipboard.isHtmlInExternalDataTransfer ) {
if ( !CKEDITOR.plugins.clipboard.isCustomCopyCutSupported ) {
assert.ignore();
}

Expand All @@ -1270,7 +1270,7 @@
},

'paste with HTML in clipboardData - cancel on before paste': function() {
if ( !CKEDITOR.plugins.clipboard.isHtmlInExternalDataTransfer ) {
if ( !CKEDITOR.plugins.clipboard.isCustomCopyCutSupported ) {
assert.ignore();
}

Expand Down Expand Up @@ -1445,6 +1445,110 @@
}, 0 );
},

'test canClipboardApiBeTrusted internal': function() {
var canClipboardApiBeTrusted = CKEDITOR.plugins.clipboard.canClipboardApiBeTrusted;

var editor = this.editor,
nativeData = bender.tools.mockNativeDataTransfer(),
evt = { data: { $: { clipboardData: nativeData } } },
dataTransfer = CKEDITOR.plugins.clipboard.initPasteDataTransfer( evt, editor );

assert.isTrue( canClipboardApiBeTrusted( dataTransfer, editor ), 'Clipboard API should be used for internal operations.' );
},

'test canClipboardApiBeTrusted in Chrome': function() {
if ( !CKEDITOR.env.chrome ) {
assert.ignore();
}

var canClipboardApiBeTrusted = CKEDITOR.plugins.clipboard.canClipboardApiBeTrusted;

var nativeData = bender.tools.mockNativeDataTransfer();

nativeData.setData( 'text/html', '<b>foo</b>' );

var evt = { data: { $: { clipboardData: nativeData } } },
dataTransfer = CKEDITOR.plugins.clipboard.initPasteDataTransfer( evt );

assert.isTrue( canClipboardApiBeTrusted( dataTransfer ), 'Clipboard API should be used in Chrome.' );
},

'test canClipboardApiBeTrusted in Android Chrome (no dataTransfer support)': function() {
if ( !CKEDITOR.env.chrome ) {
assert.ignore();
}

var canClipboardApiBeTrusted = CKEDITOR.plugins.clipboard.canClipboardApiBeTrusted;

var dataTransfer = CKEDITOR.plugins.clipboard.initPasteDataTransfer(); // no native data transfer

assert.isFalse( canClipboardApiBeTrusted( dataTransfer ),
'Clipboard API should NOT be used for in Android Chrome.' );
},

'test canClipboardApiBeTrusted in Firefox with HTML': function() {
if ( !CKEDITOR.env.gecko ) {
assert.ignore();
}

var canClipboardApiBeTrusted = CKEDITOR.plugins.clipboard.canClipboardApiBeTrusted;

var nativeData = bender.tools.mockNativeDataTransfer();

nativeData.setData( 'text/html', '<b>foo</b>' );

var evt = { data: { $: { clipboardData: nativeData } } },
dataTransfer = CKEDITOR.plugins.clipboard.initPasteDataTransfer( evt );

assert.isTrue( canClipboardApiBeTrusted( dataTransfer ), 'Clipboard API should be used in Firefox with HTML.' );
},

'test canClipboardApiBeTrusted in Firefox with files': function() {
if ( !CKEDITOR.env.gecko ) {
assert.ignore();
}

var canClipboardApiBeTrusted = CKEDITOR.plugins.clipboard.canClipboardApiBeTrusted;

var nativeData = bender.tools.mockNativeDataTransfer();

nativeData.files.push( 'foo' );

var evt = { data: { $: { clipboardData: nativeData } } },
dataTransfer = CKEDITOR.plugins.clipboard.initPasteDataTransfer( evt );

assert.isTrue( canClipboardApiBeTrusted( dataTransfer ), 'Clipboard API should be used in Firefox with files.' );
},

'test canClipboardApiBeTrusted in Firefox without files and HTML': function() {
if ( !CKEDITOR.env.gecko ) {
assert.ignore();
}

var canClipboardApiBeTrusted = CKEDITOR.plugins.clipboard.canClipboardApiBeTrusted;

var nativeData = bender.tools.mockNativeDataTransfer(),
evt = { data: { $: { clipboardData: nativeData } } },
dataTransfer = CKEDITOR.plugins.clipboard.initPasteDataTransfer( evt );

assert.isFalse( canClipboardApiBeTrusted( dataTransfer ),
'Clipboard API should not be used in Firefox without html and files.' );
},

'test canClipboardApiBeTrusted on other browser': function() {
if ( CKEDITOR.env.chrome || CKEDITOR.env.gecko ) {
assert.ignore();
}

var canClipboardApiBeTrusted = CKEDITOR.plugins.clipboard.canClipboardApiBeTrusted;

var nativeData = bender.tools.mockNativeDataTransfer(),
evt = { data: { $: { clipboardData: nativeData } } },
dataTransfer = CKEDITOR.plugins.clipboard.initPasteDataTransfer( evt );

assert.isFalse( canClipboardApiBeTrusted( dataTransfer ), 'Clipboard API should not be used in other browsers.' );
},

'#131 - trailing spaces': function() {
assertPasteEvent(
this.editor,
Expand Down

0 comments on commit 933b853

Please sign in to comment.