Changeset 2220

Show
Ignore:
Timestamp:
2008-07-15 08:55:33 (8 weeks ago)
Author:
martinkou
Message:

Fixed #1229 : Converting multiple contiguous paragraphs to Formatted will now be merged into a single <PRE> block.

Location:
FCKeditor/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • FCKeditor/trunk/editor/_source/classes/fckstyle.js

    r2124 r2220  
    788788                                if ( !isTag ) 
    789789                                { 
    790                                         value = value.replace( /\n/g, '<BR>' ) ; 
     790                                        value = value.replace( /\n/g, '<br>' ) ; 
    791791                                        value = value.replace( /[ \t]{2,}/g, 
    792792                                                        function ( match ) 
     
    809809                var innerHTML = block.innerHTML.Trim() ; 
    810810 
    811                 // 1. Delete ANSI whitespaces immediately before and after <BR> because they are not visible. 
    812                 // 2. Mark down any <BR /> nodes here so they can be turned into \n in the next step and avoid being compressed. 
    813                 innerHTML = innerHTML.replace( /[ \t\r\n]*(<br[^>]*>)[ \t\r\n]*/gi, '<BR />' ) ; 
    814  
    815                 // 3. Compress other ANSI whitespaces since they're only visible as one single space previously. 
     811                // 1. Delete ANSI whitespaces immediately before and after <BR> because 
     812                //    they are not visible. 
     813                // 2. Mark down any <BR /> nodes here so they can be turned into \n in 
     814                //    the next step and avoid being compressed. 
     815                innerHTML = innerHTML.replace( /[ \t\r\n]*(<br[^>]*>)[ \t\r\n]*/gi, '<br />' ) ; 
     816 
     817                // 3. Compress other ANSI whitespaces since they're only visible as one 
     818                //    single space previously. 
    816819                // 4. Convert &nbsp; to spaces since &nbsp; is no longer needed in <PRE>. 
    817                 // 5. Convert any <BR /> to \n. This must not be done earlier because the \n would then get compressed. 
     820                // 5. Convert any <BR /> to \n. This must not be done earlier because 
     821                //    the \n would then get compressed. 
    818822                var htmlIterator = new FCKHtmlIterator( innerHTML ) ; 
    819823                var results = [] ; 
     
    822826                                if ( !isTag ) 
    823827                                        value = value.replace( /([ \t\n\r]+|&nbsp;)/g, ' ' ) ; 
    824                                 else if ( isTag && value == '<BR />' ) 
     828                                else if ( isTag && value == '<br />' ) 
    825829                                        value = '\n' ; 
    826830                                results.push( value ) ; 
    827831                        } ) ; 
    828832 
    829                 // Assigning innerHTML to <PRE> in IE causes all linebreaks to be reduced to spaces. 
    830                 // Assigning outerHTML to <PRE> in IE doesn't work if the <PRE> isn't contained in another node 
    831                 // since the node reference is changed after outerHTML assignment. 
     833                // Assigning innerHTML to <PRE> in IE causes all linebreaks to be 
     834                // reduced to spaces. 
     835                // Assigning outerHTML to <PRE> in IE doesn't work if the <PRE> isn't 
     836                // contained in another node since the node reference is changed after 
     837                // outerHTML assignment. 
    832838                // So, we need some hacks to workaround IE bugs here. 
    833839                if ( FCKBrowserInfo.IsIE ) 
     
    835841                        var temp = doc.createElement( 'div' ) ; 
    836842                        temp.appendChild( newBlock ) ; 
    837                         newBlock.outerHTML = '<PRE>\n' + results.join( '' ) + '</PRE>' ; 
     843                        newBlock.outerHTML = '<pre>\n' + results.join( '' ) + '</pre>' ; 
    838844                        newBlock = temp.removeChild( temp.firstChild ) ; 
    839845                } 
    840846                else 
    841847                        newBlock.innerHTML = results.join( '' ) ; 
     848 
    842849                return newBlock ; 
     850        }, 
     851 
     852        /** 
     853         * Merge a <pre> block with a previous <pre> block, if available. 
     854         */ 
     855        _CheckAndMergePre : function( previousBlock, preBlock ) 
     856        { 
     857                // Check if the previous block and the current block are next 
     858                // to each other. 
     859                if ( previousBlock != FCKDomTools.GetPreviousSourceElement( preBlock, true ) ) 
     860                        return ; 
     861 
     862                // Merge the previous <pre> block contents into the current <pre> 
     863                // block. 
     864                // 
     865                // Another thing to be careful here is that currentBlock might contain 
     866                // a '\n' at the beginning, and previousBlock might contain a '\n' 
     867                // towards the end. These new lines are not normally displayed but they 
     868                // become visible after merging. 
     869                var innerHTML = previousBlock.innerHTML.replace( /\n$/, '' ) + '\n\n' + 
     870                                preBlock.innerHTML.replace( /^\n/, '' ) ; 
     871 
     872                // Buggy IE normalizes innerHTML from <pre>, breaking whitespaces. 
     873                if ( FCKBrowserInfo.IsIE ) 
     874                        preBlock.outerHTML = '<pre>' + innerHTML + '</pre>' ; 
     875                else 
     876                        preBlock.innerHTML = innerHTML ; 
     877 
     878                // Remove the previous <pre> block. 
     879                // 
     880                // The preBlock must not be moved or deleted from the DOM tree. This 
     881                // guarantees the FCKDomRangeIterator in _ApplyBlockStyle would not 
     882                // get lost at the next iteration. 
     883                FCKDomTools.RemoveNode( previousBlock ) ; 
     884        }, 
     885 
     886        _CheckAndSplitPre : function( newBlock ) 
     887        { 
     888                var lastNewBlock ; 
     889 
     890                var cursor = newBlock.firstChild ; 
     891                 
     892                // We are not splitting <br><br> at the beginning of the block, so 
     893                // we'll start from the second child. 
     894                cursor = cursor && cursor.nextSibling ; 
     895 
     896                while ( cursor ) 
     897                { 
     898                        var next = cursor.nextSibling ; 
     899 
     900                        // If we have two <BR>s, and they're not at the beginning or the end, 
     901                        // then we'll split up the contents following them into another block. 
     902                        // Stop processing if we are at the last child couple. 
     903                        if ( next && next.nextSibling && cursor.nodeName.IEquals( 'br' ) && next.nodeName.IEquals( 'br' ) ) 
     904                        { 
     905                                // Remove the first <br>. 
     906                                FCKDomTools.RemoveNode( cursor ) ; 
     907 
     908                                // Move to the node after the second <br>. 
     909                                cursor = next.nextSibling ; 
     910 
     911                                // Remove the second <br>. 
     912                                FCKDomTools.RemoveNode( next ) ; 
     913 
     914                                // Create the block that will hold the child nodes from now on. 
     915                                lastNewBlock = FCKDomTools.InsertAfterNode( lastNewBlock || newBlock, FCKDomTools.CloneElement( newBlock ) ) ; 
     916 
     917                                continue ; 
     918                        } 
     919 
     920                        // If we split it, then start moving the nodes to the new block. 
     921                        if ( lastNewBlock ) 
     922                        { 
     923                                cursor = cursor.previousSibling ; 
     924                                FCKDomTools.MoveNode(cursor.nextSibling, lastNewBlock ) ; 
     925                        } 
     926 
     927                        cursor = cursor.nextSibling ; 
     928                } 
    843929        }, 
    844930 
     
    863949                var block ; 
    864950                var doc = range.Window.document ; 
    865  
    866                 var preBlocks = [] ; 
    867                 var convertedPreBlocks = [] ; 
     951                var previousPreBlock ; 
    868952 
    869953                while( ( block = iterator.GetNextParagraph() ) )                // Only one = 
     
    872956                        var newBlock = this.BuildElement( doc ) ; 
    873957 
     958                        // Check if we are changing from/to <pre>. 
     959                        var newBlockIsPre       = newBlock.nodeName.IEquals( 'pre' ) ; 
     960                        var blockIsPre          = block.nodeName.IEquals( 'pre' ) ; 
     961                         
     962                        var toPre       = newBlockIsPre && !blockIsPre ; 
     963                        var fromPre     = !newBlockIsPre && blockIsPre ; 
     964                         
    874965                        // Move everything from the current node to the new one. 
    875                         var newBlockIsPre = newBlock.nodeName.IEquals( 'pre' ) ; 
    876                         var blockIsPre = block.nodeName.IEquals( 'pre' ) ; 
    877                         if ( newBlockIsPre && !blockIsPre ) 
    878                         { 
     966                        if ( toPre ) 
    879967                                newBlock = this._ToPre( doc, block, newBlock ) ; 
    880                                 preBlocks.push( newBlock ) ; 
    881                         } 
    882                         else if ( !newBlockIsPre && blockIsPre ) 
    883                         { 
     968                        else if ( fromPre ) 
    884969                                newBlock = this._FromPre( doc, block, newBlock ) ; 
    885                                 convertedPreBlocks.push( newBlock ) ; 
    886                         } 
    887970                        else    // Convering from a regular block to another regular block. 
    888971                                FCKDomTools.MoveChildren( block, newBlock ) ; 
     
    891974                        block.parentNode.insertBefore( newBlock, block ) ; 
    892975                        FCKDomTools.RemoveNode( block ) ; 
    893                 } 
    894  
    895                 // Merge adjacent <PRE> blocks for #1229. 
    896                 for ( var i = 0 ; i < preBlocks.length - 1 ; i++ ) 
    897                 { 
    898                         // Check if the next block in HTML equals the next <PRE> block generated. 
    899                         if ( FCKDomTools.GetNextSourceElement( preBlocks[i], true, [], [], true ) != preBlocks[i+1] ) 
    900                                 continue ; 
    901  
    902                         // Merge the upper <PRE> block's content into the lower <PRE> block. 
    903                         // Remove the upper <PRE> block. 
    904                         preBlocks[i+1].innerHTML = preBlocks[i].innerHTML + '\n\n' + preBlocks[i+1].innerHTML ; 
    905                         FCKDomTools.RemoveNode( preBlocks[i] ) ; 
    906                 } 
    907  
    908                 // Split converted <PRE> blocks for #1229. 
    909                 for ( var i = 0 ; i < convertedPreBlocks.length ; i++ ) 
    910                 { 
    911                         var currentBlock = convertedPreBlocks[i] ; 
    912                         var lastNewBlock = null ; 
    913                         for ( var j = 0 ; j < currentBlock.childNodes.length ; j++ ) 
    914                         { 
    915                                 var cursor = currentBlock.childNodes[j] ; 
    916  
    917                                 // If we have two <BR>s, and they're not at the beginning or the end, 
    918                                 // then we'll split up the contents following them into another block. 
    919                                 if ( cursor.nodeName.IEquals( 'br' ) && j != 0 && j != currentBlock.childNodes.length - 2 
    920                                                 && cursor.nextSibling && cursor.nextSibling.nodeName.IEquals( 'br' ) ) 
    921                                 { 
    922                                         FCKDomTools.RemoveNode( cursor.nextSibling ) ; 
    923                                         FCKDomTools.RemoveNode( cursor ) ; 
    924                                         j-- ;   // restart at current index at next iteration 
    925                                         lastNewBlock = FCKDomTools.InsertAfterNode( lastNewBlock || currentBlock, doc.createElement( currentBlock.nodeName ) ) ; 
    926                                         continue ; 
    927                                 } 
    928  
    929                                 if ( lastNewBlock ) 
    930                                 { 
    931                                         FCKDomTools.MoveNode( cursor, lastNewBlock ) ; 
    932                                         j-- ;   // restart at current index at next iteration 
    933                                 } 
    934                         } 
     976 
     977                        // Complete other tasks after inserting the node in the DOM. 
     978                        if ( newBlockIsPre ) 
     979                        { 
     980                                if ( previousPreBlock ) 
     981                                        this._CheckAndMergePre( previousPreBlock, newBlock ) ;  // Merge successive <pre> blocks. 
     982                                previousPreBlock = newBlock ; 
     983                        } 
     984                        else if ( fromPre ) 
     985                                this._CheckAndSplitPre( newBlock ) ;    // Split <br><br> in successive <pre>s. 
    935986                } 
    936987 
  • FCKeditor/trunk/_whatsnew.html

    r2219 r2220  
    8787                <li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/1150">#1150</a>] Fixed the type="_moz" attribute 
    8888                        that sometimes appear in &lt;br&gt; tags in non-IE browsers.</li> 
     89                <li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/1229">#1229</a>] Converting 
     90                        multiple contiguous paragraphs to Formatted will now be merged into a single  
     91                        &lt;PRE&gt; block.</li> 
    8992        </ul> 
    9093        <p>