Skip to content

Commit

Permalink
Merge branch 't/13441'
Browse files Browse the repository at this point in the history
  • Loading branch information
oleq committed Jul 23, 2015
2 parents 03c3329 + c5ec78b commit b88638a
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 27 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Fixed Issues:
* [#11376](http://dev.ckeditor.com/ticket/11376): [IE11] Fixed: Loss of text when pasting bullet lists from Microsoft Word.
* [#13387](http://dev.ckeditor.com/ticket/13387): [Edge] Fixed: "Permission denied" error thrown while loading the editor with developer tools open.
* [#13409](http://dev.ckeditor.com/ticket/13409): Fixed: List elements incorrectly merged when pressing *Backspace* or *Delete*.
* [#13441](http://dev.ckeditor.com/ticket/13441): [Edge] Fixed: [Clipboard](http://ckeditor.com/addon/clipboard) plugin breaks the state of [Undo](http://ckeditor.com/addon/undo) commands after paste.

## CKEditor 4.5.1

Expand Down
58 changes: 31 additions & 27 deletions plugins/clipboard/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -542,8 +542,9 @@
// it's introduced by a document command execution (e.g. toolbar buttons) or
// user paste behaviors (e.g. CTRL+V).
editable.on( clipboard.mainPasteEvent, function( evt ) {
if ( CKEDITOR.env.ie && preventBeforePasteEvent )
if ( clipboard.mainPasteEvent == 'beforepaste' && preventBeforePasteEvent ) {
return;
}

// If you've just asked yourself why preventPasteEventNow() is not here, but
// in listener for CTRL+V and exec method of 'paste' command
Expand Down Expand Up @@ -591,33 +592,36 @@
// special flag, other than preventPasteEvent. But we still would have to
// have preventPasteEvent for the second event fired by execIECommand.
// Code would be longer and not cleaner.
CKEDITOR.env.ie && editable.on( 'paste', function( evt ) {
if ( preventPasteEvent )
return;
// Cancel next 'paste' event fired by execIECommand( 'paste' )
// at the end of this callback.
preventPasteEventNow();
if ( clipboard.mainPasteEvent == 'beforepaste' ) {
editable.on( 'paste', function( evt ) {
if ( preventPasteEvent ) {
return;
}

// Prevent native paste.
evt.data.preventDefault();
// Cancel next 'paste' event fired by execIECommand( 'paste' )
// at the end of this callback.
preventPasteEventNow();

pasteDataFromClipboard( evt );
// Prevent native paste.
evt.data.preventDefault();

// Force IE to paste content into pastebin so pasteDataFromClipboard will work.
if ( !execIECommand( 'paste' ) )
editor.openDialog( 'paste' );
} );
pasteDataFromClipboard( evt );

// [IE] Dismiss the (wrong) 'beforepaste' event fired on context/toolbar menu open. (#7953)
if ( CKEDITOR.env.ie ) {
// Force IE to paste content into pastebin so pasteDataFromClipboard will work.
if ( !execIECommand( 'paste' ) ) {
editor.openDialog( 'paste' );
}
} );

// If mainPasteEvent is 'beforePaste' (IE before Edge),
// dismiss the (wrong) 'beforepaste' event fired on context/toolbar menu open. (#7953)
editable.on( 'contextmenu', preventBeforePasteEventNow, null, null, 0 );

editable.on( 'beforepaste', function( evt ) {
// Do not prevent event on CTRL+V and SHIFT+INS because it blocks paste (#11970).
if ( evt.data && !evt.data.$.ctrlKey && !evt.data.$.shiftKey )
preventBeforePasteEventNow();
}, null, null, 0 );

}

editable.on( 'beforecut', function() {
Expand Down Expand Up @@ -950,16 +954,14 @@
}

// Try to get content directly on IE from clipboard, without native event
// being fired before. In other words - synthetically get clipboard data
// if it's possible.
// being fired before. In other words - synthetically get clipboard data, if it's possible.
// mainPasteEvent will be fired, so if forced native paste:
// * worked, getClipboardDataByPastebin will grab it,
// * didn't work, dataValue and dataTransfer will be empty and editor#paste won't be fired.
// On browsers other then IE it is not possible to get data directly so function will
// return false.
// Clipboard data can be accessed directly only on IEs older than Edge.
// On other browsers we should fire beforePaste event and return false.
function getClipboardDataDirectly() {
// On non-IE it is not possible to get data directly.
if ( !CKEDITOR.env.ie ) {
if ( clipboard.mainPasteEvent == 'paste' ) {
// beforePaste should be fired when dialog open so it can be canceled.
editor.fire( 'beforePaste', { type: 'auto', method: 'paste' } );
return false;
Expand Down Expand Up @@ -1002,8 +1004,10 @@
// by 'beforepaste'.
preventPasteEventNow();

// Simulate 'beforepaste' event for all none-IEs.
!CKEDITOR.env.ie && editable.fire( 'beforepaste' );
// Simulate 'beforepaste' event for all browsers using 'paste' as main event.
if ( clipboard.mainPasteEvent == 'paste' ) {
editable.fire( 'beforepaste' );
}

return;

Expand Down Expand Up @@ -1501,15 +1505,15 @@
*
* **Note:** Safari does not like the {@link CKEDITOR.editor#beforePaste} event — it sometimes does not
* handle <kbd>Ctrl+C</kbd> properly. This is probably caused by some race condition between events.
* Chrome and Firefox work well with both events, so it is better to use {@link CKEDITOR.editor#paste}
* Chrome, Firefox and Edge work well with both events, so it is better to use {@link CKEDITOR.editor#paste}
* which will handle pasting from e.g. browsers' menu bars.
* IE7/8 does not like the {@link CKEDITOR.editor#paste} event for which it is throwing random errors.
*
* @since 4.5
* @readonly
* @property {String}
*/
mainPasteEvent: CKEDITOR.env.ie ? 'beforepaste' : 'paste',
mainPasteEvent: ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) ? 'beforepaste' : 'paste',

/**
* Returns the element that should be used as the target for the drop event.
Expand Down
19 changes: 19 additions & 0 deletions tests/tickets/13441/1.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<h3>First editor:</h3>
<div id="editor1" contenteditable="true" style="border:1px solid gray;">
<p>Foo bar.</p>
</div>
<br />
<h3>Second editor:</h3>
<div id="editor2" contenteditable="true" style="border:1px solid gray;">
<p>Foo bar.</p>
</div>
<br />
<h3>Third editor:</h3>
<div id="editor3" contenteditable="true" style="border:1px solid gray;">
<p>Foo bar.</p>
</div>
<script>
CKEDITOR.inline( 'editor1' );
CKEDITOR.inline( 'editor2' );
CKEDITOR.inline( 'editor3' );
</script>
20 changes: 20 additions & 0 deletions tests/tickets/13441/1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@bender-ui: collapsed
@bender-tags: undo, tc, 4.5.2, 13441
@bender-ckeditor-plugins: wysiwygarea, toolbar, undo, basicstyles, image2, font, stylescombo, basicstyles, format, maximize, blockquote, list, table, resize, elementspath, justify, clipboard, floatingspace, sourcearea, htmlwriter, link

###Only on IE Edge###

1. Select all contents of one editor.
2. <kbd>ctrl + c</kbd>.
3. Focus second editor.
4. <kbd>ctrl + v</kbd>.
5. Undo button should be enabled. Press <kbd>ctrl + z</kbd> or use undo button.

**Expected result**: Pasted content has been undone.

------------

1. Focus third editor.
2. Type a letter.

**Expected result**: Undo enabled.

0 comments on commit b88638a

Please sign in to comment.