| 641 | | // Check if we are changing from/to <pre>. |
| 642 | | // var newBlockIsPre = newBlock.nodeName.IEquals( 'pre' ); |
| 643 | | // var blockIsPre = block.nodeName.IEquals( 'pre' ); |
| | 642 | range.moveToBookmark( bookmark ); |
| | 643 | } |
| | 644 | |
| | 645 | // Replace the orignal block with new one, also contains special treatment |
| | 646 | // for <pre> blocks is needed, which makes it possible to switch forth and |
| | 647 | // back to <p>, with format well preserved, and merging/splitting adjacent |
| | 648 | // when necessary.(#3188) |
| | 649 | function replaceBlock( block, newBlock, document ) |
| | 650 | { |
| | 651 | // Create the new node right before the current one. |
| | 652 | // Check if we are changing from/to <pre>. |
| | 653 | var newBlockIsPre = newBlock.is( 'pre' ); |
| | 654 | var blockIsPre = block.is( 'pre' ); |
| 648 | | // Move everything from the current node to the new one. |
| 649 | | // if ( toPre ) |
| 650 | | // newBlock = this._ToPre( doc, block, newBlock ); |
| 651 | | // else if ( fromPre ) |
| 652 | | // newBlock = this._FromPre( doc, block, newBlock ); |
| 653 | | // else // Convering from a regular block to another regular block. |
| 654 | | block.moveChildren( newBlock ); |
| | 659 | // Move everything from the current node to the new one. |
| | 660 | if ( isToPre ) |
| | 661 | newBlock = toPre( block, newBlock, document ); |
| | 662 | else if ( isFromPre ) |
| | 663 | newBlock = fromPre( block, newBlock ); |
| 656 | | // Replace the current block. |
| 657 | | newBlock.insertBefore( block ); |
| 658 | | block.remove(); |
| 659 | | |
| 660 | | // Complete other tasks after inserting the node in the DOM. |
| 661 | | // if ( newBlockIsPre ) |
| 662 | | // { |
| 663 | | // if ( previousPreBlock ) |
| 664 | | // this._CheckAndMergePre( previousPreBlock, newBlock ) ; // Merge successive <pre> blocks. |
| 665 | | // previousPreBlock = newBlock; |
| 666 | | // } |
| 667 | | // else if ( fromPre ) |
| 668 | | // this._CheckAndSplitPre( newBlock ) ; // Split <br><br> in successive <pre>s. |
| 669 | | } |
| | 665 | newBlock.replace( block ); |
| | 666 | if ( newBlockIsPre ) |
| | 667 | // Merge successive <pre> blocks. |
| | 668 | mergePre( newBlock ); |
| | 669 | else if ( isFromPre ) |
| | 670 | // Split <br><br> in successive <pre>s. |
| | 671 | splitIntoBlocks( newBlock, document ); |
| | 672 | |
| | 673 | }; |
| | 674 | |
| | 675 | /** |
| | 676 | * Merge a <pre> block with a previous sibling if available. |
| | 677 | */ |
| | 678 | function mergePre( preBlock ) |
| | 679 | { |
| | 680 | var previousBlock; |
| | 681 | if ( !( ( previousBlock = preBlock.getPreviousSourceNode( true, CKEDITOR.NODE_ELEMENT ) ) |
| | 682 | && previousBlock.is |
| | 683 | && previousBlock.is( 'pre') ) ) |
| | 684 | return; |
| | 685 | |
| | 686 | // Merge the previous <pre> block contents into the current <pre> |
| | 687 | // block. |
| | 688 | // |
| | 689 | // Another thing to be careful here is that currentBlock might contain |
| | 690 | // a '\n' at the beginning, and previousBlock might contain a '\n' |
| | 691 | // towards the end. These new lines are not normally displayed but they |
| | 692 | // become visible after merging. |
| | 693 | var mergedHtml = previousBlock.getHtml().replace( /\n$/, '' ) + '\n\n' + |
| | 694 | preBlock.getHtml().replace( /^\n/, '' ) ; |
| | 695 | |
| | 696 | // Krugle: IE normalizes innerHTML from <pre>, breaking whitespaces. |
| | 697 | if ( CKEDITOR.env.ie ) |
| | 698 | preBlock.$.outerHTML = '<pre>' + mergedHtml + '</pre>'; |
| | 699 | else |
| | 700 | preBlock.setHtml( mergedHtml ); |
| | 701 | |
| | 702 | previousBlock.remove(); |
| | 703 | } |
| | 716 | var temp = doc.createElement( 'div' ); |
| | 717 | temp.setHtml( splitedHtml ); |
| | 718 | temp.replace( newBlock ); |
| | 719 | temp.remove( true ); |
| | 720 | } |
| | 721 | |
| | 722 | /** |
| | 723 | * Converting from a PRE block to a non-PRE block in formatting operations. |
| | 724 | */ |
| | 725 | function fromPre( block, newBlock ) |
| | 726 | { |
| | 727 | var blockHtml = block.getHtml(); |
| | 728 | |
| | 729 | // Trim the first and last linebreaks immediately after and before <pre>, </pre>, |
| | 730 | // if they exist. |
| | 731 | // This is done because the linebreaks are not rendered. |
| | 732 | blockHtml = blockHtml.replace( /(\r\n|\r)/g, '\n' ) ; |
| | 733 | blockHtml = blockHtml.replace( /^[ \t]*\n/, '' ) ; |
| | 734 | blockHtml = blockHtml.replace( /\n$/, '' ) ; |
| | 735 | |
| | 736 | // 1. Convert spaces or tabs at the beginning or at the end to |
| | 737 | blockHtml = blockHtml.replace( /^[ \t]+|[ \t]+$/g, function( match, offset, s ) |
| | 738 | { |
| | 739 | if ( match.length == 1 ) // one space, preserve it |
| | 740 | return ' ' ; |
| | 741 | else if ( offset == 0 ) // beginning of block |
| | 742 | return new Array( match.length ).join( ' ' ) + ' ' ; |
| | 743 | else // end of block |
| | 744 | return ' ' + new Array( match.length ).join( ' ' ) ; |
| | 745 | } ) ; |
| | 746 | |
| | 747 | // 2. Convert \n to <BR>. |
| | 748 | // 3. Convert contiguous (i.e. non-singular) spaces or tabs to |
| | 749 | blockHtml = blockHtml.replace( /\n/g, '<br>' ) ; |
| | 750 | blockHtml = blockHtml.replace( /[ \t]{2,}/g, |
| | 751 | function ( match ) |
| | 752 | { |
| | 753 | return new Array( match.length ).join( ' ' ) + ' ' ; |
| | 754 | } ) ; |
| | 755 | newBlock.setHtml( blockHtml ); |
| | 756 | return newBlock ; |
| | 757 | } |
| | 758 | |
| | 759 | /** |
| | 760 | * Converting from a non-PRE block to a PRE block in formatting operations. |
| | 761 | */ |
| | 762 | function toPre( block, newBlock, document ) |
| | 763 | { |
| | 764 | // Handle converting from a regular block to a <pre> block. |
| | 765 | var preHtml = CKEDITOR.tools.trim( block.getHtml() ); |
| | 766 | |
| | 767 | // 1. Delete ANSI whitespaces immediately before and after <BR> because |
| | 768 | // they are not visible. |
| | 769 | // 2. Mark down any <BR /> nodes here so they can be turned into \n in |
| | 770 | // the next step and avoid being compressed. |
| | 771 | preHtml = preHtml.replace( /[ \t\r\n]*(<br[^>]*>)[ \t\r\n]*/gi, '$1' ); |
| | 772 | // 3. Compress other ANSI whitespaces since they're only visible as one |
| | 773 | // single space previously. |
| | 774 | // 4. Convert to spaces since is no longer needed in <PRE>. |
| | 775 | preHtml = preHtml.replace( /([ \t\n\r]+| )/g, ' ' ); |
| | 776 | // 5. Convert any <BR /> to \n. This must not be done earlier because |
| | 777 | // the \n would then get compressed. |
| | 778 | preHtml = preHtml.replace( /<br\b[^>]*>/gi, '\n' ); |
| | 779 | |
| | 780 | // Krugle: IE normalizes innerHTML to <pre>, breaking whitespaces. |
| | 781 | if ( CKEDITOR.env.ie ) |
| | 782 | { |
| | 783 | var temp = document.createElement( 'div' ); |
| | 784 | temp.append( newBlock ); |
| | 785 | newBlock.$.outerHTML = '<pre>\n' + preHtml + '</pre>'; |
| | 786 | newBlock = temp.getFirst().remove(); |
| | 787 | } |
| | 788 | else |
| | 789 | newBlock.setHtml( preHtml ); |
| | 790 | |
| | 791 | return newBlock; |
| | 792 | } |
| | 793 | |