Index: _source/plugins/list/plugin.js
===================================================================
--- _source/plugins/list/plugin.js (revision 6093)
+++ _source/plugins/list/plugin.js (working copy)
@@ -694,6 +694,131 @@
// Register the state changing handlers.
editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, numberedListCommand ) );
editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, bulletedListCommand ) );
+
+ // Registering keydown delete/backspace key handling logic.
+ editor.on( 'contentDom', function()
+ {
+ editor.document.on( 'keydown', function( evt )
+ {
+ var keyCode = evt.data.getKeystroke();
+
+ // Backspace or Delete.
+ if ( keyCode in { 8 : 1, 46 : 1 } )
+ {
+ var range = editor.getSelection().getRanges()[ 0 ],
+ block = new CKEDITOR.dom.elementPath( range.startContainer ).block,
+ li;
+
+ if ( range.collapsed && ( li = block.getAscendant( 'li', true ) ) )
+ {
+ // Backspace
+ if ( keyCode == 8 && range.checkStartOfBlock() )
+ {
+ var previous, list, sublist;
+
+ if (
+ // Previous element is item of the same list.
+ ( ( previous = li.getPrevious() ) && previous.is( 'li' ) ) ||
+ // Previous element is item of the parent list.
+ ( ( list = li.getParent() ) && list.is( 'ol', 'ul' ) && ( previous = list.getParent() ) && previous.is( 'li' ) )
+ )
+ {
+ // If next list item of li also contains list, remove it and add aggain later.
+ var sublist = li.getFirst( function( node ){ return node.is && node.is( 'ol', 'ul' ); } );
+ sublist && sublist.remove();
+ list && list.remove();
+
+ // In Gecko, the last child node is
.
+ if ( CKEDITOR.env.gecko )
+ {
+ li.getLast() && li.getLast().is && li.getLast().is( 'br' ) && li.getLast().remove();
+ previous.getLast() && previous.getLast().is && previous.getLast().is( 'br' ) && previous.getLast().remove();
+ }
+
+ // If current list item or next list item contains block element
+ //
...
+ var innerLi = li.getFirst() && li.getFirst().type == CKEDITOR.NODE_ELEMENT ? li.getFirst() : li;
+ var innerPrevious = previous.getFirst() && previous.getFirst().type == CKEDITOR.NODE_ELEMENT ? previous.getFirst() : previous;
+
+ range.moveToElementEditEnd( innerPrevious );
+ innerLi.moveChildren( innerPrevious );
+ li.remove();
+
+ list && sublist && sublist.getChildCount() && sublist.moveChildren( list, true );
+ list && list.getChildCount() && previous.append( list );
+
+ range.select();
+ evt.data.preventDefault();
+ }
+ }
+ // Delete
+ else if ( keyCode == 46 )
+ {
+ var sublist = li.getFirst( function( node ){ return node.is && node.is( 'ol', 'ul' ); } );
+
+ // Check if cursor (range) is set in the end of current list item.
+ // If list item doesn't contain any sublist we can use range::checkEndOfBlock() function.
+ // If list item contains sublist, we have to use walker to find if the next element is sublist.
+ if ( !range.checkEndOfBlock() )
+ {
+ if ( sublist )
+ {
+ var walkerRange = range.clone();
+ walkerRange.setEndAt( sublist, CKEDITOR.POSITION_AFTER_START );
+
+ var walker = new CKEDITOR.dom.walker( walkerRange );
+ walker.evaluator = function( node )
+ {
+ if ( CKEDITOR.env.gecko && node.is && node.is( 'br' ) && node.getNext().is && node.getNext().is( 'ul' ) )
+ return false;
+ }
+
+ if ( !walker.next().equals( sublist ) )
+ return;
+ }
+ else
+ return;
+ }
+
+ // Get next list item.
+ var next = sublist ?
+ sublist.getFirst( function( node ) { return node.is( 'li' ) } ) :
+ li.getNext();
+
+ if ( !next )
+ return;
+
+ // If next list item from sublist also contains list, remove it and add aggain later.
+ var nextSublist = sublist && next.getFirst( function( node ){ return node.is && node.is( 'ol', 'ul' ); } );
+ nextSublist && nextSublist.remove();
+ sublist && sublist.remove();
+
+ // In Gecko, the last child node is
.
+ if ( CKEDITOR.env.gecko )
+ {
+ li.getLast() && li.getLast().is && li.getLast().is( 'br' ) && li.getLast().remove();
+ next.getLast() && next.getLast().is && next.getLast().is( 'br' ) && next.getLast().remove();
+ }
+
+ // If current list item or next list item contains block element
+ // ...
+ var innerLi = ( li.getChildCount() == 1 && li.getChild(0).type == CKEDITOR.NODE_ELEMENT ) ? li.getChild(0) : li;
+ var innerNext = ( next.getChildCount() == 1 && next.getChild(0).type == CKEDITOR.NODE_ELEMENT ) ? next.getChild(0) : next;
+
+ range.moveToElementEditEnd( innerLi );
+ innerNext.moveChildren( innerLi );
+ next.remove();
+
+ sublist && nextSublist && nextSublist.getChildCount() && nextSublist.moveChildren( sublist, true );
+ sublist && sublist.getChildCount() && li.append( sublist );
+
+ range.select();
+ evt.data.preventDefault();
+ }
+ }
+ }
+ });
+ });
},
afterInit : function ( editor )