Changeset 7540


Ignore:
Timestamp:
07/05/2012 12:18:57 PM (3 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