| | 742 | // Check if node is block element that recieves text. |
| | 743 | function isTextBlock( node ) |
| | 744 | { |
| | 745 | return node.type == CKEDITOR.NODE_ELEMENT && |
| | 746 | ( node.getName() in CKEDITOR.dtd.$block || |
| | 747 | node.getName() in CKEDITOR.dtd.$listItem ) && |
| | 748 | CKEDITOR.dtd[ node.getName() ][ '#' ]; |
| | 749 | } |
| | 750 | |
| | 751 | // Merge the visual line content at the cursor range into the block. |
| | 752 | function joinCursorLineToBlock( block, cursor ) |
| | 753 | { |
| | 754 | // Place cursor at the end of previous block. |
| | 755 | var newCursor = new CKEDITOR.dom.range( cursor.document ); |
| | 756 | newCursor.moveToElementEditEnd( block ); |
| | 757 | |
| | 758 | // Merge with previous block's content. |
| | 759 | cursor.enlarge( CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ); |
| | 760 | var frag = cursor.extractContents(); |
| | 761 | |
| | 762 | // Kill the tail br in extracted. |
| | 763 | var last = frag.getLast(); |
| | 764 | if ( last && last.type == CKEDITOR.NODE_ELEMENT && |
| | 765 | last.is( 'br' ) ) |
| | 766 | last.remove(); |
| | 767 | |
| | 768 | // Kill original bogus; |
| | 769 | var bogus = block.getBogus(); |
| | 770 | bogus && bogus.remove(); |
| | 771 | |
| | 772 | block.append( frag ); |
| | 773 | |
| | 774 | // Remove the original path block if needed. |
| | 775 | if ( cursor.checkStartOfBlock() && |
| | 776 | cursor.checkEndOfBlock() ) |
| | 777 | { |
| | 778 | var path = new CKEDITOR.dom.elementPath( cursor.startContainer ); |
| | 779 | path.block.remove(); |
| | 780 | } |
| | 781 | |
| | 782 | // Make fresh selection. |
| | 783 | newCursor.select(); |
| | 784 | |
| | 785 | } |
| | 786 | |
| | 810 | |
| | 811 | // [IE8] Fix "backspace" after list and "del" at the end of list item. (#8248) |
| | 812 | if ( CKEDITOR.env.ie8Compat ) |
| | 813 | { |
| | 814 | editor.on( 'key', function( evt ) |
| | 815 | { |
| | 816 | var key = evt.data.keyCode; |
| | 817 | |
| | 818 | // DEl/BACKSPACE |
| | 819 | if ( editor.mode == 'wysiwyg' && key in { 8 : 1, 46 : 1 } ) |
| | 820 | { |
| | 821 | var sel = editor.getSelection(), |
| | 822 | range = sel.getRanges()[ 0 ]; |
| | 823 | |
| | 824 | if ( !range.collapsed ) |
| | 825 | return; |
| | 826 | |
| | 827 | var isBackspace = key == 8; |
| | 828 | var body = editor.document.getBody(); |
| | 829 | var walker = new CKEDITOR.dom.walker( new CKEDITOR.dom.range( editor.document ) ); |
| | 830 | walker.evaluator = nonEmpty; |
| | 831 | |
| | 832 | if ( isBackspace ) |
| | 833 | { |
| | 834 | walker.range.setStartAt( body, CKEDITOR.POSITION_AFTER_START ); |
| | 835 | walker.range.setEnd( range.startContainer, range.startOffset ); |
| | 836 | |
| | 837 | var previous = walker.previous(); |
| | 838 | |
| | 839 | // Check if cursor collapsed right behind of a list. |
| | 840 | if ( previous && |
| | 841 | previous.type == CKEDITOR.NODE_ELEMENT && |
| | 842 | previous.getName() in listNodeNames ) |
| | 843 | { |
| | 844 | walker.range.selectNodeContents( previous ); |
| | 845 | walker.reset(); |
| | 846 | walker.evaluator = isTextBlock; |
| | 847 | joinCursorLineToBlock( walker.lastForward(), range ); |
| | 848 | evt.cancel(); |
| | 849 | } |
| | 850 | } |
| | 851 | else |
| | 852 | { |
| | 853 | var li = range.startContainer.getAscendant( 'li', 1 ); |
| | 854 | if ( li ) |
| | 855 | { |
| | 856 | var block = li.getLast( isTextBlock ) || li; |
| | 857 | |
| | 858 | // Check cursor at the very end of list item. |
| | 859 | if ( range.checkBoundaryOfElement( block, CKEDITOR.END ) ) |
| | 860 | { |
| | 861 | walker.range.setStartAt( li, CKEDITOR.POSITION_AFTER_END ); |
| | 862 | walker.range.setEndAt( body, CKEDITOR.POSITION_BEFORE_END ); |
| | 863 | |
| | 864 | var next = walker.next(); |
| | 865 | |
| | 866 | // Check if following the list are inline or text block. |
| | 867 | if ( next && next.type == CKEDITOR.NODE_ELEMENT && |
| | 868 | ( isTextBlock( next ) || next.getName() in CKEDITOR.dtd.$inline ) ) |
| | 869 | { |
| | 870 | // Put cursor range there. |
| | 871 | range = range.clone(); |
| | 872 | range.moveToElementEditStart( next ); |
| | 873 | |
| | 874 | joinCursorLineToBlock( block, range ); |
| | 875 | evt.cancel(); |
| | 876 | } |
| | 877 | } |
| | 878 | } |
| | 879 | } |
| | 880 | } |
| | 881 | } ); |
| | 882 | } |