Ticket #1229: 1229_4.patch
File 1229_4.patch, 9.8 KB (added by , 16 years ago) |
---|
-
_whatsnew.html
300 300 block.</li> 301 301 <li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/1627">#1627</a>] Samples 302 302 failed to load from local filesystem in IE7.</li> 303 <li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/1229">#1229</a>] Converting 304 multiple contiguous paragraphs to Formatted will now be merged into a single 305 <PRE> block.</li> 303 306 </ul> 304 307 <p> 305 308 <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( previousBlock, preBlock ) 850 { 851 // Check if the previous block and the current block are next 852 // to each other. 853 if ( previousBlock != FCKDomTools.GetPreviousSourceElement( preBlock, true ) ) 854 return ; 855 856 // Merge the previous <pre> block contents into the current <pre> 857 // block. 858 // 859 // Another thing to be careful here is that currentBlock might contain 860 // a '\n' at the beginning, and previousBlock might contain a '\n' 861 // towards the end. These new lines are not normally displayed but they 862 // become visible after merging. 863 var innerHTML = previousBlock.innerHTML.replace( /\n$/, '' ) + '\n\n' + 864 preBlock.innerHTML.replace( /^\n/, '' ) ; 865 866 // Buggy IE normalizes innerHTML from <pre>, breaking whitespaces. 867 if ( FCKBrowserInfo.IsIE ) 868 preBlock.outerHTML = '<pre>' + innerHTML + '</pre>' ; 869 else 870 preBlock.innerHTML = innerHTML ; 871 872 // Remove the previous <pre> block. 873 // 874 // The preBlock must not be moved or deleted from the DOM tree. This 875 // guarantees the FCKDomRangeIterator in _ApplyBlockStyle would not 876 // get lost at the next iteration. 877 FCKDomTools.RemoveNode( previousBlock ) ; 878 }, 879 880 _CheckAndSplitPre : function( newBlock ) 881 { 882 var lastNewBlock ; 883 884 var cursor = newBlock.firstChild ; 885 886 // We are not splitting <br><br> at the beginning of the block, so 887 // we'll start from the second child. 888 cursor = cursor && cursor.nextSibling ; 889 890 while ( cursor ) 891 { 892 var next = cursor.nextSibling ; 893 894 // If we have two <BR>s, and they're not at the beginning or the end, 895 // then we'll split up the contents following them into another block. 896 // Stop processing if we are at the last child couple. 897 if ( next && next.nextSibling && cursor.nodeName.IEquals( 'br' ) && next.nodeName.IEquals( 'br' ) ) 898 { 899 // Remove the first <br>. 900 FCKDomTools.RemoveNode( cursor ) ; 901 902 // Move to the node after the second <br>. 903 cursor = next.nextSibling ; 904 905 // Remove the second <br>. 906 FCKDomTools.RemoveNode( next ) ; 907 908 // Create the block that will hold the child nodes from now on. 909 lastNewBlock = FCKDomTools.InsertAfterNode( lastNewBlock || newBlock, FCKDomTools.CloneElement( newBlock ) ) ; 910 911 continue ; 912 } 913 914 // If we split it, then start moving the nodes to the new block. 915 if ( lastNewBlock ) 916 { 917 cursor = cursor.previousSibling ; 918 FCKDomTools.MoveNode(cursor.nextSibling, lastNewBlock ) ; 919 } 920 921 cursor = cursor.nextSibling ; 922 } 923 }, 924 925 /** 840 926 * Apply an inline style to a FCKDomRange. 841 927 * 842 928 * TODO … … 856 942 857 943 var block ; 858 944 var doc = range.Window.document ; 945 var previousPreBlock ; 859 946 860 var preBlocks = [] ;861 var convertedPreBlocks = [] ;862 863 947 while( ( block = iterator.GetNextParagraph() ) ) // Only one = 864 948 { 865 949 // Create the new node right before the current one. 866 950 var newBlock = this.BuildElement( doc ) ; 867 951 952 // Check if we are changing from/to <pre>. 953 var newBlockIsPre = newBlock.nodeName.IEquals( 'pre' ) ; 954 var blockIsPre = block.nodeName.IEquals( 'pre' ) ; 955 956 var toPre = newBlockIsPre && !blockIsPre ; 957 var fromPre = !newBlockIsPre && blockIsPre ; 958 868 959 // 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 { 960 if ( toPre ) 873 961 newBlock = this._ToPre( doc, block, newBlock ) ; 874 preBlocks.push( newBlock ) ; 875 } 876 else if ( !newBlockIsPre && blockIsPre ) 877 { 962 else if ( fromPre ) 878 963 newBlock = this._FromPre( doc, block, newBlock ) ; 879 convertedPreBlocks.push( newBlock ) ;880 }881 964 else // Convering from a regular block to another regular block. 882 965 FCKDomTools.MoveChildren( block, newBlock ) ; 883 966 884 967 // Replace the current block. 885 968 block.parentNode.insertBefore( newBlock, block ) ; 886 969 FCKDomTools.RemoveNode( block ) ; 887 }888 970 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] ) ; 900 } 901 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++ ) 971 // Complete other tasks after inserting the node in the DOM. 972 if ( newBlockIsPre ) 908 973 { 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 - 2 914 && 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 iteration 919 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 iteration 927 } 974 if ( previousPreBlock ) 975 this._CheckAndMergePre( previousPreBlock, newBlock ) ; // Merge successive <pre> blocks. 976 previousPreBlock = newBlock ; 928 977 } 978 else if ( fromPre ) 979 this._CheckAndSplitPre( newBlock ) ; // Split <br><br> in successive <pre>s. 929 980 } 930 981 931 982 // Re-select the original range.