Ticket #1355: 1355_3.patch

File 1355_3.patch, 9.3 KB (added by Martin Kou, 13 years ago)

Fixes a minor bug in 1533_2.patch discovered when writing test cases.

  • editor/_source/classes/fckdomrange_gecko.js

     
    101101        var selection = this.Window.getSelection() ;
    102102        selection.removeAllRanges() ;
    103103        selection.addRange( domRange ) ;
    104 }
    105  No newline at end of file
     104}
  • editor/_source/classes/fckstyle.js

     
    759759                var bookmark ;
    760760
    761761                if ( selectIt )
    762                         bookmark = range.CreateBookmark( true ) ;
     762                        bookmark = range.CreateBookmark() ;
    763763
    764764                var iterator = new FCKDomRangeIterator( range ) ;
    765765                iterator.EnforceRealBlocks = true ;
    766766
    767767                var block ;
     768                var doc = range.Window.document ;
     769                var tagPattern = FCKRegexLib.HTMLTag;
     770
    768771                while( ( block = iterator.GetNextParagraph() ) )                // Only one =
    769772                {
    770773                        // Create the new node right before the current one.
    771                         var newBlock = block.parentNode.insertBefore( this.BuildElement( range.Window.document ), block ) ;
     774                        // var newBlock = block.parentNode.insertBefore( this.BuildElement( range.Window.document ), block ) ;
     775                        var newBlock = this.BuildElement( doc ) ;
    772776
    773777                        // Move everything from the current node to the new one.
    774                         FCKDomTools.MoveChildren( block, newBlock ) ;
     778                        if ( newBlock.nodeName.IEquals( 'pre' ) && !block.nodeName.IEquals( 'pre' ) )
     779                        {
     780                                // Handle converting from a regular block to a <pre> block.
     781                                var innerHTML = block.innerHTML.Trim() ;
     782                                var xhtmlIterator = new FCKXHTMLIterator( innerHTML ) ;
     783                                var results = [] ;
     784                                var lastNodeWasBr = false ;
    775785
    776                         // Delete the current node.
     786                                // 1. Delete ANSI whitespaces immediately before and after <BR> because they are not visible.
     787                                // 2. Compress other ANSI whitespaces since they're only visible as one single space previously.
     788                                // 3. Convert &nbsp; to spaces since &nbsp; is no longer needed in <PRE>.
     789                                var processor = function( type, value )
     790                                {
     791                                        if ( type == 'tag' )
     792                                        {
     793                                                if ( /^<BR/i.test( value ) )
     794                                                {
     795                                                        value = '\n' ;
     796                                                        if ( results.length > 0 )
     797                                                                results[results.length - 1] = results[results.length - 1].RTrim() ;
     798                                                        lastNodeWasBr = true ;
     799                                                }
     800                                                else
     801                                                        lastNodeWasBr = false ;
     802                                        }
     803                                        else
     804                                        {
     805                                                if ( lastNodeWasBr )
     806                                                        value = value.LTrim() ;
     807                                                value = value.replace( /([ \t\n\r]+|&nbsp;)/g, ' ' ) ;
     808                                                lastNodeWasBr = false ;
     809                                        }
     810                                        results.push( value ) ;
     811                                }
     812                                xhtmlIterator.Each( processor ) ;
     813
     814                                // Assigning innerHTML to <PRE> in IE causes all linebreaks to be reduced to spaces.
     815                                // Assigning outerHTML to <PRE> in IE doesn't work if the <PRE> isn't contained in another node
     816                                // since the node reference is changed after outerHTML assignment.
     817                                // So, we need some hacks to workaround IE bugs here.
     818                                if ( FCKBrowserInfo.IsIE )
     819                                {
     820                                        var temp = doc.createElement( 'div' ) ;
     821                                        temp.appendChild( newBlock ) ;
     822                                        newBlock.outerHTML = '<PRE>\n' + results.join( '' ) + '</PRE>' ;
     823                                        newBlock = temp.removeChild( temp.firstChild ) ;
     824                                }
     825                                else
     826                                        newBlock.innerHTML = results.join( '' ) ;
     827                        }
     828                        else if ( !newBlock.nodeName.IEquals( 'pre' ) && block.nodeName.IEquals( 'pre' ) )
     829                        {
     830                                var innerHTML = block.innerHTML ;
     831
     832                                // Trim the first and last linebreaks immediately after and before <pre>, </pre>,
     833                                // if they exist.
     834                                // This is done because the linebreaks are not rendered.
     835                                innerHTML = innerHTML.replace( /(\r\n|\r)/g, '\n' ) ;
     836                                innerHTML = innerHTML.match( /^(?:[ \t]*\n)?((?:[a]|[^a])*)$/ )[1] ;
     837                                var lastWhiteSpaceMatch = /\n$/.exec( innerHTML ) ;
     838                                if ( lastWhiteSpaceMatch )
     839                                        innerHTML = innerHTML.substr( 0, lastWhiteSpaceMatch.index ) ;
     840
     841                                // 1. Convert spaces or tabs at the beginning or at the end to &nbsp;
     842                                var beginSpaces = /^[ \t]+/.exec( innerHTML ) ;
     843                                var endSpaces = /[ \t]+$/.exec( innerHTML ) ;
     844                                if ( endSpaces )
     845                                        innerHTML = innerHTML.substr( 0, endSpaces.index ) + endSpaces[0].replace( /[ \t]/g, '&nbsp;' ) ;
     846                                if ( beginSpaces )
     847                                        innerHTML = beginSpaces[0].replace( /[ \t]/g, '&nbsp;' ) + innerHTML.substr( beginSpaces[0].length ) ;
     848
     849                                // 2. Convert \n to <BR>.
     850                                // 3. Convert contiguous (i.e. non-singular) spaces or tabs to &nbsp;
     851                                var xhtmlIterator = new FCKXHTMLIterator( innerHTML ) ;
     852                                var results = [] ;
     853                                var processor = function( type, value )
     854                                {
     855                                        if ( type == 'text' )
     856                                        {
     857                                                value = value.replace( /\n/g, '<BR>' ) ;
     858                                                value = value.replace( /[ \t]{2}/g, '&nbsp;&nbsp;' ) ;
     859                                        }
     860                                        results.push( value ) ;
     861                                }
     862                                xhtmlIterator.Each( processor ) ;
     863                                newBlock.innerHTML = results.join( '' ) ;
     864                        }
     865                        else    // Convering from a regular block to another regular block.
     866                                FCKDomTools.MoveChildren( block, newBlock ) ;
     867
     868                        // Replace the current block.
     869                        block.parentNode.insertBefore( newBlock, block ) ;
    777870                        FCKDomTools.RemoveNode( block ) ;
    778871                }
    779872
     
    782875                        range.SelectBookmark( bookmark ) ;
    783876
    784877                if ( updateRange )
    785                         range.MoveToBookmark( range ) ;
     878                        range.MoveToBookmark( bookmark ) ;
    786879        },
    787880
    788881        /**
  • editor/_source/classes/fckxhtmliterator.js

     
     1/*
     2 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
     3 * Copyright (C) 2003-2007 Frederico Caldeira Knabben
     4 *
     5 * == BEGIN LICENSE ==
     6 *
     7 * Licensed under the terms of any of the following licenses at your
     8 * choice:
     9 *
     10 *  - GNU General Public License Version 2 or later (the "GPL")
     11 *    http://www.gnu.org/licenses/gpl.html
     12 *
     13 *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
     14 *    http://www.gnu.org/licenses/lgpl.html
     15 *
     16 *  - Mozilla Public License Version 1.1 or later (the "MPL")
     17 *    http://www.mozilla.org/MPL/MPL-1.1.html
     18 *
     19 * == END LICENSE ==
     20 *
     21 * This class can be used to interate through nodes inside a range.
     22 *
     23 * During interation, the provided range can become invalid, due to document
     24 * mutations, so CreateBookmark() used to restore it after processing, if
     25 * needed.
     26 */
     27
     28var FCKXHTMLIterator = function( source )
     29{
     30        this._sourceHTML = source ;
     31}
     32FCKXHTMLIterator.prototype =
     33{
     34        Next : function()
     35        {
     36                if ( this._sourceHTML == null )
     37                        return null ;
     38
     39                var match = FCKRegexLib.HTMLTag.exec( this._sourceHTML ) ;
     40                var retval ;
     41                if ( match )
     42                {
     43                        if ( match.index > 0 )
     44                        {
     45                                retval = { 'type' : 'text', 'value' : this._sourceHTML.substr( 0, match.index ) } ;
     46                                this._sourceHTML = this._sourceHTML.substr( match.index ) ;
     47                        }
     48                        else
     49                        {
     50                                retval = { 'type' : 'tag', 'value' : match[0] } ;
     51                                this._sourceHTML = this._sourceHTML.substr( match[0].length ) ;
     52                        }
     53                }
     54                else
     55                {
     56                        retval = { 'type' : 'text', 'value' : this._sourceHTML } ;
     57                        this._sourceHTML = null ;
     58                }
     59                return retval ;
     60        },
     61
     62        Each : function( func )
     63        {
     64                var chunk ;
     65                while ( ( chunk = this.Next() ) )
     66                        func( chunk.type, chunk.value ) ;
     67        }
     68} ;
  • editor/_source/internals/fckregexlib.js

     
    9393// name is returned with $2.
    9494StyleVariableAttName : /#\(\s*("|')(.+?)\1[^\)]*\s*\)/g,
    9595
    96 RegExp : /^\/(.*)\/([gim]*)$/
     96RegExp : /^\/(.*)\/([gim]*)$/,
     97
     98HTMLTag : /<[^\s<>](?:"[^"]*"|'[^']*'|[^<])*>/
    9799} ;
  • editor/fckeditor.html

     
    186186LoadScript( '_source/classes/fckmenublockpanel.js' ) ;
    187187LoadScript( '_source/classes/fckcontextmenu.js' ) ;
    188188LoadScript( '_source/internals/fck_contextmenu.js' ) ;
     189LoadScript( '_source/classes/fckxhtmliterator.js' ) ;
    189190LoadScript( '_source/classes/fckplugin.js' ) ;
    190191LoadScript( '_source/internals/fckplugins.js' ) ;
    191192
  • fckpackager.xml

     
    157157                <File path="editor/_source/classes/fckmenublockpanel.js" />
    158158                <File path="editor/_source/classes/fckcontextmenu.js" />
    159159                <File path="editor/_source/internals/fck_contextmenu.js" />
     160                <File path="editor/_source/class/fckxhtmliterator.js" />
    160161
    161162                <File path="editor/_source/classes/fckplugin.js" />
    162163                <File path="editor/_source/internals/fckplugins.js" />
     
    252253                <File path="editor/_source/classes/fckmenublockpanel.js" />
    253254                <File path="editor/_source/classes/fckcontextmenu.js" />
    254255                <File path="editor/_source/internals/fck_contextmenu.js" />
     256                <File path="editor/_source/class/fckxhtmliterator.js" />
    255257
    256258                <File path="editor/_source/classes/fckplugin.js" />
    257259                <File path="editor/_source/internals/fckplugins.js" />
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy