Ticket #1229: 1229_3.patch
| File 1229_3.patch, 9.8 kB (added by fredck, 6 months ago) |
|---|
-
_whatsnew.html
275 275 <PRE> block.</li> 276 276 <li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/1627">#1627</a>] Samples 277 277 failed to load from local filesystem in IE7.</li> 278 <li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/1229">#1229</a>] Converting 279 multiple contiguous paragraphs to Formatted will now be merged into a single 280 <PRE> block.</li> 278 281 </ul> 279 282 <p> 280 283 <a href="_whatsnew_history.html">See previous versions history</a> -
editor/_source/classes/fckstyle.js
781 781 { 782 782 if ( !isTag ) 783 783 { 784 value = value.replace( /\n/g, '< BR>' ) ;784 value = value.replace( /\n/g, '<br>' ) ; 785 785 value = value.replace( /[ \t]{2,}/g, 786 786 function ( match ) 787 787 { … … 802 802 // Handle converting from a regular block to a <pre> block. 803 803 var innerHTML = block.innerHTML.Trim() ; 804 804 805 // 1. Delete ANSI whitespaces immediately before and after <BR> because they are not visible. 806 // 2. Mark down any <BR /> nodes here so they can be turned into \n in the next step and avoid being compressed. 807 innerHTML = innerHTML.replace( /[ \t\r\n]*(<br[^>]*>)[ \t\r\n]*/gi, '<BR />' ) ; 805 // 1. Delete ANSI whitespaces immediately before and after <BR> because 806 // they are not visible. 807 // 2. Mark down any <BR /> nodes here so they can be turned into \n in 808 // the next step and avoid being compressed. 809 innerHTML = innerHTML.replace( /[ \t\r\n]*(<br[^>]*>)[ \t\r\n]*/gi, '<br />' ) ; 808 810 809 // 3. Compress other ANSI whitespaces since they're only visible as one single space previously. 811 // 3. Compress other ANSI whitespaces since they're only visible as one 812 // single space previously. 810 813 // 4. Convert to spaces since is no longer needed in <PRE>. 811 // 5. Convert any <BR /> to \n. This must not be done earlier because the \n would then get compressed. 814 // 5. Convert any <BR /> to \n. This must not be done earlier because 815 // the \n would then get compressed. 812 816 var htmlIterator = new FCKHtmlIterator( innerHTML ) ; 813 817 var results = [] ; 814 818 htmlIterator.Each( function( isTag, value ) 815 819 { 816 820 if ( !isTag ) 817 821 value = value.replace( /([ \t\n\r]+| )/g, ' ' ) ; 818 else if ( isTag && value == '< BR/>' )822 else if ( isTag && value == '<br />' ) 819 823 value = '\n' ; 820 824 results.push( value ) ; 821 825 } ) ; 822 826 823 // Assigning innerHTML to <PRE> in IE causes all linebreaks to be reduced to spaces. 824 // Assigning outerHTML to <PRE> in IE doesn't work if the <PRE> isn't contained in another node 825 // since the node reference is changed after outerHTML assignment. 827 // Assigning innerHTML to <PRE> in IE causes all linebreaks to be 828 // reduced to spaces. 829 // Assigning outerHTML to <PRE> in IE doesn't work if the <PRE> isn't 830 // contained in another node since the node reference is changed after 831 // outerHTML assignment. 826 832 // So, we need some hacks to workaround IE bugs here. 827 833 if ( FCKBrowserInfo.IsIE ) 828 834 { 829 835 var temp = doc.createElement( 'div' ) ; 830 836 temp.appendChild( newBlock ) ; 831 newBlock.outerHTML = '< PRE>\n' + results.join( '' ) + '</PRE>' ;837 newBlock.outerHTML = '<pre>\n' + results.join( '' ) + '</pre>' ; 832 838 newBlock = temp.removeChild( temp.firstChild ) ; 833 839 } 834 840 else 835 841 newBlock.innerHTML = results.join( '' ) ; 842 836 843 return newBlock ; 837 844 }, 838 845 839 846 /** 847 * Merge a <pre> block with a previous <pre> block, if available. 848 */ 849 _CheckAndMergePre : function( preBlock ) 850 { 851 // Get the sibling element before the block. 852 var previousBlock = FCKDomTools.GetPreviousSourceElement( preBlock, true ) ; 853 854 // Check if the previous block is a <pre>. 855 if ( previousBlock.nodeName.toLowerCase() != 'pre' ) 856 return ; 857 858 // Merge the previous <pre> block contents into the current <pre> 859 // block. 860 // 861 // Another thing to be careful here is that currentBlock might contain 862 // a '\n' at the beginning, and previousBlock might contain a '\n' 863 // towards the end. These new lines are not normally displayed but they 864 // become visible after merging. 865 var innerHTML = previousBlock.innerHTML.replace( /\n$/, '' ) + '\n\n' + 866 preBlock.innerHTML.replace( /^\n/, '' ) ; 867 868 // Buggy IE normalizes innerHTML from <pre>, breaking whitespaces. 869 if ( FCKBrowserInfo.IsIE ) 870 preBlock.outerHTML = '<pre>' + innerHTML + '</pre>' ; 871 else 872 preBlock.innerHTML = innerHTML ; 873 874 // Remove the previous <pre> block. 875 // 876 // The preBlock must not be moved or deleted from the DOM tree. This 877 // guarantees the FCKDomRangeIterator in _ApplyBlockStyle would not 878 // get lost at the next iteration. 879 FCKDomTools.RemoveNode( previousBlock ) ; 880 }, 881 882 _CheckAndSplitPre : function( previousBlock ) 883 { 884 var lastNewBlock ; 885 886 var cursor = previousBlock.firstChild ; 887 888 // We are not splitting <br><br> at the beginning of the block, so 889 // we'll start from the second child. 890 cursor = cursor && cursor.nextSibling ; 891 892 while ( cursor ) 893 { 894 var next = cursor.nextSibling ; 895 896 // If we have two <BR>s, and they're not at the beginning or the end, 897 // then we'll split up the contents following them into another block. 898 // Stop processing if we are at the last child couple. 899 if ( next && next.nextSibling && cursor.nodeName.IEquals( 'br' ) && next.nodeName.IEquals( 'br' ) ) 900 { 901 // Remove the first <br>. 902 FCKDomTools.RemoveNode( cursor ) ; 903 904 // Move to the node after the second <br>. 905 cursor = next.nextSibling ; 906 907 // Remove the second <br>. 908 FCKDomTools.RemoveNode( next ) ; 909 910 // Create the block that will hold the child nodes from now on. 911 lastNewBlock = FCKDomTools.InsertAfterNode( lastNewBlock || previousBlock, FCKDomTools.CloneElement( previousBlock ) ) ; 912 913 continue ; 914 } 915 916 // If we split it, then start moving the nodes to the new block. 917 if ( lastNewBlock ) 918 FCKDomTools.MoveNode( cursor, lastNewBlock ) ; 919 920 cursor = cursor.nextSibling ; 921 } 922 }, 923 924 /** 840 925 * Apply an inline style to a FCKDomRange. 841 926 * 842 927 * TODO … … 857 942 var block ; 858 943 var doc = range.Window.document ; 859 944 860 var preBlocks = [] ;861 var convertedPreBlocks = [] ;862 863 945 while( ( block = iterator.GetNextParagraph() ) ) // Only one = 864 946 { 865 947 // Create the new node right before the current one. 866 948 var newBlock = this.BuildElement( doc ) ; 867 949 950 // Check if we are changing from/to <pre>. 951 var newBlockIsPre = newBlock.nodeName.IEquals( 'pre' ) ; 952 var blockIsPre = block.nodeName.IEquals( 'pre' ) ; 953 954 var toPre = newBlockIsPre && !blockIsPre ; 955 var fromPre = !newBlockIsPre && blockIsPre ; 956 868 957 // Move everything from the current node to the new one. 869 var newBlockIsPre = newBlock.nodeName.IEquals( 'pre' ) ; 870 var blockIsPre = block.nodeName.IEquals( 'pre' ) ; 871 if ( newBlockIsPre && !blockIsPre ) 872 { 958 if ( toPre ) 873 959 newBlock = this._ToPre( doc, block, newBlock ) ; 874 preBlocks.push( newBlock ) ; 875 } 876 else if ( !newBlockIsPre && blockIsPre ) 877 { 960 else if ( fromPre ) 878 961 newBlock = this._FromPre( doc, block, newBlock ) ; 879 convertedPreBlocks.push( newBlock ) ;880 }881 962 else // Convering from a regular block to another regular block. 882 963 FCKDomTools.MoveChildren( block, newBlock ) ; 883 964 884 965 // Replace the current block. 885 966 block.parentNode.insertBefore( newBlock, block ) ; 886 967 FCKDomTools.RemoveNode( block ) ; 887 }888 968 889 // Merge adjacent <PRE> blocks for #1229. 890 for ( var i = 0 ; i < preBlocks.length - 1 ; i++ ) 891 { 892 // Check if the next block in HTML equals the next <PRE> block generated. 893 if ( FCKDomTools.GetNextSourceElement( preBlocks[i], true, [], [], true ) != preBlocks[i+1] ) 894 continue ; 895 896 // Merge the upper <PRE> block's content into the lower <PRE> block. 897 // Remove the upper <PRE> block. 898 preBlocks[i+1].innerHTML = preBlocks[i].innerHTML + '\n\n' + preBlocks[i+1].innerHTML ; 899 FCKDomTools.RemoveNode( preBlocks[i] ) ; 969 // Complete other tasks after inserting the node in the DOM. 970 if ( newBlockIsPre ) 971 this._CheckAndMergePre( newBlock ) ; // Merge successive <pre> blocks. 972 else if ( fromPre ) 973 this._CheckAndSplitPre( newBlock ) ; // Split <br><br> in successive <pre>s. 900 974 } 901 975 902 // Split converted <PRE> blocks for #1229.903 for ( var i = 0 ; i < convertedPreBlocks.length ; i++ )904 {905 var currentBlock = convertedPreBlocks[i] ;906 var lastNewBlock = null ;907 for ( var j = 0 ; j < currentBlock.childNodes.length ; j++ )908 {909 var cursor = currentBlock.childNodes[j] ;910 911 // If we have two <BR>s, and they're not at the beginning or the end,912 // then we'll split up the contents following them into another block.913 if ( cursor.nodeName.IEquals( 'br' ) && j != 0 && j != currentBlock.childNodes.length - 2914 && cursor.nextSibling && cursor.nextSibling.nodeName.IEquals( 'br' ) )915 {916 FCKDomTools.RemoveNode( cursor.nextSibling ) ;917 FCKDomTools.RemoveNode( cursor ) ;918 j-- ; // restart at current index at next iteration919 lastNewBlock = FCKDomTools.InsertAfterNode( lastNewBlock || currentBlock, doc.createElement( currentBlock.nodeName ) ) ;920 continue ;921 }922 923 if ( lastNewBlock )924 {925 FCKDomTools.MoveNode( cursor, lastNewBlock ) ;926 j-- ; // restart at current index at next iteration927 }928 }929 }930 931 976 // Re-select the original range. 932 977 if ( selectIt ) 933 978 range.SelectBookmark( bookmark ) ;