Skip to content
Permalink
Browse files

Merge branch 't/13011' into major

  • Loading branch information...
Reinmar committed Jun 15, 2015
2 parents a3d9e76 + 1a8de0c commit 4870adb3779955598e2b4859eb95e24037dc121c
@@ -27,6 +27,7 @@ Fixed Issues:
* [#13176](http://dev.ckeditor.com/ticket/13176): [IE8] Fixed: Errors while drag&drop of embed widgets.
* [#13015](http://dev.ckeditor.com/ticket/13015): Fixed: Dropping image file on [Enhanced Image](http://ckeditor.com/addon/image2) causes page reload.
* [#13080](http://dev.ckeditor.com/ticket/13080): Fixed: Ugly notification when response has HTML content.
* [#13011](http://dev.ckeditor.com/ticket/13011): [IE8] Fixed: Anchors are duplicated when drag&drop in specific locations.
* [#13105](http://dev.ckeditor.com/ticket/13105): Fixed: Various issues related to [`CKEDITOR.tools.htmlEncode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-htmlEncode) and [`CKEDITOR.tools.htmlDecode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-htmlDecode).
* [#13128](http://dev.ckeditor.com/ticket/13128): Fixed: Various issues regarding cloning IDs of elements:
* Fixed the default behavior of [`range.cloneContents()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-cloneContents), [`range.extractContents()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-extractContents) methods which now clone IDs similarly to their native counterparts.
@@ -1,4 +1,4 @@
/**
/**
* @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or http://ckeditor.com/license
*/
@@ -1294,7 +1294,13 @@
clipboard.initDragDataTransfer( evt, editor );

// Save drag range globally for cross editor D&D.
clipboard.dragRange = editor.getSelection().getRanges()[ 0 ];
var dragRange = clipboard.dragRange = editor.getSelection().getRanges()[ 0 ];

// Store number of children, so we can later tell if any text node was split on drop. (#13011)
if ( CKEDITOR.env.ie && CKEDITOR.env.version < 10 ) {
clipboard.dragStartContainerChildCount = getContainerChildCount( dragRange.startContainer );
clipboard.dragEndContainerChildCount = getContainerChildCount( dragRange.endContainer );
}
}, null, null, 2 );

// -------------- DRAGEND --------------
@@ -1442,6 +1448,14 @@
evt.data.preventDefault();
}
}

function getContainerChildCount( container ) {
if ( container.type != CKEDITOR.NODE_ELEMENT ) {
container = container.getParent();
}

return container.getChildCount();
}
} );
}

@@ -1529,23 +1543,60 @@
* @private
* @param {CKEDITOR.dom.range} dragRange The drag range.
* @param {CKEDITOR.dom.range} dropRange The drop range.
* @param {Number} preDragStartContainerChildCount Number of children of drag range start container before drop.
* @param {Number} preDragEndContainerChildCount Number of children of drag range end container before drop.
*/
fixIESplitNodesAfterDrop: function( dragRange, dropRange ) {
if ( dropRange.startContainer.type == CKEDITOR.NODE_ELEMENT &&
dropRange.startOffset > 0 &&
dropRange.startContainer.getChildCount() > dropRange.startOffset - 1 &&
dropRange.startContainer.getChild( dropRange.startOffset - 1 ).equals( dragRange.startContainer ) ) {
fixSplitNodesAfterDrop: function( dragRange, dropRange, preDragStartContainerChildCount, preDragEndContainerChildCount ) {
var dropContainer = dropRange.startContainer;

if (
typeof preDragEndContainerChildCount != 'number' ||
typeof preDragStartContainerChildCount != 'number'
) {
return;
}

// We are only concerned about ranges anchored in elements.
if ( dropContainer.type != CKEDITOR.NODE_ELEMENT ) {
return;
}

if ( handleContainer( dragRange.startContainer, dropContainer, preDragStartContainerChildCount ) ) {
return;
}

if ( handleContainer( dragRange.endContainer, dropContainer, preDragEndContainerChildCount ) ) {
return;
}

function handleContainer( dragContainer, dropContainer, preChildCount ) {
var dragElement = dragContainer;
if ( dragElement.type == CKEDITOR.NODE_TEXT ) {
dragElement = dragContainer.getParent();
}

if ( dragElement.equals( dropContainer ) && preChildCount != dropContainer.getChildCount() ) {
applyFix( dropRange );
return true;
}
}

function applyFix( dropRange ) {
var nodeBefore = dropRange.startContainer.getChild( dropRange.startOffset - 1 ),
nodeAfter = dropRange.startContainer.getChild( dropRange.startOffset ),
offset = nodeBefore.getLength();
nodeAfter = dropRange.startContainer.getChild( dropRange.startOffset );

if (
nodeBefore && nodeBefore.type == CKEDITOR.NODE_TEXT &&
nodeAfter && nodeAfter.type == CKEDITOR.NODE_TEXT
) {
var offset = nodeBefore.getLength();

if ( nodeAfter ) {
nodeBefore.setText( nodeBefore.getText() + nodeAfter.getText() );
nodeAfter.remove();
}

dropRange.setStart( nodeBefore, offset );
dropRange.collapse( true );
dropRange.setStart( nodeBefore, offset );
dropRange.collapse( true );
}
}
},

@@ -1616,7 +1667,8 @@
* @param {CKEDITOR.editor} editor
*/
internalDrop: function( dragRange, dropRange, dataTransfer, editor ) {
var editable = editor.editable(),
var clipboard = CKEDITOR.plugins.clipboard,
editable = editor.editable(),
dragBookmark, dropBookmark, isDropRangeAffected;

// Save and lock snapshot so there will be only
@@ -1625,7 +1677,12 @@
editor.fire( 'lockSnapshot', { dontUpdate: 1 } );

if ( CKEDITOR.env.ie && CKEDITOR.env.version < 10 ) {
this.fixIESplitNodesAfterDrop( dragRange, dropRange );
this.fixSplitNodesAfterDrop(
dragRange,
dropRange,
clipboard.dragStartContainerChildCount,
clipboard.dragEndContainerChildCount
);
}

// Because we manipulate multiple ranges we need to do it carefully,
@@ -2389,6 +2389,12 @@
dragRange.setEndAfter( sourceWidget.wrapper );
evt.data.dragRange = dragRange;

// [IE8-9] Reset state of the clipboard#fixSplitNodesAfterDrop fix because by setting evt.data.dragRange
// (see above) after drop happened we do not need it. That fix is needed only if dragRange was created
// before drop (before text node was split).
delete CKEDITOR.plugins.clipboard.dragStartContainerChildCount;
delete CKEDITOR.plugins.clipboard.dragEndContainerChildCount;

evt.data.dataTransfer.setData( 'text/html', editor.editable().getHtmlFromRange( dragRange ).getHtml() );
editor.widgets.destroy( sourceWidget, true );
} );
@@ -618,7 +618,7 @@ var testsForMultipleEditor = {
assert.isTrue( listener.calledOnce );
},

'test fixIESplittedNodes': function() {
'test fix split nodes': function() {
var editor = this.editors.framed,
bot = this.editorBots[ editor.name ],
dragRange = editor.createRange(),
@@ -643,7 +643,7 @@ var testsForMultipleEditor = {
dropRange.collapse( true );

// Fix nodes.
CKEDITOR.plugins.clipboard.fixIESplitNodesAfterDrop( dragRange, dropRange );
CKEDITOR.plugins.clipboard.fixSplitNodesAfterDrop( dragRange, dropRange, 1, 1 );

// Asserts.
assert.areSame( 1, p.getChildCount() );
@@ -653,6 +653,85 @@ var testsForMultipleEditor = {
assert.isInnerHtmlMatching( '<p class="p">lorem^ ipsum sit amet.@</p>', getWithHtml( editor ), htmlMatchOpts );
},

'test fix split nodes 2 (#13011)': function() {
// <p id="p"> " f o o " " b a r " <img /> </p>
// ^ [ ]
// drop drag

var editor = this.editors.framed,
bot = this.editorBots[ editor.name ],
dragRange = editor.createRange(),
dropRange = editor.createRange(),
p, img;

// Create DOM
bot.setHtmlWithSelection( '<p id="p"></p>' );
p = editor.document.getById( 'p' );

p.appendText( 'foo' );
p.appendText( 'bar' );

img = new CKEDITOR.dom.element( 'img' );
p.append( img );

dropRange.setStart( p, 1 );
dropRange.collapse( true );

dragRange.setStart( p, 2 );
dragRange.setEnd( p, 3 );

assert.areSame( 3, p.getChildCount() );

CKEDITOR.plugins.clipboard.fixSplitNodesAfterDrop( dragRange, dropRange, 2, 2 );

assert.areSame( 2, p.getChildCount() );
assert.areSame( 'foobar', p.getChild( 0 ).getText() );
},

'test fix split nodes 3': function() {
// In this test nothing should change because drop range is not between two text nodes.
// <p> " f o o " <img /> " b a r " </p>
// ^ { }
// drop drag

var editor = this.editors.framed,
bot = this.editorBots[ editor.name ],
dragRange = editor.createRange(),
dropRange = editor.createRange(),
p, text2, img;

// Create DOM
bot.setHtmlWithSelection( '<p class="p">foo</p>' );
p = editor.editable().findOne( '.p' );

// Set drag range.
dragRange.setStart( p.getChild( 0 ), 11 );
dragRange.collapse( true );

img = new CKEDITOR.dom.element( 'img' );
img.insertAfter( p.getChild( 0 ) );

text2 = new CKEDITOR.dom.text( 'bar' );
text2.insertAfter( img );

// Set drop range.
dropRange.setStart( p, 1 );
dropRange.collapse( true );

dragRange.setStart( text2, 1 );
dragRange.setEnd( text2, 2 );

// Fix nodes.
CKEDITOR.plugins.clipboard.fixSplitNodesAfterDrop( dragRange, dropRange, 1, 1 );

// Nothing changes.
assert.areSame( 3, p.getChildCount() );

assert.isTrue( dropRange.collapsed );
assert.isTrue( dropRange.startContainer.equals( p ) );
assert.areSame( 1, dropRange.startOffset );
},

'test isDropRangeAffectedByDragRange 1': function() {
var editor = this.editors.framed,
bot = this.editorBots[ editor.name ],
@@ -317,7 +317,7 @@
[ '-', '-', '-', '-' ],
'-',
[ '?', null, null, null ],
// See fixIESplitNodesAfterDrop. It doesn't cover case like this one
// See fixSplitNodesAfterDrop. It doesn't cover case like this one
// because it isn't fully realistic, so it brokes the drag range and this tc fails.
( CKEDITOR.env.ie && CKEDITOR.env.version < 10 ? '?' : '+' ),
[ '-', '-', '-' ],
@@ -0,0 +1,13 @@
<body>
<div id="editor">
<p>Broadcasting and <a id="quotes" name="quotes"></a></p>

<p>foo bar <strong>baz</strong> ban</p>

<p>Foo bar baz <img alt="CKEditor logo" src="%BASE_PATH%_assets/logo.png" /> ban.</p>
</div>

<script>
CKEDITOR.replace( 'editor' );
</script>
</body>
@@ -0,0 +1,36 @@
@bender-tags: tc, 4.5.0, 13011, clipboard
@bender-ui: collapsed
@bender-ckeditor-plugins: floatingspace, toolbar, wysiwygarea, link, clipboard, basicstyles, image2

**PLEASE NOTE:** Second test doesn't have an automatic test. Be sure it pass.

Step:

1. Drag anchor before itself.

Unexpected:

Anchors are duplicated.

----

Steps:

1. Select text "r **baz** b" in the editor.
2. D&amp;D selected text before itself.

Expected:

D&amp;D works properly.

----

Step:

**Please note:** Don't click on the widget - just mouse down drag handler.

1. D&amp;D image some in the same line before itself using drag handler.

Expected:

Image is moved properly.

0 comments on commit 4870adb

Please sign in to comment.
You can’t perform that action at this time.