Skip to content

Commit 8a5e226

Browse files
committed
Merge branch 't/13884'
2 parents 30d620e + 3ec1185 commit 8a5e226

File tree

7 files changed

+266
-1
lines changed

7 files changed

+266
-1
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CKEditor 4 Changelog
88
* [#13377](http://dev.ckeditor.com/ticket/13377): [Widget](http://ckeditor.com/addon/widget) plugin issue when typing in Korean.
99
* [#13389](http://dev.ckeditor.com/ticket/13389): [Blink] [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) fails when the cursor is next to an `<hr>` tag.
1010
* [#13513](http://dev.ckeditor.com/ticket/13513): [Blink, WebKit] [Div Editing Area](http://ckeditor.com/addon/divarea) and [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) throw an error when an image is the only data in the editor.
11+
* [#13884](http://dev.ckeditor.com/ticket/13884): Fixed: Copy/paste table in Firefox results in just first cell being pasted.
1112

1213
## CKEditor 4.5.6
1314

core/editor.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,47 @@
654654
return editor.blockless ? CKEDITOR.ENTER_BR : enterMode;
655655
}
656656

657+
// Create DocumentFragment from specified ranges. For now it handles only tables in Firefox
658+
// and returns DocumentFragment from the 1. range for other cases. (#13884)
659+
function createDocumentFragmentFromRanges( ranges, editable ) {
660+
var docFragment = new CKEDITOR.dom.documentFragment(),
661+
tableClone,
662+
currentRow,
663+
currentRowClone;
664+
665+
for ( var i = 0; i < ranges.length; i++ ) {
666+
var range = ranges[ i ],
667+
container = range.startContainer;
668+
669+
if ( container.getName && container.getName() == 'tr' ) {
670+
if ( !tableClone ) {
671+
tableClone = container.getAscendant( 'table' ).clone();
672+
tableClone.append( container.getAscendant( 'tbody' ).clone() );
673+
docFragment.append( tableClone );
674+
tableClone = tableClone.findOne( 'tbody' );
675+
}
676+
677+
if ( !( currentRow && currentRow.equals( container ) ) ) {
678+
currentRow = container;
679+
currentRowClone = container.clone();
680+
tableClone.append( currentRowClone );
681+
}
682+
683+
currentRowClone.append( range.cloneContents() );
684+
} else {
685+
// If there was something else copied with table,
686+
// append it to DocumentFragment.
687+
docFragment.append( range.cloneContents() );
688+
}
689+
}
690+
691+
if ( !tableClone ) {
692+
return editable.getHtmlFromRange( ranges[ 0 ] );
693+
}
694+
695+
return docFragment;
696+
}
697+
657698
CKEDITOR.tools.extend( CKEDITOR.editor.prototype, {
658699
/**
659700
* Adds a command definition to the editor instance. Commands added with
@@ -1133,7 +1174,7 @@
11331174
return null;
11341175
}
11351176

1136-
var docFragment = editable.getHtmlFromRange( ranges[ 0 ] );
1177+
var docFragment = createDocumentFragmentFromRanges( ranges, editable );
11371178

11381179
return toString ? docFragment.getHtml() : docFragment;
11391180
},

tests/core/editor/getextractselectedhtml.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,90 @@ bender.test( {
126126
assert.isNull( selectedHtml, 'There should be no error but null should be returns if selection contains no ranges' );
127127
},
128128

129+
// #13884.
130+
'test getSelectedHtml with multiple ranges': function() {
131+
if ( CKEDITOR.env.ie ) {
132+
assert.ignore();
133+
}
134+
135+
var editor = this.editors.editor,
136+
input = '<p>' +
137+
'<table>' +
138+
'<tr>' +
139+
'<td>11</td>' +
140+
'<td>22</td>' +
141+
'</tr>' +
142+
'<tr>' +
143+
'<td>44</td>' +
144+
'<td>55</td>' +
145+
'</tr>' +
146+
'</table>' +
147+
'</p>',
148+
sel = editor.getSelection(),
149+
ranges = [],
150+
tableCells,
151+
curRange,
152+
i;
153+
154+
bender.tools.selection.setWithHtml( editor, input );
155+
156+
// Find cells in the first row.
157+
tableCells = editor.editable().find( 'tr:first-child td' );
158+
159+
for ( i = 0; i < tableCells.count(); i++ ) {
160+
curRange = editor.createRange();
161+
curRange.setStartBefore( tableCells.getItem( i ) );
162+
curRange.setEndAfter( tableCells.getItem( i ) );
163+
ranges.push( curRange );
164+
}
165+
166+
sel.selectRanges( ranges );
167+
168+
assert.isInnerHtmlMatching( '<table><tbody><tr><td>11@</td><td>22</td></tr></tbody></table>', editor.getSelectedHtml( true ) );
169+
},
170+
171+
// #13884.
172+
'test getSelectedHtml with partial table selection': function() {
173+
if ( !CKEDITOR.env.gecko ) {
174+
assert.ignore();
175+
}
176+
177+
var editor = this.editors.editor,
178+
input = '<p>' +
179+
'<table>' +
180+
'<tr>' +
181+
'<td>11</td>' +
182+
'<td>22</td>' +
183+
'</tr>' +
184+
'<tr>' +
185+
'<td>44</td>' +
186+
'<td>55</td>' +
187+
'</tr>' +
188+
'</table>' +
189+
'</p>',
190+
sel = editor.getSelection(),
191+
ranges = [],
192+
tableCells,
193+
curRange,
194+
i;
195+
196+
bender.tools.selection.setWithHtml( editor, input );
197+
198+
// Find first cells in rows.
199+
tableCells = editor.editable().find( 'tr td:first-child' );
200+
201+
for ( i = 0; i < tableCells.count(); i++ ) {
202+
curRange = editor.createRange();
203+
curRange.setStartBefore( tableCells.getItem( i ) );
204+
curRange.setEndAfter( tableCells.getItem( i ) );
205+
ranges.push( curRange );
206+
}
207+
208+
sel.selectRanges( ranges );
209+
210+
assert.isInnerHtmlMatching( '<table><tbody><tr><td>11@</td></tr><tr><td>44</td></tr></tbody></table>', editor.getSelectedHtml( true ) );
211+
},
212+
129213
'test extractSelectedHtml with removeEmptyBlock': function() {
130214
var editor = this.editors.editor;
131215
bender.tools.selection.setWithHtml( editor, '<p>{foo}</p><p>bar</p>' );
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<h2>Classic editor</h2>
2+
<div id="editor1">
3+
<table border="1">
4+
<tr>
5+
<td>11</td>
6+
<td>22</td>
7+
<td>33</td>
8+
</tr>
9+
<tr>
10+
<td>44</td>
11+
<td>55</td>
12+
<td>66</td>
13+
</tr>
14+
</table>
15+
<p>Paste stuff: </p>
16+
</div>
17+
18+
<h2>Inline editor</h2>
19+
<div id="editor2" contenteditable="true">
20+
<table border="1">
21+
<tr>
22+
<td>11</td>
23+
<td>22</td>
24+
<td>33</td>
25+
</tr>
26+
<tr>
27+
<td>44</td>
28+
<td>55</td>
29+
<td>66</td>
30+
</tr>
31+
</table>
32+
<p>Paste stuff: </p>
33+
</div>
34+
35+
<script>
36+
var editor1 = CKEDITOR.replace( 'editor1' );
37+
var editor2 = CKEDITOR.inline( 'editor2' );
38+
</script>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
@bender-tags: clipboard, tc, 4.5.7, 13884
2+
@bender-ui: collapsed
3+
@bender-ckeditor-plugins: clipboard, wysiwygarea, toolbar, sourcearea, sourcedialog, floatingspace, elementspath, table
4+
5+
## First row copy
6+
7+
1. Select three cells in the first row.
8+
2. Copy using `CTRL + C`.
9+
3. Paste in any other place of the editor.
10+
11+
### Expected
12+
13+
Table with three cells and one row is created (pasted).
14+
15+
----
16+
17+
## Partial multi ranges (Firefox only)
18+
19+
1. Make a 2x2 cells selection - that's 4 cells including 11, 22, 44, 55 cells, so that you end with a square selection.
20+
2. Copy using `CTRL + C`.
21+
3. Paste in any other place of the editor.
22+
23+
### Expected
24+
25+
Pasted table has 2 rows with 2 cells in each row resulting with following HTML:
26+
27+
```
28+
<table border="1">
29+
<tbody>
30+
<tr>
31+
<td>11</td>
32+
<td>22</td>
33+
</tr>
34+
<tr>
35+
<td>44</td>
36+
<td>55</td>
37+
</tr>
38+
</tbody>
39+
</table>
40+
```
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<h2>Classic editor</h2>
2+
<div id="editor1">
3+
<table border="1" cellpadding="1" cellspacing="1" style="width:500px">
4+
<tbody>
5+
<tr>
6+
<td style="background-color: rgb(102, 102, 204);">s</td>
7+
<td>s</td>
8+
</tr>
9+
<tr>
10+
<td>s</td>
11+
<td style="background-color: rgb(255, 255, 0);">s</td>
12+
</tr>
13+
<tr>
14+
<td style="background-color: rgb(255, 204, 0);">s</td>
15+
<td style="background-color: rgb(255, 204, 0);">s</td>
16+
</tr>
17+
</tbody>
18+
</table>
19+
20+
<p>Paste here:</p>
21+
</div>
22+
23+
<h2>Inline editor</h2>
24+
<div id="editor2" contenteditable="true">
25+
<table border="1" cellpadding="1" cellspacing="1" style="width:500px">
26+
<tbody>
27+
<tr>
28+
<td style="background-color: rgb(102, 102, 204);">s</td>
29+
<td>s</td>
30+
</tr>
31+
<tr>
32+
<td>s</td>
33+
<td style="background-color: rgb(255, 255, 0);">s</td>
34+
</tr>
35+
<tr>
36+
<td style="background-color: rgb(255, 204, 0);">s</td>
37+
<td style="background-color: rgb(255, 204, 0);">s</td>
38+
</tr>
39+
</tbody>
40+
</table>
41+
42+
<p>Paste here:</p>
43+
</div>
44+
45+
<script>
46+
CKEDITOR.replace( 'editor1' );
47+
CKEDITOR.inline( 'editor2' );
48+
</script>
49+
</body>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@bender-tags: tc, editor, 13884, 4.5.7
2+
@bender-ui: collapsed
3+
@bender-ckeditor-plugins: clipboard, table, tabletools, floatingspace, toolbar, sourcearea, sourcedialog, elementspath, wysiwygarea
4+
5+
----
6+
7+
1. Select whole table with a mouse and Press `CTRL+C` (You can also use Copy from context menu)
8+
2. Press `CTRL+V` or right-click after "Paste here:" and select Paste (`CTRL+V` into paste dialog and click OK)
9+
10+
**Expected:** The whole table is pasted properly.
11+
12+
**Unexpected:** Only first cell is pasted.

0 commit comments

Comments
 (0)