Ticket #1355: 1355_6.patch

File 1355_6.patch, 10.9 KB (added by Martin Kou, 12 years 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" />
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy