Skip to content

Commit 8af211e

Browse files
committed
Merge branch 't/11083' into major
2 parents ca5b94a + 26a9b87 commit 8af211e

File tree

7 files changed

+80
-15
lines changed

7 files changed

+80
-15
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Fixed Issues:
4747
* [#10430](http://dev.ckeditor.com/ticket/10430): Resolve dependence of image plugin if forms plugin.
4848
* [#10911](http://dev.ckeditor.com/ticket/10911): Browser alt hotkeys will no longer be blocked while widget is focused.
4949
* [#11082](http://dev.ckeditor.com/ticket/11082): Selected widget is not copied/cut when using toolbar buttons or context menu.
50+
* [#11083](http://dev.ckeditor.com/ticket/11083): Fixed lists and divs application to block widgets.
5051

5152
## CKEditor 4.3 Beta
5253

core/dom/elementpath.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@
6464
if ( !this.lastElement ) {
6565
this.lastElement = e;
6666

67-
// If a table is fully selected at the end of the element path,
67+
// If an object or non-editable element is fully selected at the end of the element path,
6868
// it must not become the block limit.
69-
if ( e.is( CKEDITOR.dtd.$object ) )
69+
if ( e.is( CKEDITOR.dtd.$object ) || e.getAttribute( 'contenteditable' ) == 'false' )
7070
continue;
7171
}
7272

core/editable.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,6 @@
818818
// Returns truly value when dom was changed, falsy otherwise.
819819
function fixDom( evt ) {
820820
var editor = evt.editor,
821-
editable = editor.editable(),
822821
path = evt.data.path,
823822
blockLimit = path.blockLimit,
824823
selection = evt.data.selection,
@@ -838,7 +837,10 @@
838837

839838
// When we're in block enter mode, a new paragraph will be established
840839
// to encapsulate inline contents inside editable. (#3657)
841-
if ( shouldAutoParagraph( editor, path.block, blockLimit ) && range.collapsed ) {
840+
// Don't autoparagraph if browser (namely - IE) incorrectly anchored selection
841+
// inside non-editable content. This happens e.g. if non-editable block is the only
842+
// content of editable.
843+
if ( shouldAutoParagraph( editor, path.block, blockLimit ) && range.collapsed && !range.getCommonAncestor().isReadOnly() ) {
842844
var testRng = range.clone();
843845
testRng.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS );
844846
var walker = new CKEDITOR.dom.walker( testRng );

plugins/div/dialogs/div.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@
5454
function getDivContainer( element ) {
5555
var container = editor.elementPath( element ).blockLimit;
5656

57+
// Never consider read-only (i.e. contenteditable=false) element as
58+
// a first div limit (#11083).
59+
if ( container.isReadOnly() )
60+
container = container.getParent();
61+
5762
// Dont stop at 'td' and 'th' when div should wrap entire table.
5863
if ( editor.config.div_wrapTable && container.is( [ 'td', 'th' ] ) ) {
5964
var parentPath = editor.elementPath( container.getParent() );
@@ -120,7 +125,7 @@
120125
iterator = ranges[ i ].createIterator();
121126
while ( ( block = iterator.getNextParagraph() ) ) {
122127
// include contents of blockLimit elements.
123-
if ( block.getName() in divLimitDefinition ) {
128+
if ( block.getName() in divLimitDefinition && !block.isReadOnly() ) {
124129
var j,
125130
childNodes = block.getChildren();
126131
for ( j = 0; j < childNodes.count(); j++ )

plugins/div/plugin.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,10 @@
120120
CKEDITOR.plugins.div = {
121121
getSurroundDiv: function( editor, start ) {
122122
var path = editor.elementPath( start );
123-
return editor.elementPath( path.blockLimit ).contains( 'div', 1 );
123+
return editor.elementPath( path.blockLimit ).contains( function( node ) {
124+
// Avoid read-only (i.e. contenteditable="false") divs (#11083).
125+
return node.is( 'div' ) && !node.isReadOnly();
126+
}, 1 );
124127
}
125128
};
126129
})();

plugins/list/plugin.js

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -164,33 +164,74 @@
164164
var needsBlock = currentListItem.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT && ( paragraphMode != CKEDITOR.ENTER_BR || dirLoose || style || className );
165165

166166
var child,
167-
count = item.contents.length;
167+
count = item.contents.length,
168+
cachedBookmark;
169+
168170
for ( i = 0; i < count; i++ ) {
169171
child = item.contents[ i ];
170172

171-
if ( child.type == CKEDITOR.NODE_ELEMENT && child.isBlockBoundary() ) {
173+
// Append bookmark if we can, or cache it and append it when we'll know
174+
// what to do with it. Generally - we want to keep it next to its original neighbour.
175+
// Exception: if bookmark is the only child it hasn't got any neighbour, so handle it normally
176+
// (wrap with block if needed).
177+
if ( bookmarks( child ) && count > 1 ) {
178+
// If we don't need block, it's simple - append bookmark directly to the current list item.
179+
if ( !needsBlock )
180+
currentListItem.append( child.clone( 1, 1 ) );
181+
else
182+
cachedBookmark = child.clone( 1, 1 );
183+
}
184+
// Block content goes directly to the current list item, without wrapping.
185+
else if ( child.type == CKEDITOR.NODE_ELEMENT && child.isBlockBoundary() ) {
172186
// Apply direction on content blocks.
173187
if ( dirLoose && !child.getDirection() )
174188
child.setAttribute( 'dir', orgDir );
175189

176190
inheirtInlineStyles( li, child );
177191

178192
className && child.addClass( className );
179-
} else if ( needsBlock ) {
193+
194+
// Close the block which we started for inline content.
195+
block = null;
196+
// Append bookmark directly before current child.
197+
if ( cachedBookmark ) {
198+
currentListItem.append( cachedBookmark );
199+
cachedBookmark = null;
200+
}
201+
// Append this block element to the list item.
202+
currentListItem.append( child.clone( 1, 1 ) );
203+
}
204+
// Some inline content was found - wrap it with block and append that
205+
// block to the current list item or append it to the block previously created.
206+
else if ( needsBlock ) {
180207
// Establish new block to hold text direction and styles.
181208
if ( !block ) {
182209
block = doc.createElement( paragraphName );
210+
currentListItem.append( block );
183211
dirLoose && block.setAttribute( 'dir', orgDir );
184212
}
185213

186214
// Copy over styles to new block;
187215
style && block.setAttribute( 'style', style );
188216
className && block.setAttribute( 'class', className );
189217

218+
// Append bookmark directly before current child.
219+
if ( cachedBookmark ) {
220+
block.append( cachedBookmark );
221+
cachedBookmark = null;
222+
}
190223
block.append( child.clone( 1, 1 ) );
191224
}
225+
// E.g. BR mode - inline content appended directly to the list item.
226+
else
227+
currentListItem.append( child.clone( 1, 1 ) );
228+
}
192229

193-
currentListItem.append( block || child.clone( 1, 1 ) );
230+
// No content after bookmark - append it to the block if we had one
231+
// or directly to the current list item if we finished directly in the current list item.
232+
if ( cachedBookmark ) {
233+
( block || currentListItem ).append( cachedBookmark );
234+
cachedBookmark = null;
194235
}
195236

196237
if ( currentListItem.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT && currentIndex != listArray.length - 1 ) {
@@ -295,8 +336,6 @@
295336
editor.fire( 'contentDomInvalidated' );
296337
}
297338

298-
var headerTagRegex = /^h[1-6]$/;
299-
300339
function createList( editor, groupObj, listsCreated ) {
301340
var contents = groupObj.contents,
302341
doc = groupObj.root.getDocument(),
@@ -366,8 +405,9 @@
366405
contentBlock = listContents.shift();
367406
listItem = doc.createElement( 'li' );
368407

369-
// Preserve preformat block and heading structure when converting to list item. (#5335) (#5271)
370-
if ( contentBlock.is( 'pre' ) || headerTagRegex.test( contentBlock.getName() ) )
408+
// If current block should be preserved, append it to list item instead of
409+
// transforming it to <li> element.
410+
if ( shouldPreserveBlock( contentBlock ) )
371411
contentBlock.appendTo( listItem );
372412
else {
373413
contentBlock.copyAttributes( listItem );
@@ -449,6 +489,20 @@
449489
editor.fire( 'contentDomInvalidated' );
450490
}
451491

492+
var headerTagRegex = /^h[1-6]$/;
493+
494+
// Checks wheather this block should be element preserved (not transformed to <li>) when creating list.
495+
function shouldPreserveBlock( block ) {
496+
return (
497+
// #5335
498+
block.is( 'pre' ) ||
499+
// #5271 - this is a header.
500+
headerTagRegex.test( block.getName() ) ||
501+
// 11083 - this is a non-editable element.
502+
block.getAttribute( 'contenteditable' ) == 'false'
503+
);
504+
}
505+
452506
function listCommand( name, type ) {
453507
this.name = name;
454508
this.type = type;

plugins/widget/plugin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
'cursor:move;' +
5959
'width:' + DRAG_HANDLER_SIZE + 'px;' +
6060
'height:' + DRAG_HANDLER_SIZE + 'px;' +
61-
'display:block' +
61+
'display:inline-block' +
6262
'}' +
6363
'.cke_widget_mask{' +
6464
'position:absolute;' +

0 commit comments

Comments
 (0)