Date: Mon, 30 Jun 2014 17:28:24 +0200
Subject: [PATCH 46/67] Compare end (instead of start) of the first range with
start of the second range in rangeBefore.
---
plugins/clipboard/plugin.js | 8 ++++----
tests/plugins/clipboard/drop.js | 27 +++++++++++++++++++++++++++
2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/plugins/clipboard/plugin.js b/plugins/clipboard/plugin.js
index 517ef40ac7a..54182d674b8 100644
--- a/plugins/clipboard/plugin.js
+++ b/plugins/clipboard/plugin.js
@@ -1426,8 +1426,8 @@
// "Lorem ipsum dolor sit[1] amet consectetur[2] adipiscing elit."
// "Lorem ipsum dolor sit" [1] "amet consectetur" [2] "adipiscing elit."
//
- if ( firstRange.startContainer.equals( secondRange.startContainer ) &&
- firstRange.startOffset < secondRange.startOffset )
+ if ( firstRange.endContainer.equals( secondRange.startContainer ) &&
+ firstRange.endOffset < secondRange.startOffset )
return true;
// First range is inside a text node and the second is not, but if we change the
@@ -1436,8 +1436,8 @@
//
// "Lorem ipsum dolor sit [1] amet" "consectetur" [2] "adipiscing elit."
//
- if ( firstRange.startContainer.getParent().equals( secondRange.startContainer ) &&
- firstRange.startContainer.getIndex() < secondRange.startOffset )
+ if ( firstRange.endContainer.getParent().equals( secondRange.startContainer ) &&
+ firstRange.endContainer.getIndex() < secondRange.startOffset )
return true;
return false;
diff --git a/tests/plugins/clipboard/drop.js b/tests/plugins/clipboard/drop.js
index 1ba66382cc4..ea4871cc297 100644
--- a/tests/plugins/clipboard/drop.js
+++ b/tests/plugins/clipboard/drop.js
@@ -3,6 +3,9 @@
'use strict';
+var setWithHtml = bender.tools.selection.setWithHtml,
+ getWithHtml = bender.tools.selection.getWithHtml;
+
CKEDITOR.disableAutoInline = true;
function createDragDropEventMock() {
@@ -167,6 +170,30 @@ var editors, editorBots,
} );
},
+ 'test drop after range end': function( editor ) {
+ var bot = editorBots[ editor.name ],
+ evt = createDragDropEventMock();
+
+ setWithHtml( editor, 'lor{em ipsum} dolor sit amet.
' );
+
+ drag( editor, evt );
+
+ drop( editor, evt, {
+ element: CKEDITOR.env.ie && CKEDITOR.env.version == 8 ?
+ editor.document.getById( 'p' ).getChild( 2 ) :
+ editor.document.getById( 'p' ).getChild( 1 ),
+ offset: CKEDITOR.env.ie && CKEDITOR.env.version == 8 ?
+ 11 :
+ 17
+ }, function() {
+ assert.isMatching( /lor<\/b> dolor sit em<\/b> ipsum(\[\]|\{\})amet\.(
)?<\/p>/, getWithHtml( editor ).toLowerCase(), 'after drop' );
+
+ editor.execCommand( 'undo' );
+
+ assert.isMatching( /
lorem<\/b> ipsum dolor sit \{\}amet\.(
)?<\/p>/, getWithHtml( editor ).toLowerCase(), 'after undo' );
+ } );
+ },
+
'test drop after paragraph': function( editor ) {
var bot = editorBots[ editor.name ],
evt = createDragDropEventMock();
From 3b68910d8cf5d861035e3036ac4834b852e45374 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotrek=20Reinmar=20Koszuli=C5=84ski?=
Date: Wed, 2 Jul 2014 11:32:25 +0200
Subject: [PATCH 47/67] Clean up in drop tests.
---
tests/plugins/clipboard/drop.js | 84 +++++++++++++++++----------------
1 file changed, 43 insertions(+), 41 deletions(-)
diff --git a/tests/plugins/clipboard/drop.js b/tests/plugins/clipboard/drop.js
index ea4871cc297..7ec882bb196 100644
--- a/tests/plugins/clipboard/drop.js
+++ b/tests/plugins/clipboard/drop.js
@@ -4,7 +4,12 @@
'use strict';
var setWithHtml = bender.tools.selection.setWithHtml,
- getWithHtml = bender.tools.selection.getWithHtml;
+ getWithHtml = bender.tools.selection.getWithHtml,
+ htmlMatchOpts = {
+ compareSelection: true,
+ normalizeSelection: true,
+ fixStyles: true
+ };
CKEDITOR.disableAutoInline = true;
@@ -41,7 +46,7 @@ function drop( editor, evt, config, callback ) {
dropTarget = ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) || editable.isInline() ? editable : editor.document,
range = new CKEDITOR.dom.range( editor.document ),
pasteEventCounter = 0,
- expectedPasteEventCount = typeof config.expectedPasteEventCount !== 'undefined' ?
+ expectedPasteEventCount = typeof config.expectedPasteEventCount !== 'undefined' ?
config.expectedPasteEventCount :
1;
@@ -63,7 +68,7 @@ function drop( editor, evt, config, callback ) {
assert.areSame( expectedPasteEventCount, pasteEventCounter, 'paste event should be called ' + expectedPasteEventCount + ' time(s)' );
callback();
- }, 100 );
+ }, 10 );
}
var editors, editorBots,
@@ -72,16 +77,14 @@ var editors, editorBots,
name: 'framed',
creator: 'replace',
config: {
- allowedContent: true,
- toolbarGroups: [ { name: 'clipboard', groups: [ 'clipboard', 'undo' ] } ]
+ allowedContent: true
}
},
inline: {
name: 'inline',
creator: 'inline',
config: {
- allowedContent: true,
- toolbarGroups: [ { name: 'clipboard', groups: [ 'clipboard', 'undo' ] } ]
+ allowedContent: true
}
},
divarea: {
@@ -89,16 +92,14 @@ var editors, editorBots,
creator: 'replace',
config: {
extraPlugins: 'divarea',
- allowedContent: true,
- toolbarGroups: [ { name: 'clipboard', groups: [ 'clipboard', 'undo' ] } ]
+ allowedContent: true
}
},
cross: {
name: 'cross',
creator: 'replace',
config: {
- allowedContent: true,
- toolbarGroups: [ { name: 'clipboard', groups: [ 'clipboard', 'undo' ] } ]
+ allowedContent: true
}
}
},
@@ -117,16 +118,14 @@ var editors, editorBots,
drag( editor, evt );
drop( editor, evt, {
- element: editor.document.getById( 'h1' ).getChild( 0 ),
+ element: editor.document.getById( 'h1' ).getChild( 0 ),
offset: 7
}, function() {
assert.areSame( 'Header1dolor^
Lorem ipsum sit amet.
', bender.tools.getHtmlWithSelection( editor ), 'after drop' );
editor.execCommand( 'undo' );
- wait( function() {
- assert.areSame( 'Header1
Lorem ipsum dolor sit amet.
', bender.tools.compatHtml( editor.getData(), 0, 1, 0, 1 ), 'after undo' );
- }, 100 );
+ assert.areSame( 'Header1
Lorem ipsum dolor sit amet.
', editor.getData(), 'after undo' );
} );
},
@@ -139,14 +138,14 @@ var editors, editorBots,
drag( editor, evt );
drop( editor, evt, {
- element: editor.document.getById( 'p' ).getChild( 0 ),
+ element: editor.document.getById( 'p' ).getChild( 0 ),
offset: 6
}, function() {
assert.areSame( 'Lorem dolor^ipsum sit amet.
', bender.tools.getHtmlWithSelection( editor ), 'after drop' );
editor.execCommand( 'undo' );
- assert.areSame( 'Lorem ipsum dolor sit amet.
', bender.tools.compatHtml( editor.getData(), 0, 1, 0, 1 ), 'after undo' );
+ assert.areSame( 'Lorem ipsum dolor sit amet.
', editor.getData(), 'after undo' );
} );
},
@@ -159,14 +158,14 @@ var editors, editorBots,
drag( editor, evt );
drop( editor, evt, {
- element: editor.document.getById( 'p' ).getChild( 2 ),
+ element: editor.document.getById( 'p' ).getChild( 2 ),
offset: 11
}, function() {
assert.areSame( 'Lorem dolor sit ipsum^amet.
', bender.tools.getHtmlWithSelection( editor ), 'after drop' );
editor.execCommand( 'undo' );
- assert.areSame( 'Lorem ipsum dolor sit amet.
', bender.tools.compatHtml( editor.getData(), 0, 1, 0, 1 ), 'after undo' );
+ assert.areSame( 'Lorem ipsum dolor sit amet.
', editor.getData(), 'after undo' );
} );
},
@@ -186,11 +185,11 @@ var editors, editorBots,
11 :
17
}, function() {
- assert.isMatching( /lor<\/b> dolor sit em<\/b> ipsum(\[\]|\{\})amet\.(
)?<\/p>/, getWithHtml( editor ).toLowerCase(), 'after drop' );
+ assert.isInnerHtmlMatching( '
lor dolor sit em ipsum^amet.@
', getWithHtml( editor ), htmlMatchOpts, 'after drop' );
editor.execCommand( 'undo' );
- assert.isMatching( /lorem<\/b> ipsum dolor sit \{\}amet\.(
)?<\/p>/, getWithHtml( editor ).toLowerCase(), 'after undo' );
+ assert.isInnerHtmlMatching( '
lorem ipsum dolor sit ^amet.@
', getWithHtml( editor ), htmlMatchOpts, 'after undo' );
} );
},
@@ -203,14 +202,14 @@ var editors, editorBots,
drag( editor, evt );
drop( editor, evt, {
- element: editor.document.getById( 'p' ).getChild( 2 ),
+ element: editor.document.getById( 'p' ).getChild( 2 ),
offset: 16
}, function() {
assert.areSame( 'Lorem dolor sit amet.ipsum^
', bender.tools.getHtmlWithSelection( editor ), 'after drop' );
editor.execCommand( 'undo' );
- assert.areSame( 'Lorem ipsum dolor sit amet.
', bender.tools.compatHtml( editor.getData(), 0, 1, 0, 1 ), 'after undo' );
+ assert.areSame( 'Lorem ipsum dolor sit amet.
', editor.getData(), 'after undo' );
} );
},
@@ -223,14 +222,14 @@ var editors, editorBots,
drag( editor, evt );
drop( editor, evt, {
- element: editor.document.getById( 'p' ).getChild( 0 ),
+ element: editor.document.getById( 'p' ).getChild( 0 ),
offset: 0
}, function() {
- assert.isMatching( /ipsum\^Lorem dolor sit amet\.<\/p>/, bender.tools.compatHtml( bender.tools.getHtmlWithSelection( editor ), 0, 1, 0, 1 ), 'after drop' );
+ assert.isInnerHtmlMatching( '
ipsum^Lorem dolor sit amet.
', getWithHtml( editor ), htmlMatchOpts, 'after drop' );
editor.execCommand( 'undo' );
- assert.isMatching( 'Lorem ipsum dolor sit amet.
', bender.tools.compatHtml( editor.getData(), 1, 1, 1, 1 ), 'after undo' );
+ assert.isInnerHtmlMatching( 'Lorem ipsum dolor sit amet.
', editor.getData(), htmlMatchOpts, 'after undo' );
} );
},
@@ -246,14 +245,14 @@ var editors, editorBots,
evt.$.dataTransfer.setData( 'text/html', 'dolor' );
drop( editor, evt, {
- element: editor.document.getById( 'p' ).getChild( 0 ),
+ element: editor.document.getById( 'p' ).getChild( 0 ),
offset: 6
}, function() {
assert.areSame( 'Lorem dolor^ipsum sit amet.
', bender.tools.getHtmlWithSelection( editor ), 'after drop' );
editor.execCommand( 'undo' );
- assert.areSame( 'Lorem ipsum sit amet.
', bender.tools.compatHtml( editor.getData(), 0, 1, 0, 1 ), 'after undo' );
+ assert.areSame( 'Lorem ipsum sit amet.
', editor.getData(), 'after undo' );
} );
},
@@ -269,14 +268,14 @@ var editors, editorBots,
evt.$.dataTransfer.setData( 'text/html', 'dolor' );
drop( editor, evt, {
- element: editor.document.getById( 'p' ).getChild( 0 ),
+ element: editor.document.getById( 'p' ).getChild( 0 ),
offset: 6
}, function() {
assert.areSame( 'Lorem dolor^ipsum sit amet.
', bender.tools.getHtmlWithSelection( editor ), 'after drop' );
editor.execCommand( 'undo' );
- assert.areSame( 'Lorem ipsum sit amet.
', bender.tools.compatHtml( editor.getData(), 0, 1, 0, 1 ), 'after undo' );
+ assert.areSame( 'Lorem ipsum sit amet.
', editor.getData(), 'after undo' );
} );
},
@@ -287,7 +286,7 @@ var editors, editorBots,
bot.setHtmlWithSelection( 'Lorem ^ipsum sit amet.
' );
drop( editor, evt, {
- element: editor.document.getById( 'p' ).getChild( 0 ),
+ element: editor.document.getById( 'p' ).getChild( 0 ),
offset: 6,
expectedPasteEventCount: 0
}, function() {
@@ -301,24 +300,23 @@ var editors, editorBots,
botCross = editorBots[ 'cross' ],
editorCross = botCross.editor;
- bot.setHtmlWithSelection( 'Lorem ipsum sit amet.
' );
- botCross.setHtmlWithSelection( 'Lorem [ipsum dolor] sit amet.
' );
+ setWithHtml( bot.editor, 'Lorem ipsum sit amet.
' );
+ setWithHtml( botCross.editor, 'Lorem {ipsum dolor }sit amet.
' );
drag( editorCross, evt );
drop( editor, evt, {
- element: editor.document.getById( 'p' ).getChild( 0 ),
+ element: editor.document.getById( 'p' ).getChild( 0 ),
offset: 6
}, function() {
- assert.areSame( 'Lorem ipsum dolor^ipsum sit amet.
', bender.tools.getHtmlWithSelection( editor ), 'after drop' );
-
- assert.areSame( 'Lorem sit amet.
', bender.tools.compatHtml( editorCross.getData(), 0, 1, 0, 1 ), 'after drop - editor cross' );
+ assert.areSame( 'Lorem ipsum dolor ^ipsum sit amet.
', bender.tools.getHtmlWithSelection( editor ), 'after drop' );
+ assert.areSame( 'Lorem sit amet.
', editorCross.getData(), 'after drop - editor cross' );
editor.execCommand( 'undo' );
editorCross.execCommand( 'undo' );
- assert.areSame( 'Lorem ipsum sit amet.
', bender.tools.compatHtml( editor.getData(), 0, 1, 0, 1 ), 'after undo' );
- assert.areSame( 'Lorem ipsum dolor sit amet.
', bender.tools.compatHtml( editorCross.getData(), 0, 1, 0, 1 ), 'after undo - editor cross' );
+ assert.areSame( 'Lorem ipsum sit amet.
', editor.getData(), 'after undo' );
+ assert.areSame( 'Lorem ipsum dolor sit amet.
', editorCross.getData(), 'after undo - editor cross' );
} );
}
},
@@ -353,9 +351,9 @@ var editors, editorBots,
// Asserts.
assert.areSame( 1, p.getChildCount() );
dragRange.select();
- assert.isMatching( /lorem ipsum\{\} sit amet\.(
)?<\/p>/, bender.tools.selection.getWithHtml( editor ).toLowerCase() );
+ assert.isInnerHtmlMatching( '
lorem ipsum^ sit amet\.@
', getWithHtml( editor ), htmlMatchOpts );
dropRange.select();
- assert.isMatching( /lorem\{\} ipsum sit amet\.(
)?<\/p>/, bender.tools.selection.getWithHtml( editor ).toLowerCase() );
+ assert.isInnerHtmlMatching( '
lorem^ ipsum sit amet.@
', getWithHtml( editor ), htmlMatchOpts );
},
'test rangeBefore 1': function() {
@@ -429,6 +427,10 @@ bender.tools.setUpEditors( editorsDefinitions, function( e, eb ) {
editors = e;
editorBots = eb;
+ for ( var name in editors ) {
+ editors[ name ].dataProcessor.writer.sortAttributes = true;
+ }
+
bender.test( CKEDITOR.tools.extend(
bender.tools.createTestsForEditors(
[ editors.framed, editors.inline, editors.divarea ],
From 93f0066112ddb68fd68260b8d1092511698c8871 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotrek=20Reinmar=20Koszuli=C5=84ski?=
Date: Wed, 2 Jul 2014 13:21:52 +0200
Subject: [PATCH 48/67] Undo tests must be run precisely - reset stack and then
wait for afterPaste - avoid guessing timeouts.
---
tests/plugins/clipboard/drop.js | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/tests/plugins/clipboard/drop.js b/tests/plugins/clipboard/drop.js
index 7ec882bb196..caf7765e11c 100644
--- a/tests/plugins/clipboard/drop.js
+++ b/tests/plugins/clipboard/drop.js
@@ -62,13 +62,22 @@ function drop( editor, evt, config, callback ) {
pasteEventCounter++;
} );
- dropTarget.fire( 'drop', evt );
+ if ( expectedPasteEventCount ) {
+ editor.once( 'afterPaste', function() {
+ resume( finish );
+ } );
+ // Ensure async.
+ wait( function() {
+ dropTarget.fire( 'drop', evt );
+ } );
+ } else {
+ wait( finish, 100 );
+ }
- wait( function() {
+ function finish() {
assert.areSame( expectedPasteEventCount, pasteEventCounter, 'paste event should be called ' + expectedPasteEventCount + ' time(s)' );
-
callback();
- }, 10 );
+ }
}
var editors, editorBots,
@@ -114,6 +123,7 @@ var editors, editorBots,
bot.setHtmlWithSelection( 'Header1
' +
'Lorem ipsum [dolor] sit amet.
' );
+ editor.resetUndo();
drag( editor, evt );
@@ -134,6 +144,7 @@ var editors, editorBots,
evt = createDragDropEventMock();
bot.setHtmlWithSelection( 'Lorem ipsum [dolor] sit amet.
' );
+ editor.resetUndo();
drag( editor, evt );
@@ -154,6 +165,7 @@ var editors, editorBots,
evt = createDragDropEventMock();
bot.setHtmlWithSelection( 'Lorem [ipsum] dolor sit amet.
' );
+ editor.resetUndo();
drag( editor, evt );
@@ -174,6 +186,7 @@ var editors, editorBots,
evt = createDragDropEventMock();
setWithHtml( editor, 'lor{em ipsum} dolor sit amet.
' );
+ editor.resetUndo();
drag( editor, evt );
@@ -198,6 +211,7 @@ var editors, editorBots,
evt = createDragDropEventMock();
bot.setHtmlWithSelection( 'Lorem [ipsum] dolor sit amet.
' );
+ editor.resetUndo();
drag( editor, evt );
@@ -218,6 +232,7 @@ var editors, editorBots,
evt = createDragDropEventMock();
bot.setHtmlWithSelection( 'Lorem [ipsum] dolor sit amet.
' );
+ editor.resetUndo();
drag( editor, evt );
@@ -238,6 +253,7 @@ var editors, editorBots,
evt = createDragDropEventMock();
bot.setHtmlWithSelection( 'Lorem ipsum sit amet.
' );
+ editor.resetUndo();
if ( CKEDITOR.env.ie )
evt.$.dataTransfer.setData( 'Text', 'dolor' );
@@ -261,6 +277,7 @@ var editors, editorBots,
evt = createDragDropEventMock();
bot.setHtmlWithSelection( 'Lorem ipsum sit amet.
' );
+ editor.resetUndo();
if ( CKEDITOR.env.ie )
evt.$.dataTransfer.setData( 'Text', 'dolor' );
@@ -283,6 +300,7 @@ var editors, editorBots,
var bot = editorBots[ editor.name ],
evt = createDragDropEventMock();
+ editor.resetUndo();
bot.setHtmlWithSelection( 'Lorem ^ipsum sit amet.
' );
drop( editor, evt, {
@@ -302,6 +320,8 @@ var editors, editorBots,
setWithHtml( bot.editor, 'Lorem ipsum sit amet.
' );
setWithHtml( botCross.editor, 'Lorem {ipsum dolor }sit amet.
' );
+ bot.editor.resetUndo();
+ botCross.editor.resetUndo();
drag( editorCross, evt );
From 08534e7c3837bb4b3fa86478ab6577467b5f38f8 Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Wed, 2 Jul 2014 15:03:50 +0200
Subject: [PATCH 49/67] Call drop even if expectedPasteEventCount=0.
---
tests/plugins/clipboard/drop.js | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/tests/plugins/clipboard/drop.js b/tests/plugins/clipboard/drop.js
index caf7765e11c..9cb1d42f149 100644
--- a/tests/plugins/clipboard/drop.js
+++ b/tests/plugins/clipboard/drop.js
@@ -66,14 +66,15 @@ function drop( editor, evt, config, callback ) {
editor.once( 'afterPaste', function() {
resume( finish );
} );
- // Ensure async.
- wait( function() {
- dropTarget.fire( 'drop', evt );
- } );
} else {
wait( finish, 100 );
}
+ // Ensure async.
+ wait( function() {
+ dropTarget.fire( 'drop', evt );
+ } );
+
function finish() {
assert.areSame( expectedPasteEventCount, pasteEventCounter, 'paste event should be called ' + expectedPasteEventCount + ' time(s)' );
callback();
From 9c6122af52aebfd18e00097c1705c4efe2d37c7a Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Wed, 2 Jul 2014 15:23:50 +0200
Subject: [PATCH 50/67] Tests: Call resetDataTransfer in the setUp.
---
tests/plugins/clipboard/datatransfer.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tests/plugins/clipboard/datatransfer.js b/tests/plugins/clipboard/datatransfer.js
index c6cb4d68b10..2e33e6cbf8f 100644
--- a/tests/plugins/clipboard/datatransfer.js
+++ b/tests/plugins/clipboard/datatransfer.js
@@ -53,6 +53,10 @@ bender.test( {
} );
},
+ setUp: function() {
+ CKEDITOR.plugins.clipboard.resetDataTransfer();
+ },
+
'test dataTransfer id': function() {
var evt1 = createDragDropEventMock(),
evt2 = createDragDropEventMock(),
@@ -183,8 +187,6 @@ bender.test( {
dataTransferB = CKEDITOR.plugins.clipboard.initDataTransfer( evt2 );
assert.areNotSame( dataTransferA, dataTransferB );
-
- CKEDITOR.plugins.clipboard.resetDataTransfer();
},
'test initDataTransfer constructor': function() {
@@ -203,7 +205,5 @@ bender.test( {
assert.areSame( 'html', dataTransfer.dataType, 'dataType' );
assert.areSame( editor, dataTransfer.sourceEditor, 'sourceEditor' );
assert.areSame( editor, dataTransfer.targetEditor, 'targetEditor' );
-
- CKEDITOR.plugins.clipboard.resetDataTransfer();
}
} );
\ No newline at end of file
From 1887bc900400e30219ae8c3143e8c48f8580e36e Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Wed, 2 Jul 2014 15:28:11 +0200
Subject: [PATCH 51/67] Tests: Used 'xfoox' instead of 'foo'.
---
tests/plugins/clipboard/datatransfer.js | 27 +++++++++++--------------
1 file changed, 12 insertions(+), 15 deletions(-)
diff --git a/tests/plugins/clipboard/datatransfer.js b/tests/plugins/clipboard/datatransfer.js
index 2e33e6cbf8f..ea74f31e89c 100644
--- a/tests/plugins/clipboard/datatransfer.js
+++ b/tests/plugins/clipboard/datatransfer.js
@@ -76,7 +76,7 @@ bender.test( {
editor = this.editors.editor1,
evt, dataTransfer;
- bot.setHtmlWithSelection( '[foo]' );
+ bot.setHtmlWithSelection( '[xfoox]' );
evt = createDragDropEventMock();
evt.data.$.dataTransfer.setData( 'Text', 'foo' );
@@ -85,8 +85,7 @@ bender.test( {
dataTransfer.setTargetEditor( editor );
assert.areSame( CKEDITOR.DATA_TRANSFER_INTERNAL, dataTransfer.getTransferType() );
- // On Safari getSelectedHtml does not work properly.
- assert.areSame( CKEDITOR.env.safari ? 'foo' : 'foo', bender.tools.fixHtml( dataTransfer.dataValue ), 'dataValue' );
+ assert.areSame( 'xfoox', bender.tools.fixHtml( dataTransfer.dataValue ), 'dataValue' );
assert.areSame( 'html', dataTransfer.dataType, 'dataType' );
assert.areSame( editor, dataTransfer.sourceEditor, 'sourceEditor' );
assert.areSame( editor, dataTransfer.targetEditor, 'targetEditor' );
@@ -99,17 +98,17 @@ bender.test( {
evt, dataTransfer;
evt = createDragDropEventMock();
- evt.data.$.dataTransfer.setData( 'Text', 'foo' );
+ evt.data.$.dataTransfer.setData( 'Text', 'xfoox' );
dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer( evt );
dataTransfer.setTargetEditor( editor );
assert.areSame( CKEDITOR.DATA_TRANSFER_EXTERNAL, dataTransfer.getTransferType() );
- assert.areSame( '<b>foo</b>', dataTransfer.dataValue, 'dataValue' );
+ assert.areSame( 'x<b>foo</b>x', dataTransfer.dataValue, 'dataValue' );
assert.areSame( 'text', dataTransfer.dataType, 'dataType' );
assert.isUndefined( dataTransfer.sourceEditor, 'sourceEditor' );
assert.areSame( editor, dataTransfer.targetEditor, 'targetEditor' );
- assert.areSame( 'foo', dataTransfer.getData( 'Text' ), 'getData( \'Text\' )' );
+ assert.areSame( 'xfoox', dataTransfer.getData( 'Text' ), 'getData( \'Text\' )' );
},
'test dataTransfer external html': function() {
@@ -119,7 +118,7 @@ bender.test( {
evt = createDragDropEventMock();
evt.data.$.dataTransfer.setData( 'Text', 'foo' );
if ( !CKEDITOR.env.ie ) {
- evt.data.$.dataTransfer.setData( 'text/html', 'foo' );
+ evt.data.$.dataTransfer.setData( 'text/html', 'xfoox' );
}
dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer( evt );
@@ -134,10 +133,10 @@ bender.test( {
assert.areSame( 'text', dataTransfer.dataType, 'dataType' );
assert.areSame( 'foo', dataTransfer.getData( 'Text' ), 'getData( \'Text\' )' );
} else {
- assert.areSame( 'foo', dataTransfer.dataValue, 'dataValue' );
+ assert.areSame( 'xfoox', dataTransfer.dataValue, 'dataValue' );
assert.areSame( 'html', dataTransfer.dataType, 'dataType' );
assert.areSame( 'foo', dataTransfer.getData( 'Text' ), 'getData( \'Text\' )' );
- assert.areSame( 'foo', dataTransfer.getData( 'text/html' ), 'getData( \'text/html\' )' );
+ assert.areSame( 'xfoox', dataTransfer.getData( 'text/html' ), 'getData( \'text/html\' )' );
}
},
@@ -147,7 +146,7 @@ bender.test( {
editor2 = this.editors.editor2,
evt, dataTransfer;
- bot1.setHtmlWithSelection( '[foo]' );
+ bot1.setHtmlWithSelection( '[xfoox]' );
evt = createDragDropEventMock();
evt.data.$.dataTransfer.setData( 'Text', 'foo' );
@@ -156,8 +155,7 @@ bender.test( {
dataTransfer.setTargetEditor( editor2 );
assert.areSame( CKEDITOR.DATA_TRANSFER_CROSS_EDITORS, dataTransfer.getTransferType() );
- // On Safari getSelectedHtml does not work properly.
- assert.areSame( CKEDITOR.env.safari ? 'foo' : 'foo', bender.tools.fixHtml( dataTransfer.dataValue ), 'dataValue' );
+ assert.areSame( 'xfoox', bender.tools.fixHtml( dataTransfer.dataValue ), 'dataValue' );
assert.areSame( 'html', dataTransfer.dataType, 'dataType' );
assert.areSame( editor1, dataTransfer.sourceEditor, 'sourceEditor' );
assert.areSame( editor2, dataTransfer.targetEditor, 'targetEditor' );
@@ -193,15 +191,14 @@ bender.test( {
var bot = this.bots.editor1,
editor = this.editors.editor1;
- bot.setHtmlWithSelection( '[foo]' );
+ bot.setHtmlWithSelection( '[xfoox]' );
var evt = createDragDropEventMock(),
dataTransfer = CKEDITOR.plugins.clipboard.initDataTransfer( evt, editor );
dataTransfer.setTargetEditor( editor );
assert.areSame( CKEDITOR.DATA_TRANSFER_INTERNAL, dataTransfer.getTransferType() );
- // On Safari getSelectedHtml does not work properly.
- assert.areSame( CKEDITOR.env.safari ? 'foo' : 'foo', bender.tools.fixHtml( dataTransfer.dataValue ), 'dataValue' );
+ assert.areSame( 'xfoox', bender.tools.fixHtml( dataTransfer.dataValue ), 'dataValue' );
assert.areSame( 'html', dataTransfer.dataType, 'dataType' );
assert.areSame( editor, dataTransfer.sourceEditor, 'sourceEditor' );
assert.areSame( editor, dataTransfer.targetEditor, 'targetEditor' );
From a189f5c94eb53e0fb0965e0065db1f9a5b7dcbb4 Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Wed, 2 Jul 2014 16:56:24 +0200
Subject: [PATCH 52/67] Fixed tests on FF and IE10.
---
tests/plugins/clipboard/drop.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/plugins/clipboard/drop.js b/tests/plugins/clipboard/drop.js
index 9cb1d42f149..a77194481a1 100644
--- a/tests/plugins/clipboard/drop.js
+++ b/tests/plugins/clipboard/drop.js
@@ -67,7 +67,7 @@ function drop( editor, evt, config, callback ) {
resume( finish );
} );
} else {
- wait( finish, 100 );
+ wait( finish, 300 );
}
// Ensure async.
@@ -241,11 +241,11 @@ var editors, editorBots,
element: editor.document.getById( 'p' ).getChild( 0 ),
offset: 0
}, function() {
- assert.isInnerHtmlMatching( 'ipsum^Lorem dolor sit amet.
', getWithHtml( editor ), htmlMatchOpts, 'after drop' );
+ assert.isInnerHtmlMatching( 'ipsum^Lorem dolor sit amet.@
', getWithHtml( editor ), htmlMatchOpts, 'after drop' );
editor.execCommand( 'undo' );
- assert.isInnerHtmlMatching( 'Lorem ipsum dolor sit amet.
', editor.getData(), htmlMatchOpts, 'after undo' );
+ assert.isInnerHtmlMatching( 'Lorem ipsum dolor sit amet.@
', editor.getData(), htmlMatchOpts, 'after undo' );
} );
},
From 6ecc615cb0c805837bbb2931002ba84c7a4a7c20 Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Thu, 3 Jul 2014 11:15:06 +0200
Subject: [PATCH 53/67] Tests: Added docs to the 'test drop after range end'.
---
tests/plugins/clipboard/drop.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/plugins/clipboard/drop.js b/tests/plugins/clipboard/drop.js
index a77194481a1..c18dc70037b 100644
--- a/tests/plugins/clipboard/drop.js
+++ b/tests/plugins/clipboard/drop.js
@@ -192,6 +192,7 @@ var editors, editorBots,
drag( editor, evt );
drop( editor, evt, {
+ // IE8 split text node anyway so we need different drop position there.
element: CKEDITOR.env.ie && CKEDITOR.env.version == 8 ?
editor.document.getById( 'p' ).getChild( 2 ) :
editor.document.getById( 'p' ).getChild( 1 ),
From 13a069f5fcbaae10b1bcb1e50ea32262bc4b62d5 Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Thu, 3 Jul 2014 11:29:57 +0200
Subject: [PATCH 54/67] Tests: Improved datatransfer tests descriptions.
---
tests/plugins/clipboard/datatransfer.js | 30 ++++++++++++-------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/tests/plugins/clipboard/datatransfer.js b/tests/plugins/clipboard/datatransfer.js
index ea74f31e89c..04e92b1dcb2 100644
--- a/tests/plugins/clipboard/datatransfer.js
+++ b/tests/plugins/clipboard/datatransfer.js
@@ -57,21 +57,21 @@ bender.test( {
CKEDITOR.plugins.clipboard.resetDataTransfer();
},
- 'test dataTransfer id': function() {
+ 'test id': function() {
var evt1 = createDragDropEventMock(),
evt2 = createDragDropEventMock(),
dataTransfer1a = new CKEDITOR.plugins.clipboard.dataTransfer( evt1 ),
dataTransfer1b = new CKEDITOR.plugins.clipboard.dataTransfer( evt1 ),
dataTransfer2 = new CKEDITOR.plugins.clipboard.dataTransfer( evt2 );
- assert.areSame( dataTransfer1a.id, dataTransfer1b.id );
+ assert.areSame( dataTransfer1a.id, dataTransfer1b.id, 'Ids for object based on the same event should be the same.' );
// In IE10+ we can not use any data type besides text, so id is fixed.
if ( !CKEDITOR.env.ie || CKEDITOR.env.version < 10 )
- assert.areNotSame( dataTransfer1a.id, dataTransfer2.id );
+ assert.areNotSame( dataTransfer1a.id, dataTransfer2.id, 'Ids for object based on different events should be different.' );
},
- 'test dataTransfer internal': function() {
+ 'test internal drag drop': function() {
var bot = this.bots.editor1,
editor = this.editors.editor1,
evt, dataTransfer;
@@ -84,7 +84,7 @@ bender.test( {
dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer( evt, editor );
dataTransfer.setTargetEditor( editor );
- assert.areSame( CKEDITOR.DATA_TRANSFER_INTERNAL, dataTransfer.getTransferType() );
+ assert.areSame( CKEDITOR.DATA_TRANSFER_INTERNAL, dataTransfer.getTransferType(), 'transferType' );
assert.areSame( 'xfoox', bender.tools.fixHtml( dataTransfer.dataValue ), 'dataValue' );
assert.areSame( 'html', dataTransfer.dataType, 'dataType' );
assert.areSame( editor, dataTransfer.sourceEditor, 'sourceEditor' );
@@ -93,7 +93,7 @@ bender.test( {
},
- 'test dataTransfer external text': function() {
+ 'test drop text from external source': function() {
var editor = this.editors.editor1,
evt, dataTransfer;
@@ -103,7 +103,7 @@ bender.test( {
dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer( evt );
dataTransfer.setTargetEditor( editor );
- assert.areSame( CKEDITOR.DATA_TRANSFER_EXTERNAL, dataTransfer.getTransferType() );
+ assert.areSame( CKEDITOR.DATA_TRANSFER_EXTERNAL, dataTransfer.getTransferType(), 'transferType' );
assert.areSame( 'x<b>foo</b>x', dataTransfer.dataValue, 'dataValue' );
assert.areSame( 'text', dataTransfer.dataType, 'dataType' );
assert.isUndefined( dataTransfer.sourceEditor, 'sourceEditor' );
@@ -111,7 +111,7 @@ bender.test( {
assert.areSame( 'xfoox', dataTransfer.getData( 'Text' ), 'getData( \'Text\' )' );
},
- 'test dataTransfer external html': function() {
+ 'test drop html from external source': function() {
var editor = this.editors.editor1,
evt, dataTransfer;
@@ -124,7 +124,7 @@ bender.test( {
dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer( evt );
dataTransfer.setTargetEditor( editor );
- assert.areSame( CKEDITOR.DATA_TRANSFER_EXTERNAL, dataTransfer.getTransferType() );
+ assert.areSame( CKEDITOR.DATA_TRANSFER_EXTERNAL, dataTransfer.getTransferType(), 'transferType' );
assert.isUndefined( dataTransfer.sourceEditor, 'sourceEditor' );
assert.areSame( editor, dataTransfer.targetEditor, 'targetEditor' );
@@ -140,7 +140,7 @@ bender.test( {
}
},
- 'test dataTransfer cross': function() {
+ 'test drag drop between editors': function() {
var bot1 = this.bots.editor1,
editor1 = this.editors.editor1,
editor2 = this.editors.editor2,
@@ -154,7 +154,7 @@ bender.test( {
dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer( evt, editor1 );
dataTransfer.setTargetEditor( editor2 );
- assert.areSame( CKEDITOR.DATA_TRANSFER_CROSS_EDITORS, dataTransfer.getTransferType() );
+ assert.areSame( CKEDITOR.DATA_TRANSFER_CROSS_EDITORS, dataTransfer.getTransferType(), 'transferType' );
assert.areSame( 'xfoox', bender.tools.fixHtml( dataTransfer.dataValue ), 'dataValue' );
assert.areSame( 'html', dataTransfer.dataType, 'dataType' );
assert.areSame( editor1, dataTransfer.sourceEditor, 'sourceEditor' );
@@ -168,7 +168,7 @@ bender.test( {
dataTransfer.setData( 'Text', 'foo' );
- assert.areSame( 'foo', dataTransfer.getData( 'Text' ) );
+ assert.areSame( 'foo', dataTransfer.getData( 'Text' ), 'data should match set data' );
},
@@ -178,13 +178,13 @@ bender.test( {
dataTransferA = CKEDITOR.plugins.clipboard.initDataTransfer( evt1 ),
dataTransferB = CKEDITOR.plugins.clipboard.initDataTransfer( evt1 );
- assert.areSame( dataTransferA, dataTransferB );
+ assert.areSame( dataTransferA, dataTransferB, 'If we init dataTransfer object twice on the same event this should be the same object.' );
CKEDITOR.plugins.clipboard.resetDataTransfer();
dataTransferB = CKEDITOR.plugins.clipboard.initDataTransfer( evt2 );
- assert.areNotSame( dataTransferA, dataTransferB );
+ assert.areNotSame( dataTransferA, dataTransferB, 'If we init dataTransfer object twice on different events these should be different objects.' );
},
'test initDataTransfer constructor': function() {
@@ -197,7 +197,7 @@ bender.test( {
dataTransfer = CKEDITOR.plugins.clipboard.initDataTransfer( evt, editor );
dataTransfer.setTargetEditor( editor );
- assert.areSame( CKEDITOR.DATA_TRANSFER_INTERNAL, dataTransfer.getTransferType() );
+ assert.areSame( CKEDITOR.DATA_TRANSFER_INTERNAL, dataTransfer.getTransferType(), 'transferType' );
assert.areSame( 'xfoox', bender.tools.fixHtml( dataTransfer.dataValue ), 'dataValue' );
assert.areSame( 'html', dataTransfer.dataType, 'dataType' );
assert.areSame( editor, dataTransfer.sourceEditor, 'sourceEditor' );
From 228d7e852d3c47ac429b676c513b5e31e7d7c62b Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Thu, 3 Jul 2014 11:39:15 +0200
Subject: [PATCH 55/67] Made addDropListenersToEditable anonymous function.
---
plugins/clipboard/plugin.js | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/plugins/clipboard/plugin.js b/plugins/clipboard/plugin.js
index 54182d674b8..a3e15d91f28 100644
--- a/plugins/clipboard/plugin.js
+++ b/plugins/clipboard/plugin.js
@@ -1209,9 +1209,7 @@
}
function initDragDrop( editor ) {
- editor.on( 'contentDom', addDropListenersToEditable );
-
- function addDropListenersToEditable() {
+ editor.on( 'contentDom', function() {
var editable = editor.editable(),
// #11123 Firefox needs to listen on document, because otherwise event won't be fired.
// #11086 IE8 cannot listen on document.
@@ -1352,7 +1350,7 @@
editor.toolbox.focus();
} );
}
- }
+ } );
}
/**
From 2e7311e2f38ab2f2554f94fbf2b5019a2d1c8831 Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Thu, 3 Jul 2014 11:42:51 +0200
Subject: [PATCH 56/67] Do not cache fixIESplittedNodes and rangeBefore
functions. Cache rangeBefore result.
---
plugins/clipboard/plugin.js | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/plugins/clipboard/plugin.js b/plugins/clipboard/plugin.js
index a3e15d91f28..7ac962902ad 100644
--- a/plugins/clipboard/plugin.js
+++ b/plugins/clipboard/plugin.js
@@ -1259,9 +1259,7 @@
// Execute drop with a timeout because otherwise selection, after drop,
// on IE is in the drag position, instead of drop position.
setTimeout( function() {
- var dragBookmark, dropBookmark, i,
- rangeBefore = CKEDITOR.plugins.clipboard.rangeBefore,
- fixIESplittedNodes = CKEDITOR.plugins.clipboard.fixIESplittedNodes;
+ var dragBookmark, dropBookmark, i, rangeBefore;
// Save and lock snapshot so there will be only
// one snapshot for both remove and insert content.
@@ -1269,7 +1267,7 @@
editor.fire( 'lockSnapshot', { dontUpdate: 1 } );
if ( CKEDITOR.env.ie && CKEDITOR.env.version < 10 ) {
- fixIESplittedNodes( dragRange, dropRange );
+ CKEDITOR.plugins.clipboard.fixIESplittedNodes( dragRange, dropRange );
}
// Because we manipulate multiple ranges we need to do it carefully,
@@ -1277,13 +1275,17 @@
// We need to change ranges into bookmarks so we can manipulate them easily in the future.
// We can change the range which is later in the text before we change the preceding range.
// We call rangeBefore to test the order of ranges.
- if ( !rangeBefore( dragRange, dropRange ) )
+ rangeBefore = CKEDITOR.plugins.clipboard.rangeBefore( dragRange, dropRange );
+
+ if ( !rangeBefore ) {
dragBookmark = dragRange.createBookmark( 1 );
+ }
dropBookmark = dropRange.clone().createBookmark( 1 );
- if ( rangeBefore( dragRange, dropRange ) )
+ if ( rangeBefore ) {
dragBookmark = dragRange.createBookmark( 1 );
+ }
// No we can safely delete content for the drag range...
dragRange = editor.createRange();
From 35968525b5ac71af9e6a31bc1c0b8e16fe8cc535 Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Thu, 3 Jul 2014 13:48:13 +0200
Subject: [PATCH 57/67] Replaced CKEDITOR.plugins.clipboard with clipboard or
this.
---
plugins/clipboard/plugin.js | 517 ++++++++++++++++++------------------
1 file changed, 258 insertions(+), 259 deletions(-)
diff --git a/plugins/clipboard/plugin.js b/plugins/clipboard/plugin.js
index 7ac962902ad..cf11cdc9459 100644
--- a/plugins/clipboard/plugin.js
+++ b/plugins/clipboard/plugin.js
@@ -1209,6 +1209,8 @@
}
function initDragDrop( editor ) {
+ var clipboard = CKEDITOR.plugins.clipboard;
+
editor.on( 'contentDom', function() {
var editable = editor.editable(),
// #11123 Firefox needs to listen on document, because otherwise event won't be fired.
@@ -1219,14 +1221,14 @@
// and save range and selected HTML.
editable.attachListener( dropTarget, 'dragstart', function( evt ) {
// Create a dataTransfer object and save it globally.
- CKEDITOR.plugins.clipboard.initDataTransfer( evt, editor );
+ clipboard.initDataTransfer( evt, editor );
} );
// Clean up on dragend.
editable.attachListener( dropTarget, 'dragend', function( evt ) {
// When drag & drop is done we need to reset dataTransfer so the future
// external drop will be not recognize as internal.
- CKEDITOR.plugins.clipboard.resetDataTransfer();
+ clipboard.resetDataTransfer();
} );
editable.attachListener( dropTarget, 'drop', function( evt ) {
@@ -1234,12 +1236,12 @@
evt.data.preventDefault();
// Create dataTransfer of get it, if it was created before.
- var dataTransfer = CKEDITOR.plugins.clipboard.initDataTransfer( evt );
+ var dataTransfer = clipboard.initDataTransfer( evt );
dataTransfer.setTargetEditor( editor );
// Getting drop position is one of the most complex part.
- var dropRange = CKEDITOR.plugins.clipboard.getRangeAtDropPosition( evt, editor ),
- dragRange = CKEDITOR.plugins.clipboard.dragRange;
+ var dropRange = clipboard.getRangeAtDropPosition( evt, editor ),
+ dragRange = clipboard.dragRange;
// Do nothing if it was not possible to get drop range.
if ( !dropRange )
@@ -1267,7 +1269,7 @@
editor.fire( 'lockSnapshot', { dontUpdate: 1 } );
if ( CKEDITOR.env.ie && CKEDITOR.env.version < 10 ) {
- CKEDITOR.plugins.clipboard.fixIESplittedNodes( dragRange, dropRange );
+ clipboard.fixIESplittedNodes( dragRange, dropRange );
}
// Because we manipulate multiple ranges we need to do it carefully,
@@ -1275,14 +1277,11 @@
// We need to change ranges into bookmarks so we can manipulate them easily in the future.
// We can change the range which is later in the text before we change the preceding range.
// We call rangeBefore to test the order of ranges.
- rangeBefore = CKEDITOR.plugins.clipboard.rangeBefore( dragRange, dropRange );
-
+ rangeBefore = clipboard.rangeBefore( dragRange, dropRange );
if ( !rangeBefore ) {
dragBookmark = dragRange.createBookmark( 1 );
}
-
dropBookmark = dropRange.clone().createBookmark( 1 );
-
if ( rangeBefore ) {
dragBookmark = dragRange.createBookmark( 1 );
}
@@ -1359,280 +1358,280 @@
* @singleton
* @class CKEDITOR.plugins.clipboard
*/
- CKEDITOR.plugins.clipboard = {};
+ CKEDITOR.plugins.clipboard = {
+ /**
+ * IE 8 & 9 split text node on drop so the first node contains
+ * text before drop position and the second contains rest. If we
+ * drag the content from the same node we will be not able to get
+ * it (range became invalid), so we need to join them back.
+ *
+ * Notify that first node on IE 8 & 9 is the original node object
+ * but with shortened content.
+ *
+ * Before:
+ * --- Text Node A ----------------------------------
+ * /\
+ * Drag position
+ *
+ * After (IE 8 & 9):
+ * --- Text Node A ----- --- Text Node B -----------
+ * /\ /\
+ * Drop position Drag position
+ * (invalid)
+ *
+ * After (other browsers):
+ * --- Text Node A ----------------------------------
+ * /\ /\
+ * Drop position Drag position
+ *
+ * This function is in the public scope for tests usage only.
+ *
+ * @private
+ */
+ fixIESplittedNodes: 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 ) ) {
+ var nodeBefore = dropRange.startContainer.getChild( dropRange.startOffset - 1 ),
+ nodeAfter = dropRange.startContainer.getChild( dropRange.startOffset ),
+ offset = nodeBefore.getLength();
+
+ if ( nodeAfter ) {
+ nodeBefore.setText( nodeBefore.getText() + nodeAfter.getText() );
+ nodeAfter.remove();
+ }
- /**
- * @private
- *
- * IE 8 & 9 split text node on drop so the first node contains
- * text before drop position and the second contains rest. If we
- * drag the content from the same node we will be not able to get
- * it (range became invalid), so we need to join them back.
- *
- * Notify that first node on IE 8 & 9 is the original node object
- * but with shortened content.
- *
- * Before:
- * --- Text Node A ----------------------------------
- * /\
- * Drag position
- *
- * After (IE 8 & 9):
- * --- Text Node A ----- --- Text Node B -----------
- * /\ /\
- * Drop position Drag position
- * (invalid)
- *
- * After (other browsers):
- * --- Text Node A ----------------------------------
- * /\ /\
- * Drop position Drag position
- *
- * This function is in the public scope for tests usage only.
- */
- CKEDITOR.plugins.clipboard.fixIESplittedNodes = 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 ) ) {
- var nodeBefore = dropRange.startContainer.getChild( dropRange.startOffset - 1 ),
- nodeAfter = dropRange.startContainer.getChild( dropRange.startOffset ),
- 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 );
- }
- };
-
- /**
- * @private
- *
- * Check if the beginning of the firstRange is before the beginning of the secondRange
- * and modification of the content in the firstRange may break secondRange.
- *
- * Notify that this function returns false if these two ranges are in two
- * separate nodes and do not affect each other (even if firstRange is before secondRange).
- *
- * This function is in the public scope for tests usage only.
- */
- CKEDITOR.plugins.clipboard.rangeBefore = function( firstRange, secondRange ) {
- // Both ranges has the same parent and the first has smaller offset. E.g.:
- //
- // "Lorem ipsum dolor sit[1] amet consectetur[2] adipiscing elit."
- // "Lorem ipsum dolor sit" [1] "amet consectetur" [2] "adipiscing elit."
- //
- if ( firstRange.endContainer.equals( secondRange.startContainer ) &&
- firstRange.endOffset < secondRange.startOffset )
- return true;
-
- // First range is inside a text node and the second is not, but if we change the
- // first range into bookmark and split the text node then the seconds node offset
- // will be no longer correct.
- //
- // "Lorem ipsum dolor sit [1] amet" "consectetur" [2] "adipiscing elit."
- //
- if ( firstRange.endContainer.getParent().equals( secondRange.startContainer ) &&
- firstRange.endContainer.getIndex() < secondRange.startOffset )
- return true;
-
- return false;
- };
+ /**
+ * Check if the beginning of the firstRange is before the beginning of the secondRange
+ * and modification of the content in the firstRange may break secondRange.
+ *
+ * Notify that this function returns false if these two ranges are in two
+ * separate nodes and do not affect each other (even if firstRange is before secondRange).
+ *
+ * This function is in the public scope for tests usage only.
+ *
+ * @private
+ */
+ rangeBefore: function( firstRange, secondRange ) {
+ // Both ranges has the same parent and the first has smaller offset. E.g.:
+ //
+ // "Lorem ipsum dolor sit[1] amet consectetur[2] adipiscing elit."
+ // "Lorem ipsum dolor sit" [1] "amet consectetur" [2] "adipiscing elit."
+ //
+ if ( firstRange.endContainer.equals( secondRange.startContainer ) &&
+ firstRange.endOffset < secondRange.startOffset )
+ return true;
- /**
- * Get range from the drop event.
- *
- * Copy of getRangeAtDropPosition method from widget plugin.
- * In #11219 method in widget should be removed and everything be according to DRY.
- *
- * @param {Object} domEvent A native DOM drop event object.
- * @param {CKEDITOR.editor} editor The source editor instance.
- * @returns {CKEDITOR.dom.range} range at drop position.
- *
- */
- CKEDITOR.plugins.clipboard.getRangeAtDropPosition = function( dropEvt, editor ) {
- // If we drop content from the external source we need to call focus on IE.
- if ( CKEDITOR.env.ie ) {
- editor.focus();
- }
+ // First range is inside a text node and the second is not, but if we change the
+ // first range into bookmark and split the text node then the seconds node offset
+ // will be no longer correct.
+ //
+ // "Lorem ipsum dolor sit [1] amet" "consectetur" [2] "adipiscing elit."
+ //
+ if ( firstRange.endContainer.getParent().equals( secondRange.startContainer ) &&
+ firstRange.endContainer.getIndex() < secondRange.startOffset )
+ return true;
- var $evt = dropEvt.data.$,
- x = $evt.clientX,
- y = $evt.clientY,
- $range,
- defaultRange = editor.getSelection( true ).getRanges()[ 0 ],
- range = editor.createRange();
-
- // Make testing possible.
- if ( dropEvt.data.testRange )
- return dropEvt.data.testRange;
-
- // Webkits.
- if ( document.caretRangeFromPoint ) {
- $range = editor.document.$.caretRangeFromPoint( x, y );
- range.setStart( CKEDITOR.dom.node( $range.startContainer ), $range.startOffset );
- range.collapse( true );
- }
- // FF.
- else if ( $evt.rangeParent ) {
- range.setStart( CKEDITOR.dom.node( $evt.rangeParent ), $evt.rangeOffset );
- range.collapse( true );
- }
- // IEs 9+.
- else if ( CKEDITOR.env.ie && CKEDITOR.env.version > 8 )
- // On IE 9+ range by default is where we expected it.
- return defaultRange;
- // IE 8.
- else if ( document.body.createTextRange ) {
- $range = editor.document.getBody().$.createTextRange();
- try {
- var sucess = false;
+ return false;
+ },
- // If user drop between text line IEs moveToPoint throws exception:
- //
- // Lorem ipsum pulvinar purus et euismod
- //
- // dolor sit amet,| consectetur adipiscing
- // *
- // vestibulum tincidunt augue eget tempus.
- //
- // * - drop position
- // | - expected cursor position
- //
- // So we try to call moveToPoint with +-1px up to +-20px above or
- // below original drop position to find nearest good drop position.
- for ( var i = 0; i < 20 && !sucess; i++ ) {
- if ( !sucess ) {
- try {
- $range.moveToPoint( x, y - i );
- sucess = true;
- } catch ( err ) {
- }
- }
- if ( !sucess ) {
- try {
- $range.moveToPoint( x, y + i );
- sucess = true;
- } catch ( err ) {
- }
- }
- }
+ /**
+ * Get range from the drop event.
+ *
+ * Copy of getRangeAtDropPosition method from widget plugin.
+ * In #11219 method in widget should be removed and everything be according to DRY.
+ *
+ * @param {Object} domEvent A native DOM drop event object.
+ * @param {CKEDITOR.editor} editor The source editor instance.
+ * @returns {CKEDITOR.dom.range} range at drop position.
+ *
+ */
+ getRangeAtDropPosition: function( dropEvt, editor ) {
+ // If we drop content from the external source we need to call focus on IE.
+ if ( CKEDITOR.env.ie ) {
+ editor.focus();
+ }
- if ( sucess ) {
- var id = 'cke-temp-' + ( new Date() ).getTime();
- $range.pasteHTML( '\u200b' );
+ var $evt = dropEvt.data.$,
+ x = $evt.clientX,
+ y = $evt.clientY,
+ $range,
+ defaultRange = editor.getSelection( true ).getRanges()[ 0 ],
+ range = editor.createRange();
+
+ // Make testing possible.
+ if ( dropEvt.data.testRange )
+ return dropEvt.data.testRange;
+
+ // Webkits.
+ if ( document.caretRangeFromPoint ) {
+ $range = editor.document.$.caretRangeFromPoint( x, y );
+ range.setStart( CKEDITOR.dom.node( $range.startContainer ), $range.startOffset );
+ range.collapse( true );
+ }
+ // FF.
+ else if ( $evt.rangeParent ) {
+ range.setStart( CKEDITOR.dom.node( $evt.rangeParent ), $evt.rangeOffset );
+ range.collapse( true );
+ }
+ // IEs 9+.
+ else if ( CKEDITOR.env.ie && CKEDITOR.env.version > 8 )
+ // On IE 9+ range by default is where we expected it.
+ return defaultRange;
+ // IE 8.
+ else if ( document.body.createTextRange ) {
+ $range = editor.document.getBody().$.createTextRange();
+ try {
+ var sucess = false;
- var span = editor.document.getById( id );
- range.moveToPosition( span, CKEDITOR.POSITION_BEFORE_START );
- span.remove();
- } else {
- // If the fist method does not succeed we might be next to
- // the short element (like header):
- //
- // Lorem ipsum pulvinar purus et euismod.
- //
- //
- // SOME HEADER| *
+ // If user drop between text line IEs moveToPoint throws exception:
//
+ // Lorem ipsum pulvinar purus et euismod
//
+ // dolor sit amet,| consectetur adipiscing
+ // *
// vestibulum tincidunt augue eget tempus.
//
// * - drop position
// | - expected cursor position
//
- // In such situation elementFromPoint returns proper element. Using getClientRect
- // it is possible to check if the cursor should be at the beginning or at the end
- // of paragraph.
- var $element = editor.document.$.elementFromPoint( x, y ),
- element = new CKEDITOR.dom.element( $element ),
- rect;
-
- if ( !element.equals( editor.editable() ) && element.getName() != 'html' ) {
- rect = element.getClientRect();
-
- if ( x < rect.left ) {
- range.setStartAt( element, CKEDITOR.POSITION_AFTER_START );
- range.collapse( true );
- } else {
- range.setStartAt( element, CKEDITOR.POSITION_BEFORE_END );
- range.collapse( true );
+ // So we try to call moveToPoint with +-1px up to +-20px above or
+ // below original drop position to find nearest good drop position.
+ for ( var i = 0; i < 20 && !sucess; i++ ) {
+ if ( !sucess ) {
+ try {
+ $range.moveToPoint( x, y - i );
+ sucess = true;
+ } catch ( err ) {
+ }
+ }
+ if ( !sucess ) {
+ try {
+ $range.moveToPoint( x, y + i );
+ sucess = true;
+ } catch ( err ) {
+ }
}
}
- // If drop happens on no element elementFromPoint returns html or body.
- //
- // * |Lorem ipsum pulvinar purus et euismod.
- //
- // vestibulum tincidunt augue eget tempus.
- //
- // * - drop position
- // | - expected cursor position
- //
- // In such case we can try to use default selection. If startContainer is not
- // 'editable' element it is probably proper selection.
- else if ( defaultRange && defaultRange.startContainer &&
- !defaultRange.startContainer.equals( editor.editable() ) ) {
- return defaultRange;
- }
- // Otherwise we can not find any drop position and we have to return null
- // and cancel drop event.
- else
- return null;
+ if ( sucess ) {
+ var id = 'cke-temp-' + ( new Date() ).getTime();
+ $range.pasteHTML( '\u200b' );
+
+ var span = editor.document.getById( id );
+ range.moveToPosition( span, CKEDITOR.POSITION_BEFORE_START );
+ span.remove();
+ } else {
+ // If the fist method does not succeed we might be next to
+ // the short element (like header):
+ //
+ // Lorem ipsum pulvinar purus et euismod.
+ //
+ //
+ // SOME HEADER| *
+ //
+ //
+ // vestibulum tincidunt augue eget tempus.
+ //
+ // * - drop position
+ // | - expected cursor position
+ //
+ // In such situation elementFromPoint returns proper element. Using getClientRect
+ // it is possible to check if the cursor should be at the beginning or at the end
+ // of paragraph.
+ var $element = editor.document.$.elementFromPoint( x, y ),
+ element = new CKEDITOR.dom.element( $element ),
+ rect;
+
+ if ( !element.equals( editor.editable() ) && element.getName() != 'html' ) {
+ rect = element.getClientRect();
+
+ if ( x < rect.left ) {
+ range.setStartAt( element, CKEDITOR.POSITION_AFTER_START );
+ range.collapse( true );
+ } else {
+ range.setStartAt( element, CKEDITOR.POSITION_BEFORE_END );
+ range.collapse( true );
+ }
+ }
+ // If drop happens on no element elementFromPoint returns html or body.
+ //
+ // * |Lorem ipsum pulvinar purus et euismod.
+ //
+ // vestibulum tincidunt augue eget tempus.
+ //
+ // * - drop position
+ // | - expected cursor position
+ //
+ // In such case we can try to use default selection. If startContainer is not
+ // 'editable' element it is probably proper selection.
+ else if ( defaultRange && defaultRange.startContainer &&
+ !defaultRange.startContainer.equals( editor.editable() ) ) {
+ return defaultRange;
+ }
+ // Otherwise we can not find any drop position and we have to return null
+ // and cancel drop event.
+ else
+ return null;
+
+ }
+ } catch ( err ) {
+ return null;
}
- } catch ( err ) {
- return null;
}
- }
- else
- return null;
+ else
+ return null;
- return range;
- };
+ return range;
+ },
- /**
- * Initialize dataTransfer object based on the native drop event. If data
- * transfer object was already initialized on this event then function will
- * return that object.
- *
- * @param {Object} domEvent A native DOM drop event object.
- * @param {CKEDITOR.editor} [sourceEditor] The source editor instance.
- * @returns {CKEDITOR.plugins.clipboard.dataTransfer} dataTransfer object
- *
- */
- CKEDITOR.plugins.clipboard.initDataTransfer = function( evt, sourceEditor ) {
- // Create a new dataTransfer object based on the drop event.
- // If this event was used on dragstart to create dataTransfer
- // both dataTransfer objects will have the same id.
- var dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer( evt, sourceEditor );
-
- // If there is the same id we will replace dataTransfer with the one
- // created on drag, because it contains drag editor, drag content and so on.
- // Otherwise (in case of drag from external source) we save new object to
- // the global clipboard.dragData.
- if ( CKEDITOR.plugins.clipboard.dragData &&
- dataTransfer.id == CKEDITOR.plugins.clipboard.dragData.id ) {
- dataTransfer = CKEDITOR.plugins.clipboard.dragData;
- } else {
- CKEDITOR.plugins.clipboard.dragData = dataTransfer;
- }
+ /**
+ * Initialize dataTransfer object based on the native drop event. If data
+ * transfer object was already initialized on this event then function will
+ * return that object.
+ *
+ * @param {Object} domEvent A native DOM drop event object.
+ * @param {CKEDITOR.editor} [sourceEditor] The source editor instance.
+ * @returns {CKEDITOR.plugins.clipboard.dataTransfer} dataTransfer object
+ *
+ */
+ initDataTransfer: function( evt, sourceEditor ) {
+ // Create a new dataTransfer object based on the drop event.
+ // If this event was used on dragstart to create dataTransfer
+ // both dataTransfer objects will have the same id.
+ var dataTransfer = new this.dataTransfer( evt, sourceEditor );
+
+ // If there is the same id we will replace dataTransfer with the one
+ // created on drag, because it contains drag editor, drag content and so on.
+ // Otherwise (in case of drag from external source) we save new object to
+ // the global clipboard.dragData.
+ if ( this.dragData &&
+ dataTransfer.id == this.dragData.id ) {
+ dataTransfer = this.dragData;
+ } else {
+ this.dragData = dataTransfer;
+ }
- if ( sourceEditor ) {
- CKEDITOR.plugins.clipboard.dragRange = sourceEditor.getSelection().getRanges()[ 0 ];
- }
+ if ( sourceEditor ) {
+ this.dragRange = sourceEditor.getSelection().getRanges()[ 0 ];
+ }
- return dataTransfer;
- };
+ return dataTransfer;
+ },
- /*
- * Remove global dataTransfer object so the new dataTransfer
- * will be not linked with the old one.
- */
- CKEDITOR.plugins.clipboard.resetDataTransfer = function() {
- CKEDITOR.plugins.clipboard.dragData = null;
+ /*
+ * Remove global dataTransfer object so the new dataTransfer
+ * will be not linked with the old one.
+ */
+ resetDataTransfer: function() {
+ this.dragData = null;
+ }
};
// Data type used to link drag and drop events.
From 448f9eef111c66b0a32c30b46c9c2dbd08afde9c Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Thu, 3 Jul 2014 13:50:56 +0200
Subject: [PATCH 58/67] Renamed fixIESplittedNodes to fixIESplitNodesAfterDrop.
---
plugins/clipboard/plugin.js | 4 ++--
tests/plugins/clipboard/drop.js | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/plugins/clipboard/plugin.js b/plugins/clipboard/plugin.js
index cf11cdc9459..4242110ad0a 100644
--- a/plugins/clipboard/plugin.js
+++ b/plugins/clipboard/plugin.js
@@ -1269,7 +1269,7 @@
editor.fire( 'lockSnapshot', { dontUpdate: 1 } );
if ( CKEDITOR.env.ie && CKEDITOR.env.version < 10 ) {
- clipboard.fixIESplittedNodes( dragRange, dropRange );
+ clipboard.fixIESplitNodesAfterDrop( dragRange, dropRange );
}
// Because we manipulate multiple ranges we need to do it carefully,
@@ -1388,7 +1388,7 @@
*
* @private
*/
- fixIESplittedNodes: function( dragRange, dropRange ) {
+ fixIESplitNodesAfterDrop: function( dragRange, dropRange ) {
if ( dropRange.startContainer.type == CKEDITOR.NODE_ELEMENT &&
dropRange.startOffset > 0 &&
dropRange.startContainer.getChildCount() > dropRange.startOffset - 1 &&
diff --git a/tests/plugins/clipboard/drop.js b/tests/plugins/clipboard/drop.js
index c18dc70037b..d5432969d86 100644
--- a/tests/plugins/clipboard/drop.js
+++ b/tests/plugins/clipboard/drop.js
@@ -368,7 +368,7 @@ var editors, editorBots,
dropRange.collapse( true );
// Fix nodes.
- CKEDITOR.plugins.clipboard.fixIESplittedNodes( dragRange, dropRange );
+ CKEDITOR.plugins.clipboard.fixIESplitNodesAfterDrop( dragRange, dropRange );
// Asserts.
assert.areSame( 1, p.getChildCount() );
From 84846850b7a14f1039ab09eb1c5733438b5cce82 Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Thu, 3 Jul 2014 14:14:26 +0200
Subject: [PATCH 59/67] Improved docs.
---
plugins/clipboard/plugin.js | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/plugins/clipboard/plugin.js b/plugins/clipboard/plugin.js
index 4242110ad0a..f84ead3aab2 100644
--- a/plugins/clipboard/plugin.js
+++ b/plugins/clipboard/plugin.js
@@ -1387,6 +1387,8 @@
* This function is in the public scope for tests usage only.
*
* @private
+ * @param {CKEDITOR.dom.range} dragRange The drag range.
+ * @param {CKEDITOR.dom.range} dropRange The drop range.
*/
fixIESplitNodesAfterDrop: function( dragRange, dropRange ) {
if ( dropRange.startContainer.type == CKEDITOR.NODE_ELEMENT &&
@@ -1417,6 +1419,9 @@
* This function is in the public scope for tests usage only.
*
* @private
+ * @param {CKEDITOR.dom.range} firstRange The first range to compare.
+ * @param {CKEDITOR.dom.range} secondRange The second range to compare.
+ * @returns {Boolean} True if the first range in before the second range.
*/
rangeBefore: function( firstRange, secondRange ) {
// Both ranges has the same parent and the first has smaller offset. E.g.:
@@ -1450,7 +1455,6 @@
* @param {Object} domEvent A native DOM drop event object.
* @param {CKEDITOR.editor} editor The source editor instance.
* @returns {CKEDITOR.dom.range} range at drop position.
- *
*/
getRangeAtDropPosition: function( dropEvt, editor ) {
// If we drop content from the external source we need to call focus on IE.
@@ -1599,7 +1603,6 @@
* @param {Object} domEvent A native DOM drop event object.
* @param {CKEDITOR.editor} [sourceEditor] The source editor instance.
* @returns {CKEDITOR.plugins.clipboard.dataTransfer} dataTransfer object
- *
*/
initDataTransfer: function( evt, sourceEditor ) {
// Create a new dataTransfer object based on the drop event.
@@ -1632,6 +1635,21 @@
resetDataTransfer: function() {
this.dragData = null;
}
+
+ /**
+ * Global object to save data for drag and drop. Object must be global to handle
+ * drag and drop from one CKEditor to the other.
+ *
+ * @private
+ * @property {CKEDITOR.plugins.clipboard.dataTransfer} dragData
+ */
+
+ /**
+ * Range object to save drag range and remove it after drop.
+ *
+ * @private
+ * @property {CKEDITOR.dom.range} dragRange
+ */
};
// Data type used to link drag and drop events.
From 101066610d9d52535f1c006db8526b081f699b19 Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Thu, 3 Jul 2014 14:17:09 +0200
Subject: [PATCH 60/67] Renamed rangeBefore to isRangeBefore.
---
plugins/clipboard/plugin.js | 12 ++++++------
tests/plugins/clipboard/drop.js | 12 ++++++------
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/plugins/clipboard/plugin.js b/plugins/clipboard/plugin.js
index f84ead3aab2..730ccb03185 100644
--- a/plugins/clipboard/plugin.js
+++ b/plugins/clipboard/plugin.js
@@ -1261,7 +1261,7 @@
// Execute drop with a timeout because otherwise selection, after drop,
// on IE is in the drag position, instead of drop position.
setTimeout( function() {
- var dragBookmark, dropBookmark, i, rangeBefore;
+ var dragBookmark, dropBookmark, i, isRangeBefore;
// Save and lock snapshot so there will be only
// one snapshot for both remove and insert content.
@@ -1276,13 +1276,13 @@
// changing one range (event creating a bookmark) may make other invalid.
// We need to change ranges into bookmarks so we can manipulate them easily in the future.
// We can change the range which is later in the text before we change the preceding range.
- // We call rangeBefore to test the order of ranges.
- rangeBefore = clipboard.rangeBefore( dragRange, dropRange );
- if ( !rangeBefore ) {
+ // We call isRangeBefore to test the order of ranges.
+ isRangeBefore = clipboard.isRangeBefore( dragRange, dropRange );
+ if ( !isRangeBefore ) {
dragBookmark = dragRange.createBookmark( 1 );
}
dropBookmark = dropRange.clone().createBookmark( 1 );
- if ( rangeBefore ) {
+ if ( isRangeBefore ) {
dragBookmark = dragRange.createBookmark( 1 );
}
@@ -1423,7 +1423,7 @@
* @param {CKEDITOR.dom.range} secondRange The second range to compare.
* @returns {Boolean} True if the first range in before the second range.
*/
- rangeBefore: function( firstRange, secondRange ) {
+ isRangeBefore: function( firstRange, secondRange ) {
// Both ranges has the same parent and the first has smaller offset. E.g.:
//
// "Lorem ipsum dolor sit[1] amet consectetur[2] adipiscing elit."
diff --git a/tests/plugins/clipboard/drop.js b/tests/plugins/clipboard/drop.js
index d5432969d86..27a93864fe2 100644
--- a/tests/plugins/clipboard/drop.js
+++ b/tests/plugins/clipboard/drop.js
@@ -378,7 +378,7 @@ var editors, editorBots,
assert.isInnerHtmlMatching( 'lorem^ ipsum sit amet.@
', getWithHtml( editor ), htmlMatchOpts );
},
- 'test rangeBefore 1': function() {
+ 'test isRangeBefore 1': function() {
var editor = editors.framed,
bot = editorBots[ editor.name ],
firstRange = editor.createRange(),
@@ -395,10 +395,10 @@ var editors, editorBots,
secondRange.setStart( p.getChild( 0 ), 11 );
secondRange.collapse( true );
- assert.isTrue( CKEDITOR.plugins.clipboard.rangeBefore( firstRange, secondRange ) );
+ assert.isTrue( CKEDITOR.plugins.clipboard.isRangeBefore( firstRange, secondRange ) );
},
- 'test rangeBefore 2': function() {
+ 'test isRangeBefore 2': function() {
var editor = editors.framed,
bot = editorBots[ editor.name ],
firstRange = editor.createRange(),
@@ -419,10 +419,10 @@ var editors, editorBots,
secondRange.setStart( p, 2 );
secondRange.collapse( true );
- assert.isTrue( CKEDITOR.plugins.clipboard.rangeBefore( firstRange, secondRange ) );
+ assert.isTrue( CKEDITOR.plugins.clipboard.isRangeBefore( firstRange, secondRange ) );
},
- 'test rangeBefore 3': function() {
+ 'test isRangeBefore 3': function() {
var editor = editors.framed,
bot = editorBots[ editor.name ],
firstRange = editor.createRange(),
@@ -441,7 +441,7 @@ var editors, editorBots,
secondRange.setStart( p, 1 );
secondRange.collapse( true );
- assert.isTrue( CKEDITOR.plugins.clipboard.rangeBefore( firstRange, secondRange ) );
+ assert.isTrue( CKEDITOR.plugins.clipboard.isRangeBefore( firstRange, secondRange ) );
}
};
From d72f886fc8a01c3e96ad1020f13822768086195d Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Thu, 3 Jul 2014 14:28:21 +0200
Subject: [PATCH 61/67] Renamed initDataTransfer to initDragDataTransfer and
resetDataTransfer to resetDragDataTransfer.
---
plugins/clipboard/plugin.js | 10 +++++-----
tests/plugins/clipboard/datatransfer.js | 16 ++++++++--------
tests/plugins/clipboard/drop.js | 2 +-
3 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/plugins/clipboard/plugin.js b/plugins/clipboard/plugin.js
index 730ccb03185..b26bd258629 100644
--- a/plugins/clipboard/plugin.js
+++ b/plugins/clipboard/plugin.js
@@ -1221,14 +1221,14 @@
// and save range and selected HTML.
editable.attachListener( dropTarget, 'dragstart', function( evt ) {
// Create a dataTransfer object and save it globally.
- clipboard.initDataTransfer( evt, editor );
+ clipboard.initDragDataTransfer( evt, editor );
} );
// Clean up on dragend.
editable.attachListener( dropTarget, 'dragend', function( evt ) {
// When drag & drop is done we need to reset dataTransfer so the future
// external drop will be not recognize as internal.
- clipboard.resetDataTransfer();
+ clipboard.resetDragDataTransfer();
} );
editable.attachListener( dropTarget, 'drop', function( evt ) {
@@ -1236,7 +1236,7 @@
evt.data.preventDefault();
// Create dataTransfer of get it, if it was created before.
- var dataTransfer = clipboard.initDataTransfer( evt );
+ var dataTransfer = clipboard.initDragDataTransfer( evt );
dataTransfer.setTargetEditor( editor );
// Getting drop position is one of the most complex part.
@@ -1604,7 +1604,7 @@
* @param {CKEDITOR.editor} [sourceEditor] The source editor instance.
* @returns {CKEDITOR.plugins.clipboard.dataTransfer} dataTransfer object
*/
- initDataTransfer: function( evt, sourceEditor ) {
+ initDragDataTransfer: function( evt, sourceEditor ) {
// Create a new dataTransfer object based on the drop event.
// If this event was used on dragstart to create dataTransfer
// both dataTransfer objects will have the same id.
@@ -1632,7 +1632,7 @@
* Remove global dataTransfer object so the new dataTransfer
* will be not linked with the old one.
*/
- resetDataTransfer: function() {
+ resetDragDataTransfer: function() {
this.dragData = null;
}
diff --git a/tests/plugins/clipboard/datatransfer.js b/tests/plugins/clipboard/datatransfer.js
index 04e92b1dcb2..c9ccc90b9a6 100644
--- a/tests/plugins/clipboard/datatransfer.js
+++ b/tests/plugins/clipboard/datatransfer.js
@@ -54,7 +54,7 @@ bender.test( {
},
setUp: function() {
- CKEDITOR.plugins.clipboard.resetDataTransfer();
+ CKEDITOR.plugins.clipboard.resetDragDataTransfer();
},
'test id': function() {
@@ -172,29 +172,29 @@ bender.test( {
},
- 'test initDataTransfer binding': function() {
+ 'test initDragDataTransfer binding': function() {
var evt1 = createDragDropEventMock(),
evt2 = createDragDropEventMock(),
- dataTransferA = CKEDITOR.plugins.clipboard.initDataTransfer( evt1 ),
- dataTransferB = CKEDITOR.plugins.clipboard.initDataTransfer( evt1 );
+ dataTransferA = CKEDITOR.plugins.clipboard.initDragDataTransfer( evt1 ),
+ dataTransferB = CKEDITOR.plugins.clipboard.initDragDataTransfer( evt1 );
assert.areSame( dataTransferA, dataTransferB, 'If we init dataTransfer object twice on the same event this should be the same object.' );
- CKEDITOR.plugins.clipboard.resetDataTransfer();
+ CKEDITOR.plugins.clipboard.resetDragDataTransfer();
- dataTransferB = CKEDITOR.plugins.clipboard.initDataTransfer( evt2 );
+ dataTransferB = CKEDITOR.plugins.clipboard.initDragDataTransfer( evt2 );
assert.areNotSame( dataTransferA, dataTransferB, 'If we init dataTransfer object twice on different events these should be different objects.' );
},
- 'test initDataTransfer constructor': function() {
+ 'test initDragDataTransfer constructor': function() {
var bot = this.bots.editor1,
editor = this.editors.editor1;
bot.setHtmlWithSelection( '[xfoox]' );
var evt = createDragDropEventMock(),
- dataTransfer = CKEDITOR.plugins.clipboard.initDataTransfer( evt, editor );
+ dataTransfer = CKEDITOR.plugins.clipboard.initDragDataTransfer( evt, editor );
dataTransfer.setTargetEditor( editor );
assert.areSame( CKEDITOR.DATA_TRANSFER_INTERNAL, dataTransfer.getTransferType(), 'transferType' );
diff --git a/tests/plugins/clipboard/drop.js b/tests/plugins/clipboard/drop.js
index 27a93864fe2..23e76284bd6 100644
--- a/tests/plugins/clipboard/drop.js
+++ b/tests/plugins/clipboard/drop.js
@@ -115,7 +115,7 @@ var editors, editorBots,
},
testsForMultipleEditor = {
'setUp': function() {
- CKEDITOR.plugins.clipboard.resetDataTransfer();
+ CKEDITOR.plugins.clipboard.resetDragDataTransfer();
},
'test drop to header': function( editor ) {
From 94e76bc0b7bf5ac6d54a2bfd94e24f93cc8f41f6 Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Thu, 3 Jul 2014 14:37:21 +0200
Subject: [PATCH 62/67] Added todos.
---
plugins/clipboard/plugin.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/plugins/clipboard/plugin.js b/plugins/clipboard/plugin.js
index b26bd258629..f4e20b5a635 100644
--- a/plugins/clipboard/plugin.js
+++ b/plugins/clipboard/plugin.js
@@ -1289,7 +1289,7 @@
// No we can safely delete content for the drag range...
dragRange = editor.createRange();
dragRange.moveToBookmark( dragBookmark );
- dragRange.deleteContents();
+ dragRange.deleteContents(); // @todo replace with the new delete content function
// ...and paste content into the drop position.
dropRange = editor.createRange();
@@ -1319,7 +1319,7 @@
// Remove dragged content and make a snapshot.
dataTransfer.sourceEditor.fire( 'saveSnapshot' );
- dragRange.deleteContents();
+ dragRange.deleteContents(); // @todo replace with the new delete content function
dataTransfer.sourceEditor.getSelection().reset();
dataTransfer.sourceEditor.fire( 'saveSnapshot' );
@@ -1338,13 +1338,13 @@
firePasteWithDataTransfer( dataTransfer );
}
+ // @todo integrate with firePasteEvents.
function firePasteWithDataTransfer( dataTransfer ) {
if ( dataTransfer.dataValue ) {
editor.fire( 'paste', dataTransfer );
}
}
-
// Fix for Gecko bug with disappearing cursor.
function fixGeckoDisappearingCursor() {
editor.once( 'afterPaste', function() {
@@ -1713,7 +1713,7 @@
if ( editor ) {
this.sourceEditor = editor;
- this.dataValue = editor.getSelection().getSelectedHtml();
+ this.dataValue = editor.getSelection().getSelectedHtml(); // @todo replace with the new function
this.dataType = 'html';
} else {
// IE support only text data and throws exception if we try to get html data.
From 3f5877fab99b4bedb2694719aa5ddc7d500d8732 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotrek=20Reinmar=20Koszuli=C5=84ski?=
Date: Thu, 3 Jul 2014 15:36:10 +0200
Subject: [PATCH 63/67] JSLint issue.
---
plugins/clipboard/plugin.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/clipboard/plugin.js b/plugins/clipboard/plugin.js
index f4e20b5a635..49d7b4437db 100644
--- a/plugins/clipboard/plugin.js
+++ b/plugins/clipboard/plugin.js
@@ -1681,7 +1681,7 @@
this.id = this.$.getData( clipboardIdDataType );
function generateUniqueId() {
- return ( new Date() ).getTime() + Math.random().toString( 16 ).substring( 2 )
+ return ( new Date() ).getTime() + Math.random().toString( 16 ).substring( 2 );
}
// If there is no ID we need to create it. Different browsers needs different ID.
From a1a04cae7247586d2ccbc12659ca03922f4d76ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotrek=20Reinmar=20Koszuli=C5=84ski?=
Date: Thu, 3 Jul 2014 15:50:24 +0200
Subject: [PATCH 64/67] Fixed minor code style and docs issue.
---
plugins/clipboard/plugin.js | 76 ++++++++++++++++++++++---------------
1 file changed, 45 insertions(+), 31 deletions(-)
diff --git a/plugins/clipboard/plugin.js b/plugins/clipboard/plugin.js
index 49d7b4437db..8b1f6b99ea2 100644
--- a/plugins/clipboard/plugin.js
+++ b/plugins/clipboard/plugin.js
@@ -1368,24 +1368,25 @@
* Notify that first node on IE 8 & 9 is the original node object
* but with shortened content.
*
- * Before:
- * --- Text Node A ----------------------------------
- * /\
- * Drag position
+ * Before:
+ * --- Text Node A ----------------------------------
+ * /\
+ * Drag position
*
- * After (IE 8 & 9):
- * --- Text Node A ----- --- Text Node B -----------
- * /\ /\
- * Drop position Drag position
- * (invalid)
+ * After (IE 8 & 9):
+ * --- Text Node A ----- --- Text Node B -----------
+ * /\ /\
+ * Drop position Drag position
+ * (invalid)
*
- * After (other browsers):
- * --- Text Node A ----------------------------------
- * /\ /\
- * Drop position Drag position
+ * After (other browsers):
+ * --- Text Node A ----------------------------------
+ * /\ /\
+ * Drop position Drag position
*
- * This function is in the public scope for tests usage only.
+ * **Note:** This function is in the public scope for tests usage only.
*
+ * @since 4.5
* @private
* @param {CKEDITOR.dom.range} dragRange The drag range.
* @param {CKEDITOR.dom.range} dropRange The drop range.
@@ -1410,14 +1411,15 @@
},
/**
- * Check if the beginning of the firstRange is before the beginning of the secondRange
- * and modification of the content in the firstRange may break secondRange.
+ * Check if the beginning of the `firstRange` is before the beginning of the `secondRange`
+ * and modification of the content in the `firstRange` may break `secondRange`.
*
- * Notify that this function returns false if these two ranges are in two
- * separate nodes and do not affect each other (even if firstRange is before secondRange).
+ * Notify that this function returns `false` if these two ranges are in two
+ * separate nodes and do not affect each other (even if `firstRange` is before `secondRange`).
*
- * This function is in the public scope for tests usage only.
+ * **Note:** This function is in the public scope for tests usage only.
*
+ * @since 4.5
* @private
* @param {CKEDITOR.dom.range} firstRange The first range to compare.
* @param {CKEDITOR.dom.range} secondRange The second range to compare.
@@ -1447,11 +1449,9 @@
},
/**
- * Get range from the drop event.
- *
- * Copy of getRangeAtDropPosition method from widget plugin.
- * In #11219 method in widget should be removed and everything be according to DRY.
+ * Get range from the `drop` event.
*
+ * @since 4.5
* @param {Object} domEvent A native DOM drop event object.
* @param {CKEDITOR.editor} editor The source editor instance.
* @returns {CKEDITOR.dom.range} range at drop position.
@@ -1600,6 +1600,7 @@
* transfer object was already initialized on this event then function will
* return that object.
*
+ * @since 4.5
* @param {Object} domEvent A native DOM drop event object.
* @param {CKEDITOR.editor} [sourceEditor] The source editor instance.
* @returns {CKEDITOR.plugins.clipboard.dataTransfer} dataTransfer object
@@ -1631,6 +1632,8 @@
/*
* Remove global dataTransfer object so the new dataTransfer
* will be not linked with the old one.
+ *
+ * @since 4.5
*/
resetDragDataTransfer: function() {
this.dragData = null;
@@ -1640,6 +1643,7 @@
* Global object to save data for drag and drop. Object must be global to handle
* drag and drop from one CKEditor to the other.
*
+ * @since 4.5
* @private
* @property {CKEDITOR.plugins.clipboard.dataTransfer} dragData
*/
@@ -1647,6 +1651,7 @@
/**
* Range object to save drag range and remove it after drop.
*
+ * @since 4.5
* @private
* @property {CKEDITOR.dom.range} dragRange
*/
@@ -1668,8 +1673,9 @@
* Facade for the native `dataTransfer`/`clipboadData` object to hide all differences
* between browsers.
*
+ * @since 4.5
* @class CKEDITOR.plugins.clipboard.dataTransfer
- * @constructor Creates a class instance and .
+ * @constructor Creates a class instance.
*
* @param {Object} domEvent A native DOM event object.
* @param {CKEDITOR.editor} editor The source editor instance. If editor is defined then dataValue will be created based on the editor contents and dataType will be 'html'.
@@ -1688,7 +1694,7 @@
if ( !this.id ) {
if ( clipboardIdDataType == 'URL' ) {
// For IEs URL type ID have to look like an URL.
- this.id = 'http://cke.' + generateUniqueId() +'/';
+ this.id = 'http://cke.' + generateUniqueId() + '/';
} else if ( clipboardIdDataType == 'Text' ) {
// For IE10+ only Text data type is supported and we have to compare dragged
// and dropped text. If the ID is not set it means that empty string was dragged
@@ -1721,8 +1727,7 @@
try {
this.dataValue = this.getData( 'text/html' );
this.dataType = 'html';
- } catch ( err ) {
- }
+ } catch ( err ) {}
if ( !this.dataValue ) {
// Try to get text data otherwise.
@@ -1736,17 +1741,19 @@
}
}
}
+
/**
* Data transfer ID used to bind all dataTransfer
* object based on the same event (ex. in drag and drop events).
*
+ * @readonly
* @property {String} id
*/
/**
* A native DOM event object.
*
- * @private
+ * @readonly
* @property {Object} $
*/
@@ -1754,24 +1761,28 @@
* Source editor, the editor where drag starts.
* Might be undefined if drag starts outside the editor (ex. dropping files to the editor).
*
- * @property {CKEDITOR.editor} [sourceEditor]
+ * @readonly
+ * @property {CKEDITOR.editor} sourceEditor
*/
/**
* Target editor, the editor where drop occurred.
*
+ * @readonly
* @property {CKEDITOR.editor} targetEditor
*/
/**
* HTML or text to be pasted.
*
+ * @readonly
* @property {String} dataValue
*/
/**
* Type of data in `data.dataValue`. The value might be `html` or `text`.
*
+ * @readonly
* @property {String} dataType
*/
};
@@ -1780,6 +1791,7 @@
* Data transfer operation (drag and drop or copy and pasted) started and ended in the same
* editor instance.
*
+ * @since 4.5
* @readonly
* @property {Number} [=0]
* @member CKEDITOR
@@ -1790,6 +1802,7 @@
* Data transfer operation (drag and drop or copy and pasted) started and ended in the
* instance of CKEditor but in two different editors.
*
+ * @since 4.5
* @readonly
* @property {Number} [=1]
* @member CKEDITOR
@@ -1800,6 +1813,7 @@
* Data transfer operation (drag and drop or copy and pasted) started not in the CKEditor.
* The source of the data may be textarea, HTML, another application, etc..
*
+ * @since 4.5
* @readonly
* @property {Number} [=2]
* @member CKEDITOR
@@ -1839,8 +1853,8 @@
/**
* Get data transfer type.
*
- * @returns {Number} type
- * Possible options: DATA_TRANSFER_INTERNAL, DATA_TRANSFER_CROSS_EDITORS, DATA_TRANSFER_EXTERNAL.
+ * @returns {Number} Possible values: {@link CKEDITOR#DATA_TRANSFER_INTERNAL},
+ * {@link CKEDITOR#DATA_TRANSFER_CROSS_EDITORS}, {@link CKEDITOR#DATA_TRANSFER_EXTERNAL}.
*/
getTransferType: function() {
if ( !this.sourceEditor ) {
From 7be5499cc4292abdb7383ae9d4697a77d5497f2f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotrek=20Reinmar=20Koszuli=C5=84ski?=
Date: Thu, 3 Jul 2014 16:09:58 +0200
Subject: [PATCH 65/67] Tests: Order of things matters - fixed test failing on
IE9.
---
tests/plugins/clipboard/drop.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/plugins/clipboard/drop.js b/tests/plugins/clipboard/drop.js
index 23e76284bd6..3f45a2723ce 100644
--- a/tests/plugins/clipboard/drop.js
+++ b/tests/plugins/clipboard/drop.js
@@ -302,8 +302,8 @@ var editors, editorBots,
var bot = editorBots[ editor.name ],
evt = createDragDropEventMock();
- editor.resetUndo();
bot.setHtmlWithSelection( 'Lorem ^ipsum sit amet.
' );
+ editor.resetUndo();
drop( editor, evt, {
element: editor.document.getById( 'p' ).getChild( 0 ),
From 285231656e2e4624225168cbf9cb9d0870072a3e Mon Sep 17 00:00:00 2001
From: Piotr Jasiun
Date: Thu, 3 Jul 2014 16:10:42 +0200
Subject: [PATCH 66/67] Fixed drop to the textarea on Safari.
---
plugins/clipboard/plugin.js | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/plugins/clipboard/plugin.js b/plugins/clipboard/plugin.js
index 8b1f6b99ea2..29d4232eef1 100644
--- a/plugins/clipboard/plugin.js
+++ b/plugins/clipboard/plugin.js
@@ -1712,15 +1712,16 @@
this.$.setData( clipboardIdDataType, this.id );
}
- // Without setData( 'text', ... ) on dragstart there is no drop event in Safari.
- if ( evt.name == 'dragstart' && CKEDITOR.env.safari ) {
- evt.data.$.dataTransfer.setData( 'text', evt.data.$.dataTransfer.getData( 'text' ) );
- }
-
if ( editor ) {
this.sourceEditor = editor;
this.dataValue = editor.getSelection().getSelectedHtml(); // @todo replace with the new function
this.dataType = 'html';
+
+ // Without setData( 'text', ... ) on dragstart there is no drop event in Safari.
+ // Also 'text' data is empty as drop to the textarea does not work if we do not put there text.
+ if ( evt.name == 'dragstart' && CKEDITOR.env.safari ) {
+ evt.data.$.dataTransfer.setData( 'text', editor.getSelection().getSelectedText() );
+ }
} else {
// IE support only text data and throws exception if we try to get html data.
// This html data object may also be empty if we drag content of the textarea.
From 4c944961dd23fe13194b24a81abb64ee8bb99dbe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotrek=20Reinmar=20Koszuli=C5=84ski?=
Date: Thu, 3 Jul 2014 16:25:56 +0200
Subject: [PATCH 67/67] Tests: And making some selection matters too - this
fixed test failing on IE9 for real.
---
tests/plugins/clipboard/drop.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/plugins/clipboard/drop.js b/tests/plugins/clipboard/drop.js
index 3f45a2723ce..4b7d54a798b 100644
--- a/tests/plugins/clipboard/drop.js
+++ b/tests/plugins/clipboard/drop.js
@@ -320,7 +320,7 @@ var editors, editorBots,
botCross = editorBots[ 'cross' ],
editorCross = botCross.editor;
- setWithHtml( bot.editor, 'Lorem ipsum sit amet.
' );
+ setWithHtml( bot.editor, '{}Lorem ipsum sit amet.
' );
setWithHtml( botCross.editor, 'Lorem {ipsum dolor }sit amet.
' );
bot.editor.resetUndo();
botCross.editor.resetUndo();