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 | |