Changeset 7540


Ignore:
Timestamp:
07/05/12 12:18:57 (2 years ago)
Author:
garry.yao
Message:

#9080: Fixed backspace key behavior at the start of list item, to join with previous line.

Location:
CKEditor/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • CKEditor/trunk/CHANGES.html

    r7538 r7540  
    7777                <li><a href="http://dev.ckeditor.com/ticket/6217">#6217</a> : Handled DEL/BACKSPACE key at the boundary of table to unifiy the cursor position.</li> 
    7878                <li><a href="http://dev.ckeditor.com/ticket/8950">#8950</a> : Chagend the cursor position after calling editor::insertElement on block element.</li> 
     79                <li><a href="http://dev.ckeditor.com/ticket/9080">#9080</a> : Fixed Backspace key in front of the list item to join with previous line.</li> 
    7980        </ul> 
    8081        <h3> 
  • CKEditor/trunk/_source/core/dom/walker.js

    r7538 r7540  
    456456                return function( node ) 
    457457                { 
    458                         var parent = node.getParent(), 
    459                                 isBogus = !CKEDITOR.env.ie ? node.is && node.is( 'br' ) : 
     458                        var isBogus = !CKEDITOR.env.ie ? node.is && node.is( 'br' ) : 
    460459                                          node.getText && tailNbspRegex.test( node.getText() ); 
    461460 
    462                         isBogus = isBogus && parent.isBlockBoundary() && !!parent.getLast( nonEmpty ); 
     461                        if ( isBogus ) 
     462                        { 
     463                                var parent = node.getParent(), next = node.getNext( nonEmpty ); 
     464                                isBogus = parent.isBlockBoundary() && 
     465                                          ( !next || 
     466                                            next.type == CKEDITOR.NODE_ELEMENT && 
     467                                            next.isBlockBoundary() ); 
     468                        } 
    463469 
    464470                        return !! ( isReject ^ isBogus ); 
  • CKEditor/trunk/_source/plugins/indent/plugin.js

    r7522 r7540  
    429429                                } 
    430430                        }); 
    431  
    432                         editor.on( 'key', function( evt ) 
    433                         { 
    434                                 // Backspace at the beginning of  list item should outdent it. 
    435                                 if ( editor.mode == 'wysiwyg' && evt.data.keyCode == 8 ) 
    436                                 { 
    437                                         var sel = editor.getSelection(), 
    438                                                 range = sel.getRanges()[ 0 ], 
    439                                                 li; 
    440  
    441                                         if ( range.collapsed && 
    442                                                  ( li = range.startContainer.getAscendant( 'li', 1 ) ) && 
    443                                                  range.checkBoundaryOfElement( li, CKEDITOR.START ) ) 
    444                                         { 
    445                                                 editor.execCommand( 'outdent' ); 
    446                                                 evt.cancel(); 
    447                                         } 
    448                                 } 
    449                         }); 
    450431                }, 
    451432 
  • CKEditor/trunk/_source/plugins/list/plugin.js

    r7535 r7540  
    682682                        // For all new lists created, merge into adjacent, same type lists. 
    683683                        for ( i = 0 ; i < listsCreated.length ; i++ ) 
    684                         { 
    685                                 listNode = listsCreated[i]; 
    686                                 var mergeSibling, listCommand = this; 
    687                                 ( mergeSibling = function( rtl ) 
    688                                 { 
    689                                         var sibling = listNode[ rtl ? 'getPrevious' : 'getNext' ]( nonEmpty ); 
    690                                         if ( sibling && sibling.getName && 
    691                                                  sibling.getName() == listCommand.type ) 
    692                                         { 
    693                                                 // Move children order by merge direction.(#3820) 
    694                                                 mergeChildren( listNode, sibling, null, !rtl ); 
    695  
    696                                                 listNode.remove(); 
    697                                                 listNode = sibling; 
    698                                         } 
    699                                 } )(); 
    700                                 mergeSibling( 1 ); 
    701                         } 
     684                                mergeListSiblings( listsCreated[ i ] ); 
    702685 
    703686                        // Clean up, restore selection and update toolbar button states. 
     
    707690                } 
    708691        }; 
     692 
     693        // Merge list adjacent, of same type lists. 
     694        function mergeListSiblings( listNode ) 
     695        { 
     696                var mergeSibling; 
     697                ( mergeSibling = function( rtl ) 
     698                { 
     699                        var sibling = listNode[ rtl ? 'getPrevious' : 'getNext' ]( nonEmpty ); 
     700                        if ( sibling && sibling.is( listNode.getName() ) ) 
     701                        { 
     702                                // Move children order by merge direction.(#3820) 
     703                                mergeChildren( listNode, sibling, null, !rtl ); 
     704 
     705                                listNode.remove(); 
     706                                listNode = sibling; 
     707                        } 
     708                } )(); 
     709                mergeSibling( 1 ); 
     710        } 
    709711 
    710712        var dtd = CKEDITOR.dtd; 
     
    789791 
    790792                cursor.trim( false, true ); 
     793                var bm = cursor.createBookmark(); 
    791794 
    792795                // Kill original bogus; 
     
    830833                } 
    831834 
    832  
    833                 if ( nextCursor.checkStartOfBlock() && 
     835                // Remove any remaining empty path blocks. 
     836                while ( nextCursor.checkStartOfBlock() && 
    834837                         nextCursor.checkEndOfBlock() ) 
    835838                { 
    836                         var nextBlock = nextPath.block, 
    837                                 parentBlock = nextBlock.getParent(); 
    838  
     839                        nextPath = new CKEDITOR.dom.elementPath( nextCursor.startContainer ); 
     840                        var nextBlock = nextPath.block; 
     841 
     842                        nextCursor.moveToPosition( nextBlock, CKEDITOR.POSITION_BEFORE_START ); 
    839843                        nextBlock.remove(); 
    840  
    841                         // Remove if the path block container is now empty, e.g. li. 
    842                         if ( parentBlock && 
    843                                  !parentBlock.getFirst( nonEmpty ) && 
    844                                  !parentBlock.equals( nextPath.blockLimit ) ) 
    845                         { 
    846                                 parentBlock.remove(); 
    847                         } 
    848                 } 
     844                } 
     845 
     846                // Check if need to further merge with the list resides after the merged block. (#9080) 
     847                var walkerRng = nextCursor.clone(), body = editor.document.getBody(); 
     848                walkerRng.setEndAt( body, CKEDITOR.POSITION_BEFORE_END ); 
     849                var walker = new CKEDITOR.dom.walker( walkerRng ); 
     850                walker.evaluator = function( node ) { return nonEmpty( node ) && !blockBogus( node ); }; 
     851                var next = walker.next(); 
     852                if ( next && next.type == CKEDITOR.NODE_ELEMENT && next.getName() in CKEDITOR.dtd.$list ) 
     853                        mergeListSiblings( next ); 
     854 
     855                cursor.moveToBookmark( bm ); 
    849856 
    850857                // Make fresh selection. 
    851858                cursor.select(); 
    852859 
     860                editor.selectionChange( 1 ); 
    853861                editor.fire( 'saveSnapshot' ); 
    854862        } 
     
    884892                        editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, bulletedListCommand ) ); 
    885893 
    886                         // [IE8] Fix "backspace" after list and "del" at the end of list item. (#8248) 
    887                         if ( CKEDITOR.env.ie8Compat ) 
    888                         { 
     894                                // Handled backspace/del key to join list items. (#8248,#9080) 
    889895                                editor.on( 'key', function( evt ) 
    890896                                { 
     
    909915                                                if ( isBackspace ) 
    910916                                                { 
    911                                                         walker.range.setStartAt( body, CKEDITOR.POSITION_AFTER_START ); 
    912                                                         walker.range.setEnd( range.startContainer, range.startOffset ); 
    913  
    914                                                         var previous = walker.previous(); 
    915  
    916                                                         // Check if cursor collapsed right behind of a list. 
    917                                                         if ( previous && 
    918                                                                  previous.type == CKEDITOR.NODE_ELEMENT && 
    919                                                                  previous.getName() in listNodeNames ) 
     917                                                        var previous, joinWith; 
     918 
     919                                                        var path = new CKEDITOR.dom.elementPath( range.startContainer ); 
     920 
     921                                                        // Join a sub list's first line, with the previous visual line in parent. 
     922                                                        if ( ( previous = path.contains( listNodeNames ) ) && 
     923                                                             range.checkBoundaryOfElement( previous, CKEDITOR.START ) && 
     924                                                             ( previous = previous.getParent() ) && previous.is( 'li' ) && 
     925                                                             ( previous = getSubList( previous ) ) ) 
    920926                                                        { 
    921                                                                 walker.range.selectNodeContents( previous ); 
    922                                                                 walker.reset(); 
    923                                                                 walker.evaluator = isTextBlock; 
    924  
    925                                                                 // Place cursor at the end of previous block. 
    926                                                                 cursor.moveToElementEditEnd( walker.lastForward() ); 
     927                                                                joinWith = previous; 
     928                                                                previous = previous.getPrevious( nonEmpty ); 
     929                                                                // Place cursor before the nested list. 
     930                                                                cursor.moveToPosition( 
     931                                                                        previous && blockBogus( previous ) ? previous : joinWith, 
     932                                                                        CKEDITOR.POSITION_BEFORE_START ); 
     933                                                        } 
     934                                                        // Join any line following a list, with the last visual line of the list. 
     935                                                        else 
     936                                                        { 
     937                                                                walker.range.setStartAt( body, CKEDITOR.POSITION_AFTER_START ); 
     938                                                                walker.range.setEnd( range.startContainer, range.startOffset ); 
     939                                                                previous = walker.previous(); 
     940 
     941                                                                if ( previous && previous.type == CKEDITOR.NODE_ELEMENT && 
     942                                                                   ( previous.getName() in listNodeNames || previous.is( 'li' ) ) ) 
     943                                                                { 
     944                                                                        if ( !previous.is( 'li' ) ) 
     945                                                                        { 
     946                                                                                walker.range.selectNodeContents( previous ); 
     947                                                                                walker.reset(); 
     948                                                                                walker.evaluator = isTextBlock; 
     949                                                                                previous = walker.previous(); 
     950                                                                        } 
     951 
     952                                                                        joinWith = previous; 
     953                                                                        // Place cursor at the end of previous block. 
     954                                                                        cursor.moveToElementEditEnd( joinWith ); 
     955                                                                } 
     956                                                        } 
     957 
     958                                                        if ( joinWith ) 
     959                                                        { 
    927960                                                                joinNextLineToCursor( editor, cursor, range ); 
    928961                                                                evt.cancel(); 
     
    9701003                                                        } 
    9711004                                                } 
     1005 
     1006                                                // The backspace/del could potentially put cursor at a bad position, 
     1007                                                // being it handled or not, check immediately the selection to have it fixed. 
     1008                                                setTimeout( function() { editor.selectionChange( 1 ); } ); 
    9721009                                        } 
    9731010                                } ); 
    974                         } 
    9751011                }, 
    9761012 
  • CKEditor/trunk/_source/plugins/selection/plugin.js

    r7521 r7540  
    590590                                }); 
    591591 
    592                         editor.selectionChange = checkSelectionChangeTimeout; 
     592                        /** 
     593                         * Check if to fire the {@link CKEDITOR.editor#selectionChange} event 
     594                         * for the current editor instance. 
     595                         * 
     596                         * @param {Boolean} checkNow Check immediately without any delay. 
     597                         */ 
     598                        editor.selectionChange = function( checkNow ) 
     599                        { 
     600                                ( checkNow ? checkSelectionChange : checkSelectionChangeTimeout ).call( this ); 
     601                        }; 
    593602 
    594603                        // IE9 might cease to work if there's an object selection inside the iframe (#7639). 
Note: See TracChangeset for help on using the changeset viewer.
© 2003 – 2012 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy