Ticket #1355: 1355_5.patch

File 1355_5.patch, 8.8 kB (added by martinkou, 5 months ago)

Furthur simplified 1355_4.patch from Fred's suggestions.

  • editor/_source/classes/fckhtmliterator.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 FCKHtmlIterator = function( source ) 
     29{ 
     30        this._sourceHtml = source ; 
     31} 
     32FCKHtmlIterator.prototype =  
     33{ 
     34        Next : function() 
     35        { 
     36                var sourceHtml = this._sourceHtml ; 
     37                if ( sourceHtml == null ) 
     38                        return null ; 
     39 
     40                var match = FCKRegexLib.HtmlTag.exec( sourceHtml ) ; 
     41                var isTag = false ; 
     42                var value = "" ; 
     43                if ( match ) 
     44                { 
     45                        if ( match.index > 0 ) 
     46                        { 
     47                                value = sourceHtml.substr( 0, match.index ) ; 
     48                                this._sourceHtml = sourceHtml.substr( match.index ) ; 
     49                        } 
     50                        else 
     51                        { 
     52                                isTag = true ; 
     53                                value = match[0] ; 
     54                                this._sourceHtml = sourceHtml.substr( match[0].length ) ; 
     55                        } 
     56                } 
     57                else 
     58                { 
     59                        value = sourceHtml ; 
     60                        this._sourceHtml = null ; 
     61                } 
     62                return { 'isTag' : isTag, 'value' : value } ; 
     63        }, 
     64 
     65        Each : function( func ) 
     66        { 
     67                var chunk ; 
     68                while ( ( chunk = this.Next() ) ) 
     69                        func( chunk.isTag, chunk.value ) ; 
     70        } 
     71} ; 
  • editor/_source/classes/fckstyle.js

     
    747747        }, 
    748748 
    749749        /** 
     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 &nbsp; 
     764                innerHTML = innerHTML.replace( /^[ \t]+|[ \t]+$/g, function( match ) 
     765                                { 
     766                                        return match.replace( /[ \t]/g, '&nbsp;' ) ; 
     767                                } ) ; 
     768 
     769                // 2. Convert \n to <BR>. 
     770                // 3. Convert contiguous (i.e. non-singular) spaces or tabs to &nbsp; 
     771                var htmlIterator = new FCKHtmlIterator( innerHTML ) ; 
     772                var results = [] ; 
     773                htmlIterator.Each( function( isTag, value ) 
     774                        { 
     775                                if ( !isTag ) 
     776                                { 
     777                                        value = value.replace( /\n/g, '<BR>' ) ; 
     778                                        value = value.replace( /[ \t]{2,}/g,  
     779                                                        function ( match ) 
     780                                                        { 
     781                                                                return ' ' + new Array( match.length ).join( '&nbsp;' ) ; 
     782                                                        } ) ; 
     783                                } 
     784                                results.push( value ) ; 
     785                        } ) ; 
     786                newBlock.innerHTML = results.join( '' ) ; 
     787                return newBlock ; 
     788        }, 
     789 
     790        /** 
     791         * Converting from a non-PRE block to a PRE block in formatting operations. 
     792         */ 
     793        _ToPre : function( doc, block, newBlock ) 
     794        { 
     795                // Handle converting from a regular block to a <pre> block. 
     796                var innerHTML = block.innerHTML.Trim() ; 
     797 
     798                // 1. Delete ANSI whitespaces immediately before and after <BR> because they are not visible. 
     799                // 2. Mark down any <BR /> nodes here so they can be turned into \n in the next step and avoid being compressed. 
     800                innerHTML = innerHTML.replace( /[ \t\r\n]*(<br[^>]*>)[ \t\r\n]*/gi, '<BR />' ) ; 
     801 
     802                // 3. Compress other ANSI whitespaces since they're only visible as one single space previously. 
     803                // 4. Convert &nbsp; to spaces since &nbsp; is no longer needed in <PRE>. 
     804                // 5. Convert any <BR /> to \n. This must not be done earlier because the \n would then get compressed. 
     805                var htmlIterator = new FCKHtmlIterator( innerHTML ) ; 
     806                var results = [] ; 
     807                htmlIterator.Each( function( isTag, value ) 
     808                        { 
     809                                if ( !isTag ) 
     810                                        value = value.replace( /([ \t\n\r]+|&nbsp;)/g, ' ' ) ; 
     811                                else if ( isTag && value == '<BR />' ) 
     812                                        value = '\n' ; 
     813                                results.push( value ) ; 
     814                        } ) ; 
     815 
     816                // Assigning innerHTML to <PRE> in IE causes all linebreaks to be reduced to spaces. 
     817                // Assigning outerHTML to <PRE> in IE doesn't work if the <PRE> isn't contained in another node 
     818                // since the node reference is changed after outerHTML assignment. 
     819                // So, we need some hacks to workaround IE bugs here. 
     820                if ( FCKBrowserInfo.IsIE ) 
     821                { 
     822                        var temp = doc.createElement( 'div' ) ; 
     823                        temp.appendChild( newBlock ) ; 
     824                        newBlock.outerHTML = '<PRE>\n' + results.join( '' ) + '</PRE>' ; 
     825                        newBlock = temp.removeChild( temp.firstChild ) ; 
     826                } 
     827                else 
     828                        newBlock.innerHTML = results.join( '' ) ; 
     829                return newBlock ; 
     830        }, 
     831 
     832        /** 
    750833         * Apply an inline style to a FCKDomRange. 
    751834         * 
    752835         * TODO 
     
    759842                var bookmark ; 
    760843 
    761844                if ( selectIt ) 
    762                         bookmark = range.CreateBookmark( true ) ; 
     845                        bookmark = range.CreateBookmark() ; 
    763846 
    764847                var iterator = new FCKDomRangeIterator( range ) ; 
    765848                iterator.EnforceRealBlocks = true ; 
    766849 
    767850                var block ; 
     851                var doc = range.Window.document ; 
     852 
    768853                while( ( block = iterator.GetNextParagraph() ) )                // Only one = 
    769854                { 
    770855                        // Create the new node right before the current one. 
    771                         var newBlock = block.parentNode.insertBefore( this.BuildElement( range.Window.document ), block ) ; 
     856                        var newBlock = this.BuildElement( doc ) ; 
    772857 
    773858                        // Move everything from the current node to the new one. 
    774                         FCKDomTools.MoveChildren( block, newBlock ) ; 
     859                        var newBlockIsPre = newBlock.nodeName.IEquals( 'pre' ) ; 
     860                        var blockIsPre = block.nodeName.IEquals( 'pre' ) ; 
     861                        if ( newBlockIsPre && !blockIsPre ) 
     862                                newBlock = this._ToPre( doc, block, newBlock ) ; 
     863                        else if ( !newBlockIsPre && blockIsPre ) 
     864                                newBlock = this._FromPre( doc, block, newBlock ) ; 
     865                        else    // Convering from a regular block to another regular block. 
     866                                FCKDomTools.MoveChildren( block, newBlock ) ; 
    775867 
    776                         // Delete the current node. 
     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/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/fckhtmliterator.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/fckhtmliterator.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/fckhtmliterator.js" /> 
    255257 
    256258                <File path="editor/_source/classes/fckplugin.js" /> 
    257259                <File path="editor/_source/internals/fckplugins.js" />