Index: _source/plugins/selection/plugin.js IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- _source/plugins/selection/plugin.js (revision 7585) +++ _source/plugins/selection/plugin.js (revision ) @@ -81,7 +81,13 @@ function singletonBlock( node ) { var body = range.document.getBody(); - return !node.is( 'body' ) && body.getChildCount() == 1; + + if ( node.isBlockBoundary() && + range.checkBoundaryOfElement( body, CKEDITOR.START ) && + range.checkBoundaryOfElement( body, CKEDITOR.END ) ) + { + return true; + } } var start = range.startContainer, Index: _source/plugins/wysiwygarea/plugin.js IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- _source/plugins/wysiwygarea/plugin.js (revision 7584) +++ _source/plugins/wysiwygarea/plugin.js (revision ) @@ -767,9 +767,9 @@ domDocument.getDocumentElement().addClass( domDocument.$.compatMode ); // Override keystroke behaviors. - editable && domDocument.on( 'keydown', function( evt ) + editor.on( 'key', function( evt ) { - var keyCode = evt.data.getKeystroke(); + var keyCode = evt.data.keyCode; // Backspace OR Delete. if ( keyCode in { 8 : 1, 46 : 1 } ) @@ -799,9 +799,9 @@ editor.fire( 'saveSnapshot' ); - evt.data.preventDefault(); + evt.cancel(); } - else + else if ( range.collapsed ) { // Handle the following special cases: (#6217) // 1. Del/Backspace key before/after table; @@ -823,7 +823,7 @@ editor.fire( 'saveSnapshot' ); - evt.data.preventDefault(); + evt.cancel(); } else if ( path.blockLimit.is( 'td' ) && ( parent = path.blockLimit.getAscendant( 'table' ) ) && @@ -843,7 +843,7 @@ editor.fire( 'saveSnapshot' ); - evt.data.preventDefault(); + evt.cancel(); } } @@ -865,7 +865,7 @@ range = new CKEDITOR.dom.range( domDocument ); range[ keyCode == 33 ? 'moveToElementEditStart' : 'moveToElementEditEnd']( body ); range.select(); - evt.data.preventDefault(); + evt.cancel(); } } Index: _source/plugins/list/plugin.js IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- _source/plugins/list/plugin.js (revision 7584) +++ _source/plugins/list/plugin.js (revision ) @@ -784,7 +784,7 @@ CKEDITOR.dtd[ node.getName() ][ '#' ]; } - // Merge the visual line content at the cursor range into the block. + // Join visually two block lines. function joinNextLineToCursor( editor, cursor, nextCursor ) { editor.fire( 'saveSnapshot' ); @@ -798,7 +798,7 @@ // Kill original bogus; var currentPath = new CKEDITOR.dom.elementPath( cursor.startContainer ); - var currentLi = currentPath.lastElement.getAscendant( 'li', 1 ); + var currentBlock = currentPath.lastElement.getAscendant( 'li', 1 ) || currentPath.block; var bogus = currentPath.block.getBogus(); bogus && bogus.remove(); @@ -815,8 +815,8 @@ else cursor.startContainer.append( frag ); - var nextPath = new CKEDITOR.dom.elementPath( nextCursor.startContainer ); - var nextLi = nextCursor.startContainer.getAscendant( 'li', 1 ); + var nextPath = new CKEDITOR.dom.elementPath( nextCursor.startContainer ), + nextLi = nextCursor.startContainer.getAscendant( 'li', 1 ); // Move the sub list nested in the next list item. if ( nextLi ) @@ -825,14 +825,14 @@ if ( sublist ) { // If next line is in the sub list of the current list item. - if ( currentLi.contains( nextLi ) ) + if ( currentBlock.contains( nextLi ) ) { mergeChildren( sublist, nextLi.getParent(), nextLi ); sublist.remove(); } // Migrate the sub list to current list item. else - currentLi.append( sublist ); + currentBlock.append( sublist ); } } @@ -918,10 +918,12 @@ if ( !range.collapsed ) return; + var path = new CKEDITOR.dom.elementPath( range.startContainer ); var isBackspace = key == 8; var body = editor.document.getBody(); var walker = new CKEDITOR.dom.walker( range.clone() ); walker.evaluator = function( node ) { return nonEmpty( node ) && !blockBogus( node ); }; + walker.guard = function( node, isOut ) { return !( isOut && node.type == CKEDITOR.NODE_ELEMENT && node.is( 'table' ) ) }; var cursor = range.clone(); @@ -929,8 +931,6 @@ { var previous, joinWith; - var path = new CKEDITOR.dom.elementPath( range.startContainer ); - // Join a sub list's first line, with the previous visual line in parent. if ( ( previous = path.contains( listNodeNames ) ) && range.checkBoundaryOfElement( previous, CKEDITOR.START ) && @@ -973,10 +973,44 @@ joinNextLineToCursor( editor, cursor, range ); evt.cancel(); } + else + { + var list = path.contains( listNodeNames ), li; + // Backspace pressed at the start of list outdents the first list item. (#9129) + if ( list && range.checkBoundaryOfElement( list, CKEDITOR.START ) ) + { + li = list.getFirst( nonEmpty ); + + if ( range.checkBoundaryOfElement( li, CKEDITOR.START ) ) + { + previous = list.getPrevious( nonEmpty ); + + // Only if the list item contains a sub list, do nothing but + // simply move cursor backward one character. + if ( getSubList( li ) ) + { + if ( previous ) { + range.moveToElementEditEnd( previous ); + range.select(); - } + } + + evt.cancel(); + } - else - { + else + { - var li = range.startContainer.getAscendant( 'li', 1 ); + editor.execCommand( 'outdent' ); + evt.cancel(); + } + } + } + } + } + else + { + var next, + nextLine, + li = range.startContainer.getAscendant( 'li', 1 ); + if ( li ) { walker.range.setEndAt( body, CKEDITOR.POSITION_BEFORE_END ); @@ -1007,11 +1041,46 @@ if ( isAtEnd && next ) { // Put cursor range there. - var nextLine = range.clone(); + nextLine = range.clone(); nextLine.moveToElementEditStart( next ); joinNextLineToCursor( editor, cursor, nextLine ); evt.cancel(); + } + } + else + { + // Handle Del key pressed before the list. + walker.range.setEndAt( body, CKEDITOR.POSITION_BEFORE_END ); + next = walker.next(); + + if ( next && next.type == CKEDITOR.NODE_ELEMENT && + next.getName() in listNodeNames ) + { + // The start