+ fixListAfterContentsDelete = ( function() {
+ // Creates an element walker which operates only within lists.
+ function getFixListSelectionWalker( testRange ) {
+ var walker = new CKEDITOR.dom.walker( testRange );
+ walker.guard = function( node, isMovingOut ) {
+ if ( isMovingOut )
+ return false;
+ if ( node.type == CKEDITOR.NODE_ELEMENT )
+ return node.is( CKEDITOR.dtd.$list ) || node.is( CKEDITOR.dtd.$listItem );
+ };
+ walker.evaluator = function( node ) {
+ return node.type == CKEDITOR.NODE_ELEMENT && node.is( CKEDITOR.dtd.$listItem );
+ };
+
+ return walker;
+ }
+
+ return function( range ) {
+ var container = range.startContainer,
+ appendToStart = false,
+ testRange,
+ deeperSibling;
+
+ // Look left.
+ testRange = range.clone();
+ testRange.setStart( container, 0 );
+ deeperSibling = getFixListSelectionWalker( testRange ).lastBackward();
+
+ // If left is empty, look right.
+ if ( !deeperSibling ) {
+ testRange = range.clone();
+ testRange.setEndAt( container, CKEDITOR.POSITION_BEFORE_END );
+ deeperSibling = getFixListSelectionWalker( testRange ).lastForward();
+ appendToStart = true;
+ }
+
+ // If there's no deeper nested element in both direction - container is empty - we'll use it then.
+ if ( !deeperSibling )
+ deeperSibling = container;
+
+ // We found a list what means that it's empty - remove it completely.
+ if ( deeperSibling.is( CKEDITOR.dtd.$list ) ) {
+ range.setStartAt( deeperSibling, CKEDITOR.POSITION_BEFORE_START );
+ range.collapse( true );
+ deeperSibling.remove();
+ return;
+ }
+
+ // To avoid setting selection after bogus, remove it from the target list item.
+ // We can safely do that, because we'll insert element into that cell.
+ var bogus = deeperSibling.getBogus();
+ if ( bogus )
+ bogus.remove();
+
+ range.moveToPosition( deeperSibling, appendToStart ? CKEDITOR.POSITION_AFTER_START : CKEDITOR.POSITION_BEFORE_END );
+ range.select();
+ };
+ } )();
+