| | 750 | * Converting from a PRE block to a non-PRE block in formatting operations. |
| | 751 | */ |
| | 752 | _FromPre : function( doc, block, newBlock ) |
| | 753 | { |
| | 754 | var innerHTML = block.innerHTML ; |
| | 755 | |
| | 756 | // Trim the first and last linebreaks immediately after and before <pre>, </pre>, |
| | 757 | // if they exist. |
| | 758 | // This is done because the linebreaks are not rendered. |
| | 759 | innerHTML = innerHTML.replace( /(\r\n|\r)/g, '\n' ) ; |
| | 760 | innerHTML = innerHTML.replace( /^[ \t]*\n/, '' ) ; |
| | 761 | innerHTML = innerHTML.replace( /\n$/, '' ) ; |
| | 762 | |
| | 763 | // 1. Convert spaces or tabs at the beginning or at the end to |
| | 764 | innerHTML = innerHTML.replace( /^[ \t]+|[ \t]+$/g, function( match, offset, s ) |
| | 765 | { |
| | 766 | if ( match.length == 1 ) // one space, preserve it |
| | 767 | return ' ' ; |
| | 768 | else if ( offset == 0 ) // beginning of block |
| | 769 | return new Array( match.length ).join( ' ' ) + ' ' ; |
| | 770 | else // end of block |
| | 771 | return ' ' + new Array( match.length ).join( ' ' ) ; |
| | 772 | } ) ; |
| | 773 | |
| | 774 | // 2. Convert \n to <BR>. |
| | 775 | // 3. Convert contiguous (i.e. non-singular) spaces or tabs to |
| | 776 | var htmlIterator = new FCKHtmlIterator( innerHTML ) ; |
| | 777 | var results = [] ; |
| | 778 | htmlIterator.Each( function( isTag, value ) |
| | 779 | { |
| | 780 | if ( !isTag ) |
| | 781 | { |
| | 782 | value = value.replace( /\n/g, '<BR>' ) ; |
| | 783 | value = value.replace( /[ \t]{2,}/g, |
| | 784 | function ( match ) |
| | 785 | { |
| | 786 | return new Array( match.length ).join( ' ' ) + ' ' ; |
| | 787 | } ) ; |
| | 788 | } |
| | 789 | results.push( value ) ; |
| | 790 | } ) ; |
| | 791 | newBlock.innerHTML = results.join( '' ) ; |
| | 792 | return newBlock ; |
| | 793 | }, |
| | 794 | |
| | 795 | /** |
| | 796 | * Converting from a non-PRE block to a PRE block in formatting operations. |
| | 797 | */ |
| | 798 | _ToPre : function( doc, block, newBlock ) |
| | 799 | { |
| | 800 | // Handle converting from a regular block to a <pre> block. |
| | 801 | var innerHTML = block.innerHTML.Trim() ; |
| | 802 | |
| | 803 | // 1. Delete ANSI whitespaces immediately before and after <BR> because they are not visible. |
| | 804 | // 2. Mark down any <BR /> nodes here so they can be turned into \n in the next step and avoid being compressed. |
| | 805 | innerHTML = innerHTML.replace( /[ \t\r\n]*(<br[^>]*>)[ \t\r\n]*/gi, '<BR />' ) ; |
| | 806 | |
| | 807 | // 3. Compress other ANSI whitespaces since they're only visible as one single space previously. |
| | 808 | // 4. Convert to spaces since is no longer needed in <PRE>. |
| | 809 | // 5. Convert any <BR /> to \n. This must not be done earlier because the \n would then get compressed. |
| | 810 | var htmlIterator = new FCKHtmlIterator( innerHTML ) ; |
| | 811 | var results = [] ; |
| | 812 | htmlIterator.Each( function( isTag, value ) |
| | 813 | { |
| | 814 | if ( !isTag ) |
| | 815 | value = value.replace( /([ \t\n\r]+| )/g, ' ' ) ; |
| | 816 | else if ( isTag && value == '<BR />' ) |
| | 817 | value = '\n' ; |
| | 818 | results.push( value ) ; |
| | 819 | } ) ; |
| | 820 | |
| | 821 | // Assigning innerHTML to <PRE> in IE causes all linebreaks to be reduced to spaces. |
| | 822 | // Assigning outerHTML to <PRE> in IE doesn't work if the <PRE> isn't contained in another node |
| | 823 | // since the node reference is changed after outerHTML assignment. |
| | 824 | // So, we need some hacks to workaround IE bugs here. |
| | 825 | if ( FCKBrowserInfo.IsIE ) |
| | 826 | { |
| | 827 | var temp = doc.createElement( 'div' ) ; |
| | 828 | temp.appendChild( newBlock ) ; |
| | 829 | newBlock.outerHTML = '<PRE>\n' + results.join( '' ) + '</PRE>' ; |
| | 830 | newBlock = temp.removeChild( temp.firstChild ) ; |
| | 831 | } |
| | 832 | else |
| | 833 | newBlock.innerHTML = results.join( '' ) ; |
| | 834 | return newBlock ; |
| | 835 | }, |
| | 836 | |
| | 837 | /** |
| 774 | | FCKDomTools.MoveChildren( block, newBlock ) ; |
| 775 | | |
| 776 | | // Delete the current node. |
| | 864 | var newBlockIsPre = newBlock.nodeName.IEquals( 'pre' ) ; |
| | 865 | var blockIsPre = block.nodeName.IEquals( 'pre' ) ; |
| | 866 | if ( newBlockIsPre && !blockIsPre ) |
| | 867 | newBlock = this._ToPre( doc, block, newBlock ) ; |
| | 868 | else if ( !newBlockIsPre && blockIsPre ) |
| | 869 | newBlock = this._FromPre( doc, block, newBlock ) ; |
| | 870 | else // Convering from a regular block to another regular block. |
| | 871 | FCKDomTools.MoveChildren( block, newBlock ) ; |
| | 872 | |
| | 873 | // Replace the current block. |
| | 874 | block.parentNode.insertBefore( newBlock, block ) ; |