Skip to content

Commit cc0310f

Browse files
committed
Merge branch 't/10865b' into major
2 parents ac1285f + 7649d0a commit cc0310f

File tree

2 files changed

+54
-8
lines changed

2 files changed

+54
-8
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Fixed Issues:
3636
* [#10854](http://dev.ckeditor.com/ticket/10854): Fixed: Firefox prepends `<br>` to `<body>`, so it is stripped by the HTML data processor.
3737
* [#10823](http://dev.ckeditor.com/ticket/10823): Fixed: Link plugin does not work with non-editable content.
3838
* [#10828](http://dev.ckeditor.com/ticket/10828): Magicline integration with widgets system.
39+
* [#10865](http://dev.ckeditor.com/ticket/10865): Improved hiding copybin, so copying widgets works smoothly.
3940

4041
## CKEditor 4.3 Beta
4142

plugins/widget/plugin.js

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,6 +1730,21 @@
17301730
} );
17311731
}
17321732

1733+
// And now we've got two problems - original problem and RegExp.
1734+
// Some softeners:
1735+
// * FF tends to copy all blocks up to the copybin container.
1736+
// * IE tends to copy only the copybin, without its container.
1737+
// * We use spans on IE and blockless editors, but divs in other cases.
1738+
var pasteReplaceRegex = new RegExp(
1739+
'^' +
1740+
'(?:<(?:div|span)(?: id="cke_copybin")?>)?' +
1741+
'(?:<(?:div|span)(?: style="[^"]+")?>)?' +
1742+
'<span [^>]*data-cke-copybin-start="1"[^>]*>.?</span>([\\s\\S]+)<span [^>]*data-cke-copybin-end="1"[^>]*>.?</span>' +
1743+
'(?:</(?:div|span)>)?' +
1744+
'(?:</(?:div|span)>)?' +
1745+
'$'
1746+
);
1747+
17331748
// Set up data processing like:
17341749
// * toHtml/toDataFormat,
17351750
// * pasting handling,
@@ -1747,7 +1762,7 @@
17471762
// Handle pasted single widget.
17481763
editor.on( 'paste', function( evt ) {
17491764
evt.data.dataValue = evt.data.dataValue.replace(
1750-
/^(?:<div id="cke_copybin">)?<span [^>]*data-cke-copybin-start="1"[^>]*>.?<\/span>([\s\S]+)<span [^>]*data-cke-copybin-end="1"[^>]*>.?<\/span>(?:<\/div>)?$/,
1765+
pasteReplaceRegex,
17511766
'$1'
17521767
);
17531768
} );
@@ -2231,12 +2246,32 @@
22312246

22322247
function copySingleWidget( widget, isCut ) {
22332248
var editor = widget.editor,
2234-
copybin = new CKEDITOR.dom.element( 'div', editor.document );
2249+
doc = editor.document;
2250+
2251+
// We're still handling previous copy/cut.
2252+
if ( doc.getById( 'cke_copybin' ) )
2253+
return;
22352254

2236-
copybin.setAttributes( {
2237-
id: 'cke_copybin'
2255+
// [IE] Use span for copybin and its container to avoid bug with expanding editable height by
2256+
// absolutely positioned element.
2257+
var copybinName = ( editor.blockless || CKEDITOR.env.ie ) ? 'span' : 'div',
2258+
copybin = doc.createElement( copybinName ),
2259+
copybinContainer = doc.createElement( copybinName ),
2260+
// IE8 always jumps to the end of document.
2261+
needsScrollHack = CKEDITOR.env.ie && CKEDITOR.env.version < 9;
2262+
2263+
copybinContainer.setAttribute( 'id', 'cke_copybin' );
2264+
2265+
// Position copybin element outside current viewport.
2266+
copybin.setStyles( {
2267+
position: 'absolute',
2268+
width: '1px',
2269+
height: '1px',
2270+
overflow: 'hidden'
22382271
} );
22392272

2273+
copybin.setStyle( editor.config.contentsLangDirection == 'ltr' ? 'left' : 'right', '-5000px' );
2274+
22402275
copybin.setHtml( '<span data-cke-copybin-start="1">\u200b</span>' + widget.wrapper.getOuterHtml() + '<span data-cke-copybin-end="1">\u200b</span>' );
22412276

22422277
// Save snapshot with the current state.
@@ -2245,24 +2280,34 @@
22452280
// Ignore copybin.
22462281
editor.fire( 'lockSnapshot' );
22472282

2248-
editor.editable().append( copybin );
2283+
copybinContainer.append( copybin );
2284+
editor.editable().append( copybinContainer );
22492285

22502286
var listener1 = editor.on( 'selectionChange', cancel, null, null, 0 ),
22512287
listener2 = widget.repository.on( 'checkSelection', cancel, null, null, 0 );
22522288

2289+
if ( needsScrollHack ) {
2290+
var docElement = doc.getDocumentElement().$,
2291+
scrollTop = docElement.scrollTop;
2292+
}
2293+
22532294
// Once the clone of the widget is inside of copybin, select
22542295
// the entire contents. This selection will be copied by the
22552296
// native browser's clipboard system.
22562297
var range = editor.createRange();
22572298
range.selectNodeContents( copybin );
22582299
range.select();
22592300

2260-
setTimeout( function() {
2261-
copybin.remove();
2301+
if ( needsScrollHack )
2302+
docElement.scrollTop = scrollTop;
22622303

2304+
setTimeout( function() {
2305+
// [IE] Focus widget before removing copybin to avoid scroll jump.
22632306
if ( !isCut )
22642307
widget.focus();
22652308

2309+
copybinContainer.remove();
2310+
22662311
listener1.removeListener();
22672312
listener2.removeListener();
22682313

@@ -2272,7 +2317,7 @@
22722317
widget.repository.del( widget );
22732318
editor.fire( 'saveSnapshot' );
22742319
}
2275-
}, 10 ); // Use 10ms, so Chrome (@Mac) will be able to grab the content.
2320+
}, 100 ); // Use 100ms, so Chrome (@Mac) will be able to grab the content.
22762321
}
22772322

22782323
// [IE] Force keeping focus because IE sometimes forgets to fire focus on main editable

0 commit comments

Comments
 (0)