Skip to content

Commit 541f71b

Browse files
committed
Merge branch 't/12006' into major
2 parents a9afb8d + 84d8423 commit 541f71b

File tree

7 files changed

+167
-34
lines changed

7 files changed

+167
-34
lines changed

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ CKEditor 4 Changelog
33

44
## CKEditor 4.5
55

6+
* [#12006](http://dev.ckeditor.com/ticket/12006): [Nested widgets] Drag and drop of nested block widgets.
7+
68
## CKEditor 4.4.2
79

810
Fixed Issues:

plugins/widget/plugin.js

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2275,11 +2275,26 @@
22752275
if ( !el.is( CKEDITOR.dtd.$block ) )
22762276
return;
22772277

2278-
while ( el ) {
2279-
if ( isDomNestedEditable( el ) )
2278+
// Allow drop line inside, but never before or after nested editable (#12006).
2279+
if ( isDomNestedEditable( el ) )
2280+
return;
2281+
2282+
// If element is nested editable, make sure widget can be dropped there (#12006).
2283+
var nestedEditable = getNestedEditable( editable, el );
2284+
if ( nestedEditable ) {
2285+
var draggedWidget = widgetsRepo._.draggedWidget;
2286+
2287+
// Don't let the widget to be dropped into its own nested editable.
2288+
if ( widgetsRepo.getByElement( nestedEditable ) == draggedWidget )
22802289
return;
22812290

2282-
el = el.getParent();
2291+
var filter = CKEDITOR.filter.instances[ nestedEditable.data( 'cke-filter' ) ],
2292+
draggedRequiredContent = draggedWidget.requiredContent;
2293+
2294+
// There will be no relation if the filter of nested editable does not allow
2295+
// requiredContent of dragged widget.
2296+
if ( filter && draggedRequiredContent && !filter.check( draggedRequiredContent ) )
2297+
return;
22832298
}
22842299

22852300
return CKEDITOR.LINEUTILS_BEFORE | CKEDITOR.LINEUTILS_AFTER;
@@ -2952,10 +2967,13 @@
29522967
editor = this.editor,
29532968
editable = editor.editable(),
29542969
listeners = [],
2955-
sorted = [],
2970+
sorted = [];
2971+
2972+
// Mark dragged widget for repository#finder.
2973+
this.repository._.draggedWidget = this;
29562974

2957-
// Harvest all possible relations and display some closest.
2958-
relations = finder.greedySearch(),
2975+
// Harvest all possible relations and display some closest.
2976+
var relations = finder.greedySearch(),
29592977

29602978
buffer = CKEDITOR.tools.eventsBuffer( 50, function() {
29612979
locations = locator.locate( relations );
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
var lineutilsTestsTools = ( function() {
2+
'use strict';
3+
4+
return {
5+
/**
6+
* Asserts relations created by CKEDITOR.plugins.lineutils#finder method.
7+
*
8+
* @param {CKEDITOR.editor} editor Editor instance.
9+
* @param {CKEDITOR.plugins.lineutils.finder} finder Finder instance after search (when finder#relations is present).
10+
* @param {String} expected Expected HTML with relations marked by "|".
11+
*/
12+
assertRelations: function( editor, finder, expected ) {
13+
var current, range,
14+
ranges = [],
15+
relations = finder.relations;
16+
17+
for ( var r in relations ) {
18+
current = relations[ r ];
19+
20+
if ( current.type & CKEDITOR.LINEUTILS_BEFORE )
21+
ranges.push( finder.getRange( { uid: r, type: CKEDITOR.LINEUTILS_BEFORE } ) );
22+
23+
if ( current.type & CKEDITOR.LINEUTILS_AFTER )
24+
ranges.push( finder.getRange( { uid: r, type: CKEDITOR.LINEUTILS_AFTER } ) );
25+
26+
if ( current.type & CKEDITOR.LINEUTILS_INSIDE )
27+
ranges.push( finder.getRange( { uid: r, type: CKEDITOR.LINEUTILS_INSIDE } ) );
28+
29+
while ( ( range = ranges.pop() ) )
30+
range.insertNode( new CKEDITOR.dom.comment( 'R' ) );
31+
}
32+
33+
assert.areSame( expected, editor.getData().replace( /<!--R-->/gi, '|' ), 'Relations discovered, collected and normalized correctly.' );
34+
}
35+
};
36+
} )();

tests/plugins/lineutils/finder.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<head>
2+
<script src="_helpers/tools.js"></script>
3+
</head>
4+
<body>
5+
6+
</body>

tests/plugins/lineutils/finder.js

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
var finder,
88
lookupEls1 = [],
9-
lookupEls2 = [];
9+
lookupEls2 = [],
10+
assertRelations = lineutilsTestsTools.assertRelations;
1011

1112
bender.editor = {
1213
config: {
@@ -68,29 +69,6 @@
6869
}
6970
}
7071

71-
function assertRelations( editor, expected, relations ) {
72-
var current, range,
73-
ranges = [];
74-
75-
for ( var r in relations ) {
76-
current = relations[ r ];
77-
78-
if ( current.type & CKEDITOR.LINEUTILS_BEFORE )
79-
ranges.push( finder.getRange( { uid: r, type: CKEDITOR.LINEUTILS_BEFORE } ) );
80-
81-
if ( current.type & CKEDITOR.LINEUTILS_AFTER )
82-
ranges.push( finder.getRange( { uid: r, type: CKEDITOR.LINEUTILS_AFTER } ) );
83-
84-
if ( current.type & CKEDITOR.LINEUTILS_INSIDE )
85-
ranges.push( finder.getRange( { uid: r, type: CKEDITOR.LINEUTILS_INSIDE } ) );
86-
87-
while ( ( range = ranges.pop() ) )
88-
range.insertNode( editor.document.createText( '|' ) );
89-
}
90-
91-
assert.areSame( expected, editor.getData(), 'Relations discovered, collected and normalized correctly.' );
92-
}
93-
9472
function assertLookupElements( elements, msg, sort ) {
9573
arrayAssert.itemsAreSame( elements, sort ? lookupEls1.sort() : lookupEls1, 'Lookup #1: ' + msg );
9674
arrayAssert.itemsAreSame( elements, sort ? lookupEls2.sort() : lookupEls2, 'Lookup #2: ' + msg );
@@ -133,7 +111,7 @@
133111
return doc.getById( 'x' );
134112
},
135113
assert: function( editor ) {
136-
assertRelations( editor, '<p>a</p>|<div>|b|<p>|y|<span id="x">|x</span>|c</p>|d</div>|<p>e</p>', finder.relations );
114+
assertRelations( editor, finder, '<p>a</p>|<div>|b|<p>|y|<span id="x">|x</span>|c</p>|d</div>|<p>e</p>' );
137115
}
138116
} ),
139117

@@ -143,7 +121,7 @@
143121
return doc.getById( 'x' );
144122
},
145123
assert: function( editor ) {
146-
assertRelations( editor, '<p>a</p>|<div>|<p>|<span id="x">|x</span>|</p>|</div>|<p>b</p>', finder.relations );
124+
assertRelations( editor, finder, '<p>a</p>|<div>|<p>|<span id="x">|x</span>|</p>|</div>|<p>b</p>' );
147125
}
148126
} ),
149127

@@ -153,7 +131,7 @@
153131
return doc.getById( 'x' );
154132
},
155133
assert: function( editor ) {
156-
assertRelations( editor, '|<div contenteditable="true">|<p id="x">|x</p>|</div>|', finder.relations );
134+
assertRelations( editor, finder, '|<div contenteditable="true">|<p id="x">|x</p>|</div>|' );
157135
}
158136
} ),
159137

tests/plugins/widget/dnd.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<head>
22
<script src="_helpers/tools.js"></script>
3+
<script src="../lineutils/_helpers/tools.js"></script>
34
</head>
45
<body>
56

tests/plugins/widget/dnd.js

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,37 @@
1212
evt.editor.dataProcessor.writer.sortAttributes = 1;
1313

1414
evt.editor.widgets.add( 'testwidget', {} );
15+
16+
evt.editor.widgets.add( 'testwidget2', {
17+
editables: {
18+
n1: {
19+
selector: '.n1',
20+
allowedContent: 'p;blockquote(testwidget3)'
21+
},
22+
n2: {
23+
selector: '.n2',
24+
allowedContent: 'p;blockquote'
25+
}
26+
}
27+
} );
28+
29+
evt.editor.widgets.add( 'testwidget3', {
30+
requiredContent: 'blockquote(testwidget3)'
31+
} );
32+
33+
evt.editor.widgets.add( 'testwidget4', {
34+
editables: {
35+
n1: '.n1'
36+
}
37+
} );
1538
}
1639
}
1740
}
1841
};
1942

2043
var fixHtml = widgetTestsTools.fixHtml,
21-
getWidgetById = widgetTestsTools.getWidgetById;
44+
getWidgetById = widgetTestsTools.getWidgetById,
45+
assertRelations = lineutilsTestsTools.assertRelations;
2246

2347
function dropEvent( data, range ) {
2448
var evt = new CKEDITOR.dom.event( {
@@ -369,6 +393,74 @@
369393
revert();
370394
}
371395
} );
396+
},
397+
398+
'test drag and drop - block widget into nested editable (ACF)': function() {
399+
var editor = this.editor,
400+
html = '<div data-widget="testwidget2">' +
401+
'<div class="n1">' +
402+
'<p>x</p>' +
403+
'</div>' +
404+
'<div class="n2">' +
405+
'<p>y</p>' +
406+
'</div>' +
407+
'</div>' +
408+
'<blockquote data-widget="testwidget3" class="testwidget3" id="w3">testwidget3</blockquote>';
409+
410+
this.editorBot.setData( html, function() {
411+
var widget = getWidgetById( editor, 'w3' ),
412+
repo = editor.widgets,
413+
finder = repo.finder;
414+
415+
// Detach dragged widget from DOM to make assertion simpler.
416+
widget.wrapper.remove();
417+
repo._.draggedWidget = widget;
418+
finder.greedySearch();
419+
420+
assertRelations( editor, finder, '|<div data-widget="testwidget2"><div class="n1">|<p>x</p>|</div><div class="n2"><p>y</p></div></div>|' );
421+
} );
422+
},
423+
424+
'test drag and drop - block widget into nested editable (ACF) - no filter': function() {
425+
var editor = this.editor,
426+
html = '<div data-widget="testwidget4">' +
427+
'<div class="n1">' +
428+
'<p>x</p>' +
429+
'</div>' +
430+
'</div>' +
431+
'<blockquote data-widget="testwidget3" class="testwidget3" id="w3">testwidget3</blockquote>';
432+
433+
this.editorBot.setData( html, function() {
434+
var widget = getWidgetById( editor, 'w3' ),
435+
repo = editor.widgets,
436+
finder = repo.finder;
437+
438+
// Detach dragged widget from DOM to make assertion simpler.
439+
widget.wrapper.remove();
440+
repo._.draggedWidget = widget;
441+
finder.greedySearch();
442+
443+
assertRelations( editor, finder, '|<div data-widget="testwidget4"><div class="n1">|<p>x</p>|</div></div>|' );
444+
} );
445+
},
446+
447+
'test drag and drop - block widget into nested editable (ACF) - self-drop': function() {
448+
var editor = this.editor,
449+
html = '<div data-widget="testwidget4" id="w4">' +
450+
'<div class="n1">' +
451+
'<p>x</p>' +
452+
'</div>' +
453+
'</div>';
454+
455+
this.editorBot.setData( html, function() {
456+
var repo = editor.widgets,
457+
finder = repo.finder;
458+
459+
repo._.draggedWidget = getWidgetById( editor, 'w4' );
460+
finder.greedySearch();
461+
462+
assertRelations( editor, finder, '|<div data-widget="testwidget4" id="w4"><div class="n1"><p>x</p></div></div>|' );
463+
} );
372464
}
373465
} );
374466
} )();

0 commit comments

Comments
 (0)