Ticket #1355: 1355_6.patch

File 1355_6.patch, 10.9 kB (added by martinkou, 6 months ago)
  • 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} ; 
     72/* 
     73 * FCKeditor - The text editor for Internet - http://www.fckeditor.net 
     74 * Copyright (C) 2003-2007 Frederico Caldeira Knabben 
     75 * 
     76 * == BEGIN LICENSE == 
     77 * 
     78 * Licensed under the terms of any of the following licenses at your 
     79 * choice: 
     80 * 
     81 *  - GNU General Public License Version 2 or later (the "GPL") 
     82 *    http://www.gnu.org/licenses/gpl.html 
     83 * 
     84 *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL") 
     85 *    http://www.gnu.org/licenses/lgpl.html 
     86 * 
     87 *  - Mozilla Public License Version 1.1 or later (the "MPL") 
     88 *    http://www.mozilla.org/MPL/MPL-1.1.html 
     89 * 
     90 * == END LICENSE == 
     91 * 
     92 * This class can be used to interate through nodes inside a range. 
     93 * 
     94 * During interation, the provided range can become invalid, due to document 
     95 * mutations, so CreateBookmark() used to restore it after processing, if 
     96 * needed. 
     97 */ 
     98 
     99var FCKHtmlIterator = function( source ) 
     100{ 
     101        this._sourceHtml = source ; 
     102} 
     103FCKHtmlIterator.prototype =  
     104{ 
     105        Next : function() 
     106        { 
     107                var sourceHtml = this._sourceHtml ; 
     108                if ( sourceHtml == null ) 
     109                        return null ; 
     110 
     111                var match = FCKRegexLib.HtmlTag.exec( sourceHtml ) ; 
     112                var isTag = false ; 
     113                var value = "" ; 
     114                if ( match ) 
     115                { 
     116                        if ( match.index > 0 ) 
     117                        { 
     118                                value = sourceHtml.substr( 0, match.index ) ; 
     119                                this._sourceHtml = sourceHtml.substr( match.index ) ; 
     120                        } 
     121                        else 
     122                        { 
     123                                isTag = true ; 
     124                                value = match[0] ; 
     125                                this._sourceHtml = sourceHtml.substr( match[0].length ) ; 
     126                        } 
     127                } 
     128                else 
     129                { 
     130                        value = sourceHtml ; 
     131                        this._sourceHtml = null ; 
     132                } 
     133                return { 'isTag' : isTag, 'value' : value } ; 
     134        }, 
     135 
     136        Each : function( func ) 
     137        { 
     138                var chunk ; 
     139                while ( ( chunk = this.Next() ) ) 
     140                        func( chunk.isTag, chunk.value ) ; 
     141        } 
     142} ; 
  • 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, offset, s ) 
     765                                { 
     766                                        if ( match.length == 1 )        // one space, preserve it 
     767                                                return '&nbsp;' ; 
     768                                        else if ( offset == 0 )         // beginning of block 
     769                                                return new Array( match.length ).join( '&nbsp;' ) + ' ' ; 
     770                                        else                            // end of block 
     771                                                return ' ' + new Array( match.length ).join( '&nbsp;' ) ; 
     772                                } ) ; 
     773 
     774                // 2. Convert \n to <BR>. 
     775                // 3. Convert contiguous (i.e. non-singular) spaces or tabs to &nbsp; 
     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( '&nbsp;' ) + ' ' ; 
     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 &nbsp; to spaces since &nbsp; 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]+|&nbsp;)/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        /** 
    750838         * Apply an inline style to a FCKDomRange. 
    751839         * 
    752840         * TODO 
     
    759847                var bookmark ; 
    760848 
    761849                if ( selectIt ) 
    762                         bookmark = range.CreateBookmark( true ) ; 
     850                        bookmark = range.CreateBookmark() ; 
    763851 
    764852                var iterator = new FCKDomRangeIterator( range ) ; 
    765853                iterator.EnforceRealBlocks = true ; 
    766854 
    767855                var block ; 
     856                var doc = range.Window.document ; 
     857 
    768858                while( ( block = iterator.GetNextParagraph() ) )                // Only one = 
    769859                { 
    770860                        // Create the new node right before the current one. 
    771                         var newBlock = block.parentNode.insertBefore( this.BuildElement( range.Window.document ), block ) ; 
     861                        var newBlock = this.BuildElement( doc ) ; 
    772862 
    773863                        // Move everything from the current node to the new one. 
    774                         FCKDomTools.MoveChildren( block, newBlock ) ; 
     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 ) ; 
    775872 
    776                         // Delete the current node. 
     873                        // Replace the current block. 
     874                        block.parentNode.insertBefore( newBlock, block ) ; 
    777875                        FCKDomTools.RemoveNode( block ) ; 
    778876                } 
    779877 
     
    782880                        range.SelectBookmark( bookmark ) ; 
    783881 
    784882                if ( updateRange ) 
    785                         range.MoveToBookmark( range ) ; 
     883                        range.MoveToBookmark( bookmark ) ; 
    786884        }, 
    787885 
    788886        /** 
  • 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" />