Ticket #3165: 3165_3.patch

File 3165_3.patch, 8.1 KB (added by Garry Yao, 10 years ago)
  • _source/plugins/enterkey/plugin.js

     
    101101                if ( !isStartOfBlock && !isEndOfBlock )
    102102                {
    103103                        // If the next block is an <li> with another list tree as the first
    104                         // child, we'll need to append a placeholder or the list item
     104                        // child, we'll need to append a filler (<br>/NBSP) or the list item
    105105                        // wouldn't be editable. (#1420)
    106                         if ( nextBlock.is( 'li' ) && ( node = nextBlock.getFirst() )
    107                                         && node.is && node.is( 'ul', 'ol') )
    108                                 nextBlock.insertBefore( doc.createText( '\xa0' ), node );
     106                        if ( nextBlock.is( 'li' )
     107                                 && ( node = nextBlock.getFirst( CKEDITOR.dom.walker.invisible( true ) ) )
     108                                 && node.is && node.is( 'ul', 'ol' ) )
     109                                ( CKEDITOR.env.ie ? doc.createText( '\xa0' ) : doc.createElement( 'br' ) ).insertBefore( node );
    109110
    110111                        // Move the selection to the end block.
    111112                        if ( nextBlock )
  • _source/core/dom/element.js

     
    627627
    628628                /**
    629629                 * Gets the first child node of this element.
     630                 * @param {Function} evaluator Filtering the result node.
    630631                 * @returns {CKEDITOR.dom.node} The first child node or null if not
    631632                 *              available.
    632633                 * @example
     
    634635                 * var first = <b>element.getFirst()</b>;
    635636                 * alert( first.getName() );  // "b"
    636637                 */
    637                 getFirst : function()
     638                getFirst : function( evaluator )
    638639                {
    639                         var $ = this.$.firstChild;
    640                         return $ ? new CKEDITOR.dom.node( $ ) : null;
     640                        var first = this.$.firstChild,
     641                                retval = first && new CKEDITOR.dom.node( first );
     642                        if ( retval && evaluator && !evaluator( retval ) )
     643                                retval = retval.getNext( evaluator );
     644
     645                        return retval;
    641646                },
    642647
    643648                /**
  • _source/plugins/selection/plugin.js

     
    986986                                // will expand and that the cursor will be blinking on the right place.
    987987                                // Actually, we are using this flag just to avoid using this hack in all
    988988                                // situations, but just on those needed.
    989                                 isStartMarkerAlone = forceExpand || !startNode.hasPrevious() || ( startNode.getPrevious().is && startNode.getPrevious().is( 'br' ) );
     989                                var next = startNode.getNext();
     990                                isStartMarkerAlone = ( !( next && next.getText && next.getText() && !CKEDITOR.tools.trim( next.getText() ) )
     991                                                                          && ( forceExpand || !startNode.hasPrevious() || ( startNode.getPrevious().is && startNode.getPrevious().is( 'br' ) ) ) );
    990992
    991993                                // Append a temporary <span>&#65279;</span> before the selection.
    992994                                // This is needed to avoid IE destroying selections inside empty
  • _source/core/dom/walker.js

     
    408408                        return isReject ^ isWhitespace;
    409409                };
    410410        };
     411
     412        /**
     413         * Whether the node is invisible in wysiwyg mode.
     414         * @param isReject
     415         */
     416        CKEDITOR.dom.walker.invisible = function( isReject )
     417        {
     418                var whitespace = CKEDITOR.dom.walker.whitespaces();
     419                return function( node )
     420                {
     421                        // Nodes that take no spaces in wysiwyg:
     422                        // 1. White-spaces but not including NBSP;
     423                        // 2. Empty inline elements, e.g. <b></b> we're checking here 'offsetHeight'
     424                        // instead of width for properly excluding all sorts of empty paragraph, e.g. <br />.
     425                        var isInvisible = whitespace( node ) || node.is && !node.$.offsetHeight;
     426                        return isReject ^ isInvisible;
     427                };
     428        };
     429
    411430})();
  • _source/plugins/htmldataprocessor/plugin.js

     
    77{
    88        // Regex to scan for &nbsp; at the end of blocks, which are actually placeholders.
    99        // Safari transforms the &nbsp; to \xa0. (#4172)
    10         var tailNbspRegex = /^[\t\r\n ]*(?:&nbsp;|\xa0)$/;
    11 
     10        var tailNbspRegex = /[\t\r\n ]*(?:&nbsp;|\xa0)[\t\r\n ]*$/;
    1211        var protectedSourceMarker = '{cke_protected}';
     12        var dtd = CKEDITOR.dtd;
    1313
    1414
    1515        // Return the last non-space child node of the block (#4344).
     
    2222                return last;
    2323        }
    2424
     25        function indexOfFirstChildElement( element, tagNameList )
     26        {
     27                var children = element.children,
     28                        child,
     29                        length = children.length;
     30                for ( var i = 0; i < length; i++ )
     31                {
     32                        child = children[ i ];
     33                        if( child.name && ( child.name in tagNameList ) )
     34                                return i;
     35                }
     36        }
     37
    2538        function trimFillers( block, fromSource )
    2639        {
    2740                // If the current node is a block, and if we're converting from source or
     
    3548                        if ( ( fromSource || !CKEDITOR.env.ie ) && lastChild.type == CKEDITOR.NODE_ELEMENT && lastChild.name == 'br' )
    3649                                children.pop();
    3750                        if ( lastChild.type == CKEDITOR.NODE_TEXT && tailNbspRegex.test( lastChild.value ) )
    38                                 children.pop();
     51                                lastChild.value = lastChild.value.replace( tailNbspRegex, '' );
    3952                }
    4053        }
    4154
     
    6679                        block.add( new CKEDITOR.htmlParser.text( '\xa0' ) );
    6780        }
    6881
    69         var dtd = CKEDITOR.dtd;
     82        function getExtendNestedListFilter( isHtmlFilter )
     83        {
     84                return function( listItem )
     85                {
     86                        var children = listItem.children,
     87                                firstNestedListIndex = indexOfFirstChildElement( listItem, dtd.$list ),
     88                                firstNestedList = children[ firstNestedListIndex ],
     89                                nodeBefore = firstNestedList && firstNestedList.previous,
     90                                tailNbspmatch;
    7091
     92                        if( nodeBefore
     93                                && ( nodeBefore.name && nodeBefore.name == 'br'
     94                                        || nodeBefore.value && ( tailNbspmatch = nodeBefore.value.match( tailNbspRegex ) ) ) )
     95                        {
     96                                var fillerNode = nodeBefore;
     97
     98                                // Always use 'nbsp' as filler node if we found a nested list appear
     99                                // in front of a list item.
     100                                if ( !( tailNbspmatch && tailNbspmatch.index ) && fillerNode == children[ 0 ] )
     101                                        children[ 0 ] = ( isHtmlFilter || CKEDITOR.env.ie ) ?
     102                                                         new CKEDITOR.htmlParser.text( '\xa0' ) :
     103                                                                         new CKEDITOR.htmlParser.element( 'br', {} );
     104
     105                                // Otherwise the filler is not needed anymore.
     106                                else if ( fillerNode.name == 'br' )
     107                                        children.splice( firstNestedListIndex - 1, 1 );
     108                                else
     109                                        fillerNode.value = fillerNode.value.replace( tailNbspRegex, '' );
     110                        }
     111
     112                };
     113        }
     114
    71115        // Find out the list of block-like tags that can contain <br>.
    72116        var blockLikeTags = CKEDITOR.tools.extend( {}, dtd.$block, dtd.$listItem, dtd.$tableContent );
    73117        for ( var i in blockLikeTags )
     
    93137        for ( i in blockLikeTags )
    94138                defaultDataBlockFilterRules.elements[ i ] = extendBlockForDisplay;
    95139
     140        var defaultListDataFilterRules = { elements : {} };
     141        for( i in dtd.$listItem )
     142                defaultListDataFilterRules.elements[ i ] = getExtendNestedListFilter();
     143
    96144        var defaultHtmlFilterRules =
    97145                {
    98146                        elementNames :
     
    189237        for ( i in blockLikeTags )
    190238                defaultHtmlBlockFilterRules.elements[ i ] = extendBlockForOutput;
    191239
     240        var defaultListHtmlFilterRules = { elements : {} };
     241        for( i in dtd.$listItem )
     242                defaultListHtmlFilterRules.elements[ i ] = getExtendNestedListFilter( true );
     243
    192244        if ( CKEDITOR.env.ie )
    193245        {
    194246                // IE outputs style attribute in capital letters. We should convert
     
    293345
    294346                        dataProcessor.dataFilter.addRules( defaultDataFilterRules );
    295347                        dataProcessor.dataFilter.addRules( defaultDataBlockFilterRules );
     348                        dataProcessor.dataFilter.addRules( defaultListDataFilterRules );
    296349                        dataProcessor.htmlFilter.addRules( defaultHtmlFilterRules );
    297350                        dataProcessor.htmlFilter.addRules( defaultHtmlBlockFilterRules );
     351                        dataProcessor.htmlFilter.addRules( defaultListHtmlFilterRules );
    298352                }
    299353        });
    300354
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy