Ticket #3608: 3608_4.patch

File 3608_4.patch, 9.6 KB (added by Garry Yao, 10 years ago)
  • _source/plugins/list/plugin.js

     
    377377                                                        ( editor.config.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'br' ) );
    378378                                        paragraph.appendTo( body );
    379379                                        ranges = [ new CKEDITOR.dom.range( doc ) ];
    380                                         ranges[0].selectNodeContents( paragraph );
     380                                        // IE exception on inserting anything when anchor inside <br>.
     381                                        if ( paragraph.is( 'br' ) )
     382                                        {
     383                                                ranges[ 0 ].setStartBefore( paragraph );
     384                                                ranges[ 0 ].setEndAfter( paragraph );
     385                                        }
     386                                        else
     387                                                ranges[ 0 ].selectNodeContents( paragraph );
    381388                                        selection.selectRanges( ranges );
    382389                                }
    383390                        }
  • _source/core/dom/range.js

     
    265265        // check(Start|End)OfBlock.
    266266        function getCheckStartEndBlockEvalFunction( isStart )
    267267        {
    268                 var hadBr = false;
     268                var hadBr = false, bookmarkEvaluator = CKEDITOR.dom.walker.bookmark( true );
    269269                return function( node )
    270270                {
     271                        // First ignore bookmark nodes.
     272                        if ( bookmarkEvaluator( node ) )
     273                                return true;
     274
    271275                        if ( node.type == CKEDITOR.NODE_TEXT )
    272276                        {
    273277                                // If there's any visible text, then we're not at the start.
    274278                                if ( CKEDITOR.tools.trim( node.getText() ).length )
    275279                                        return false;
    276                         }
     280                                }
    277281                        else
    278282                        {
    279283                                // If there are non-empty inline elements (e.g. <img />), then we're not
     
    11191123                                case CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS:
    11201124
    11211125                                        // Enlarging the start boundary.
    1122                                         var walkerRange = new CKEDITOR.dom.range( this.document );
    1123                                         walkerRange.setStartAt(
    1124                                                 this.document.getBody(), CKEDITOR.POSITION_AFTER_START );
     1126                                        var walkerRange = new CKEDITOR.dom.range( this.document ),
     1127                                                        body = this.document.getBody();
     1128                                        walkerRange.setStartAt( body, CKEDITOR.POSITION_AFTER_START );
    11251129                                        walkerRange.setEnd( this.startContainer, this.startOffset );
    11261130
    11271131                                        var walker = new CKEDITOR.dom.walker( walkerRange ),
    1128 
    1129                                                 guard = CKEDITOR.dom.walker.blockBoundary(
     1132                                            blockBoundary,  // The node on which the enlarging should stop.
     1133                                                tailBr, //
     1134                                            defaultGuard = CKEDITOR.dom.walker.blockBoundary(
    11301135                                                                ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ? { br : 1 } : null ),
    1131                                                 tailBr,
    1132                                                 listGuard = function( node )
     1136                                                // Record the encountered 'blockBoundary' for later use.
     1137                                                boundaryGuard = function( node )
    11331138                                                {
    1134                                                         var result = guard( node );
    1135                                                         if ( !result && node.is && node.is( 'br' ) )
     1139                                                        var retval = defaultGuard( node );
     1140                                                        if ( !retval )
     1141                                                                blockBoundary = node;
     1142                                                        return retval;
     1143                                                },
     1144                                                // Record the encounted 'tailBr' for later use.
     1145                                                tailBrGuard = function( node )
     1146                                                {
     1147                                                        var retval = boundaryGuard( node );
     1148                                                        if ( !retval && node.is && node.is( 'br' ) )
    11361149                                                                tailBr = node;
    1137                                                         return result;
     1150                                                        return retval;
    11381151                                                };
    1139                                         walker.guard = guard;
    11401152
     1153                                        walker.guard = boundaryGuard;
     1154
     1155
    11411156                                        if ( ( enlargeable = walker.lastBackward() ) )
     1157                                        {
     1158                                                // It's the body which stop the enlaring if no block boundary found.
     1159                                                blockBoundary = blockBoundary || body;
     1160
     1161                                                // Start the range at different position by comparing
     1162                                                // the document position of it with 'enlargeable' node.
    11421163                                                this.setStartAt(
    1143                                                         enlargeable, CKEDITOR.POSITION_BEFORE_START );
     1164                                                                blockBoundary,
     1165                                                                blockBoundary.contains( enlargeable ) ?
     1166                                                                        CKEDITOR.POSITION_AFTER_START :
     1167                                                                        CKEDITOR.POSITION_AFTER_END );
     1168                                        }
    11441169
    11451170                                        // Enlarging the end boundary.
    11461171                                        walkerRange = this.clone();
    11471172                                        walkerRange.collapse();
    1148                                         walkerRange.setEndAt(
    1149                                                 this.document.getBody(), CKEDITOR.POSITION_BEFORE_END );
     1173                                        walkerRange.setEndAt( body, CKEDITOR.POSITION_BEFORE_END );
    11501174                                        walker = new CKEDITOR.dom.walker( walkerRange );
     1175
     1176                                        // tailBrGuard only used for on range end.
    11511177                                        walker.guard = ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ?
    1152                                                  listGuard : guard;
     1178                                                tailBrGuard : boundaryGuard;
     1179                                        blockBoundary = null;
     1180                                        // End the range right before the block boundary node.
     1181                                        ;
    11531182                                        if ( ( enlargeable = walker.lastForward() ) )
    1154                                                         this.setEndAfter( enlargeable );
     1183                                        {
     1184                                                // It's the body which stop the enlaring if no block boundary found.
     1185                                                blockBoundary = blockBoundary || body;
     1186
     1187                                                // Start the range at different position by comparing
     1188                                                // the document position of it with 'enlargeable' node.
     1189                                                this.setEndAt(
     1190                                                                blockBoundary,
     1191                                                                blockBoundary.contains( enlargeable ) ?
     1192                                                                        CKEDITOR.POSITION_BEFORE_END :
     1193                                                                        CKEDITOR.POSITION_BEFORE_START );
     1194                                        }
    11551195                                        // We must include the <br> at the end of range if there's
    11561196                                        // one and we're expanding list item contents
    11571197                                        if ( tailBr )
  • _source/plugins/domiterator/plugin.js

     
    1212(function()
    1313{
    1414
    15         function isBookmarkNode( node )
    16         {
    17                 return ( node && node.getName
    18                                         && node.getName() == 'span'
    19                                         && node.hasAttribute( '_fck_bookmark' ) )
    20                                 ||
    21                                 ( node && !node.getName && isBookmarkNode( node.getParent()) );
    22         }
    23 
    24         function ignoreBookmarkEvaluator( node )
    25         {
    26                 return !isBookmarkNode( node );
    27         }
    28 
    29 
    30         /**
    31          * Find next source order node, ignore bookmark nodes and stop at the specified end node.
    32          * @param {Object} currentNode
    33          * @param {Object} endNode
    34          */
    35         function getNextSourceNode( currentNode, endNode, startFromSibling )
    36         {
    37                 var next = currentNode;
    38                 do
    39                 {
    40                         next = next.getNextSourceNode(
    41                                 startFromSibling, null, endNode );
    42                 }
    43                 while( isBookmarkNode( next ) )
    44                 return next;
    45         }
    46 
    4715        var iterator = function( range )
    4816        {
    4917                if ( arguments.length < 1 )
     
    7947                                range = this.range.clone();
    8048                                range.enlarge( this.forceBrBreak ? CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS );
    8149
    82                                 var walker = new CKEDITOR.dom.walker( range );
    83                                 walker.evaluator = ignoreBookmarkEvaluator;
     50                                var walker = new CKEDITOR.dom.walker( range ),
     51                                        ignoreBookmarkTextEvaluator = CKEDITOR.dom.walker.bookmark( true, true );
     52                                // Avoid anchor inside bookmark inner text.
     53                                walker.evaluator = ignoreBookmarkTextEvaluator;
    8454                                this._.nextNode = walker.next();
    85 
    8655                                // TODO: It's better to have walker.reset() used here.
    8756                                walker = new CKEDITOR.dom.walker( range );
    88                                 walker.evaluator = ignoreBookmarkEvaluator;
     57                                walker.evaluator = ignoreBookmarkTextEvaluator;
    8958                                var lastNode = walker.previous();
    90                                 this._.lastNode = getNextSourceNode( lastNode, null, true );
     59                                this._.lastNode = lastNode.getNextSourceNode( true );
    9160                                // Probably the document end is reached, we need a marker node.
    9261                                if ( !this._.lastNode )
    9362                                {
     
    10271                                lastNode = this._.lastNode;
    10372
    10473                        this._.nextNode = null;
    105 
    10674                        while ( currentNode )
    10775                        {
    10876                                // closeRange indicates that a paragraph boundary has been found,
     
    230198                                if ( isLast )
    231199                                        break;
    232200
    233                                 currentNode = getNextSourceNode( currentNode, lastNode, continueFromSibling );
     201                                currentNode = currentNode.getNextSourceNode( continueFromSibling, null, lastNode );
    234202                        }
    235203
    236204                        // Now, based on the processed range, look for (or create) the block to be returned.
     
    301269                                        // lists) or the next sibling <li>.
    302270
    303271                                        this._.nextNode = ( block.equals( lastNode ) ? null :
    304                                                 getNextSourceNode( range.getBoundaryNodes().endNode, lastNode, true ) );
     272                                                range.getBoundaryNodes().endNode.getNextSourceNode( true, null, lastNode ) );
    305273                                }
    306274                        }
    307275
     
    334302                        if ( !this._.nextNode )
    335303                        {
    336304                                this._.nextNode = ( isLast || block.equals( lastNode ) ) ? null :
    337                                         getNextSourceNode( block, lastNode, true );
     305                                        block.getNextSourceNode( true, null, lastNode );
    338306                        }
    339307
    340308                        return block;
  • _source/core/dom/walker.js

     
    353353        {
    354354                        return this.blockBoundary( { br : 1 } );
    355355        };
     356        /**
     357         * Whether the node is a bookmark node's inner text node.
     358         */
     359        CKEDITOR.dom.walker.bookmarkContents = function( node )
     360        {
     361        },
    356362
     363        /**
     364         * Whether the to-be-evaluated node is a bookmark node OR bookmark node
     365         * inner contents.
     366         * @param {Boolean} contentOnly Whether only test againt the text content of
     367         * bookmark node instead of the element itself(default).
     368         * @param {Boolean} isReject Whether should return 'false' for the bookmark
     369         * node instead of 'true'(default).
     370         */
     371        CKEDITOR.dom.walker.bookmark = function( contentOnly, isReject )
     372        {
     373                function isBookmarkNode( node )
     374                {
     375                        return ( node && node.getName
     376                                        && node.getName() == 'span'
     377                                        && node.hasAttribute('_fck_bookmark') );
     378                }
     379
     380                return function( node )
     381                {
     382                        var retval, parent;
     383                        // Is bookmark inner text node?
     384                        retval = ( node && !node.getName && ( parent = node.getParent() )
     385                                                && isBookmarkNode( parent ) );
     386                        // Is bookmark node?
     387                        retval = contentOnly ? retval : retval || isBookmarkNode( node );
     388                        return isReject ? !retval : !!retval;
     389                };
     390        };
     391
    357392})();
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy