Changeset 6495


Ignore:
Timestamp:
02/25/11 14:03:28 (3 years ago)
Author:
garry.yao
Message:

Feature branch for the new "domiterator" plugin.

Location:
CKEditor/branches/features/v4-domiterator
Files:
3 edited
1 copied

Legend:

Unmodified
Added
Removed
  • CKEditor/branches/features/v4-domiterator/_source/core/dom/range.js

    r6461 r6495  
    12721272                                case CKEDITOR.ENLARGE_BLOCK_CONTENTS: 
    12731273                                case CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS: 
     1274                                case CKEDITOR.ENLARGE_BLOCKS: 
     1275                                case CKEDITOR.ENLARGE_LIST_ITEMS: 
    12741276 
    12751277                                        // Enlarging the start boundary. 
     
    12821284 
    12831285                                        var walker = new CKEDITOR.dom.walker( walkerRange ), 
     1286                                                toSkip = CKEDITOR.dom.walker.whitespaces( 1 ), 
    12841287                                            blockBoundary,  // The node on which the enlarging should stop. 
    12851288                                                tailBr, // In case BR as block boundary. 
    12861289                                            notBlockBoundary = CKEDITOR.dom.walker.blockBoundary( 
    1287                                                                 ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ? { br : 1 } : null ), 
     1290                                                                ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS || unit == CKEDITOR.ENLARGE_LIST_ITEMS ) ? { br : 1 } : null ), 
    12881291                                                // Record the encountered 'blockBoundary' for later use. 
    12891292                                                boundaryGuard = function( node ) 
     
    13131316                                        // or at the start of block (<p>[text...), by comparing the document position 
    13141317                                        // with 'enlargeable' node. 
    1315                                         this.setStartAt( 
    1316                                                         blockBoundary, 
    1317                                                         !blockBoundary.is( 'br' ) && 
     1318                                        var fromInside = !blockBoundary.is( 'br' ) && 
    13181319                                                        ( !enlargeable && this.checkStartOfBlock() 
    1319                                                           || enlargeable && blockBoundary.contains( enlargeable ) ) ? 
    1320                                                                 CKEDITOR.POSITION_AFTER_START : 
    1321                                                                 CKEDITOR.POSITION_AFTER_END ); 
     1320                                                                || enlargeable && blockBoundary.contains( enlargeable ) ); 
     1321 
     1322                                        if ( ( unit == CKEDITOR.ENLARGE_BLOCKS || unit == CKEDITOR.ENLARGE_LIST_ITEMS ) && fromInside ) 
     1323                                        { 
     1324                                                while ( ! ( blockBoundary.is( 'body' ) || blockBoundary.getPrevious( toSkip ) ) ) 
     1325                                                        blockBoundary = blockBoundary.getParent(); 
     1326                                                this.setStartBefore( blockBoundary ); 
     1327                                        } 
     1328                                        else 
     1329                                        { 
     1330                                                this.setStartAt( blockBoundary, fromInside ? 
     1331                                                                                CKEDITOR.POSITION_AFTER_START : 
     1332                                                                                CKEDITOR.POSITION_AFTER_END ); 
     1333                                        } 
    13221334 
    13231335                                        // Enlarging the end boundary. 
     
    13281340 
    13291341                                        // tailBrGuard only used for on range end. 
    1330                                         walker.guard = ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ? 
     1342                                        walker.guard = ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS || unit == CKEDITOR.ENLARGE_LIST_ITEMS ) ? 
    13311343                                                tailBrGuard : boundaryGuard; 
    13321344                                        blockBoundary = null; 
     
    13401352                                        // Close the range either before the found block start (text]<p>...</p>) or at the block end (...text]</p>) 
    13411353                                        // by comparing the document position with 'enlargeable' node. 
    1342                                         this.setEndAt( 
    1343                                                         blockBoundary, 
    1344                                                         ( !enlargeable && this.checkEndOfBlock() 
    1345                                                           || enlargeable && blockBoundary.contains( enlargeable ) ) ? 
    1346                                                                 CKEDITOR.POSITION_BEFORE_END : 
    1347                                                                 CKEDITOR.POSITION_BEFORE_START ); 
     1354                                        fromInside = ( !enlargeable && this.checkEndOfBlock() 
     1355                                                        || enlargeable && blockBoundary.contains( enlargeable ) ); 
     1356 
     1357                                        if ( ( unit == CKEDITOR.ENLARGE_BLOCKS || unit == CKEDITOR.ENLARGE_LIST_ITEMS ) && fromInside ) 
     1358                                        { 
     1359                                                while ( ! ( blockBoundary.is( 'body' ) || blockBoundary.getNext( toSkip ) ) ) 
     1360                                                        blockBoundary = blockBoundary.getParent(); 
     1361                                                this.setEndAfter( blockBoundary ); 
     1362                                        } 
     1363                                        else 
     1364                                        { 
     1365                                                this.setEndAt( 
     1366                                                                blockBoundary, fromInside ? 
     1367                                                                        CKEDITOR.POSITION_BEFORE_END : 
     1368                                                                        CKEDITOR.POSITION_BEFORE_START ); 
     1369                                        } 
     1370 
    13481371                                        // We must include the <br> at the end of range if there's 
    13491372                                        // one and we're expanding list item contents 
     
    20202043CKEDITOR.ENLARGE_BLOCK_CONTENTS = 2; 
    20212044CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS = 3; 
     2045CKEDITOR.ENLARGE_BLOCKS = 4; 
     2046CKEDITOR.ENLARGE_LIST_ITEMS = 5; 
    20222047 
    20232048// Check boundary types. 
  • CKEditor/branches/features/v4-domiterator/_source/core/tools.js

    r6348 r6495  
    221221                }, 
    222222 
     223                convertToList : function( list ) 
     224                { 
     225                        var array; 
     226                        if ( CKEDITOR.tools.isArray( list ) ) 
     227                        { 
     228                                array = list; 
     229                                list = {}; 
     230                                for ( var i = 0; i < array.length; i++ ) 
     231                                        list[ array[ i ] ] = 1; 
     232                        } 
     233                        return list; 
     234                }, 
     235 
    223236                /** 
    224237                 * Whether the object contains no properties of it's own. 
  • CKEditor/branches/features/v4-domiterator/_source/plugins/domiterator/plugin.js

    r6368 r6495  
    1515         * @name CKEDITOR.dom.iterator 
    1616         */ 
    17         function iterator( range ) 
     17        function iterator( range, blocklist ) 
    1818        { 
    19                 if ( arguments.length < 1 ) 
    20                         return; 
     19                this.range = range; 
     20                this.enlargeBr = 1; 
     21                blocklist = CKEDITOR.tools.convertToList( blocklist ) || {}; 
    2122 
    22                 this.range = range; 
    23                 this.forceBrBreak = 0; 
    2423 
    25                 // Whether include <br>s into the enlarged range.(#3730). 
    26                 this.enlargeBr = 1; 
    27                 this.enforceRealBlocks = 0; 
     24                var doc = range.document, 
     25                        walker, 
     26                        current, 
     27                        insidePre;  // pre-formatted context indicator. 
    2828 
    29                 this._ || ( this._ = {} ); 
    30         } 
     29                this.getNextParagraph = function( fixBlockTag ) 
     30                { 
     31                        if ( !walker ) 
     32                        { 
     33                                var walkerRange = range.clone(); 
     34                                walkerRange.enlarge( this.enlargeBr ? CKEDITOR.ENLARGE_BLOCKS : CKEDITOR.ENLARGE_LIST_ITEMS ); 
     35                                walkerRange.trim(); 
    3136 
    32         var beginWhitespaceRegex = /^[\r\n\t ]+$/, 
    33                 // Ignore bookmark nodes.(#3783) 
    34                 bookmarkGuard = CKEDITOR.dom.walker.bookmark( false, true ); 
     37                                walker = new CKEDITOR.dom.walker( walkerRange ); 
    3538 
    36         // Get a reference for the next element, bookmark nodes are skipped. 
    37         function getNextSourceNode( node, startFromSibling, lastNode ) 
    38         { 
    39                 var next = node.getNextSourceNode( startFromSibling, null, lastNode ); 
    40                 while ( !bookmarkGuard( next ) ) 
    41                         next = next.getNextSourceNode( startFromSibling, null, lastNode ); 
    42                 return next; 
    43         } 
     39                                var blocker = walkerRange.endContainer.getChild( walkerRange.endOffset - 1 ) || walkerRange.endContainer.getPreviousSourceNode( 1 ); 
     40                                walker.evaluator = function( node ) 
     41                                { 
     42                                        if ( nonBookmark( node ) && nonWhitespaces( node ) ) 
     43                                        { 
     44                                                var position = node.getPosition( blocker ); 
    4445 
    45         iterator.prototype = { 
    46                 getNextParagraph : function( blockTag ) 
    47                 { 
    48                         // The block element to be returned. 
    49                         var block; 
     46                                                // Considers only the nodes that are within the range. 
     47                                                return ! ( position && !( (  position & CKEDITOR.POSITION_PRECEDING + CKEDITOR.POSITION_IS_CONTAINED ) 
     48                                                                && position ^ CKEDITOR.POSITION_PRECEDING + CKEDITOR.POSITION_CONTAINS ) ); 
     49                                        } 
     50                                        else 
     51                                                return false; 
     52                                }; 
    5053 
    51                         // The range object used to identify the paragraph contents. 
    52                         var range; 
     54                                walker.guard = function( node, walkOut ) 
     55                                { 
     56                                        if ( node.type == CKEDITOR.NODE_ELEMENT && node.is( 'pre' ) ) 
     57                                                insidePre = !walkOut; 
     58                                }; 
     59                        } 
    5360 
    54                         // Indicats that the current element in the loop is the last one. 
    55                         var isLast; 
     61                        current = current == undefined ?  walker.next() : current; 
    5662 
    57                         // Indicate at least one of the range boundaries is inside a preformat block. 
    58                         var touchPre; 
     63                        if ( !current ) 
     64                        { 
     65                                walker.reset(); 
     66                                return null; 
     67                        } 
    5968 
    60                         // Instructs to cleanup remaining BRs. 
    61                         var removePreviousBr, removeLastBr; 
     69                        var path, block, checkRange, brToRemove, fixedBlock, lastChild; 
     70                        do 
     71                        { 
     72                                // Block encountered. 
     73                                if ( current.type == CKEDITOR.NODE_ELEMENT && current.isBlockBoundary( !this.enlargeBr && { br : 1 } ) ) 
     74                                { 
     75                                        if ( current.getName() in blocklist ) 
     76                                                block = current; 
     77                                } 
     78                                // At the beginning inside of a block. 
     79                                else 
     80                                { 
     81                                        path = new CKEDITOR.dom.elementPath( current ); 
     82                                        block = path.block; 
    6283 
    63                         // This is the first iteration. Let's initialize it. 
    64                         if ( !this._.lastNode ) 
    65                         { 
    66                                 range = this.range.clone(); 
     84                                        // TODO: We should fix CKEDITOR.dom.elementPath instead. 
    6785 
    68                                 // Shrink the range to exclude harmful "noises" (#4087, #4450, #5435). 
    69                                 range.shrink( CKEDITOR.NODE_ELEMENT, true ); 
     86                                        // Negate any shared (pseudo) blocks that contain more than one block. 
     87                                        // e.g. <li>^pseudo<p>paragraph</p></li> 
     88                                        if ( block ) 
     89                                        { 
     90                                                if ( block.getName() in pathBlockExclusion ) 
     91                                                        block = null; 
     92                                                else 
     93                                                { 
     94                                                        checkRange = new CKEDITOR.dom.range( doc ); 
     95                                                        checkRange.setStartBefore( current ); 
     96                                                        checkRange.enlarge( insidePre || this.enlargeBr ? 
     97                                                                            CKEDITOR.ENLARGE_BLOCK_CONTENTS : CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ); 
     98                                                        var atBlockStart = checkRange.checkStartOfBlock( block ), 
     99                                                                        atBlockEnd = checkRange.checkEndOfBlock( block ); 
     100                                                        if ( ! ( atBlockStart && atBlockEnd ) ) 
     101                                                        { 
     102                                                                if ( !this.enlargeBr ) 
     103                                                                { 
     104                                                                        fixedBlock = block.clone(); 
     105                                                                        brToRemove = brHandler( checkRange ); 
     106                                                                        checkRange.extractContents().appendTo( fixedBlock ); 
     107                                                                        if ( atBlockStart ) 
     108                                                                                fixedBlock.insertBefore( block ); 
     109                                                                        else if ( atBlockEnd ) 
     110                                                                                fixedBlock.insertAfter( block ); 
     111                                                                        else 
     112                                                                                fixedBlock.insertBefore( checkRange.splitBlock().nextBlock ); 
     113                                                                        brToRemove.remove(); 
     114                                                                        block = fixedBlock; 
     115                                                                } 
     116                                                                else 
     117                                                                        block = null; 
     118                                                        } 
     119                                                } 
     120                                        } 
    70121 
    71                                 touchPre = range.endContainer.hasAscendant( 'pre', true ) 
    72                                         || range.startContainer.hasAscendant( 'pre', true ); 
    73  
    74                                 range.enlarge( this.forceBrBreak && !touchPre || !this.enlargeBr ? 
    75                                                            CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS ); 
    76  
    77                                 var walker = new CKEDITOR.dom.walker( range ), 
    78                                         ignoreBookmarkTextEvaluator = CKEDITOR.dom.walker.bookmark( true, true ); 
    79                                 // Avoid anchor inside bookmark inner text. 
    80                                 walker.evaluator = ignoreBookmarkTextEvaluator; 
    81                                 this._.nextNode = walker.next(); 
    82                                 // TODO: It's better to have walker.reset() used here. 
    83                                 walker = new CKEDITOR.dom.walker( range ); 
    84                                 walker.evaluator = ignoreBookmarkTextEvaluator; 
    85                                 var lastNode = walker.previous(); 
    86                                 this._.lastNode = lastNode.getNextSourceNode( true ); 
    87  
    88                                 // We may have an empty text node at the end of block due to [3770]. 
    89                                 // If that node is the lastNode, it would cause our logic to leak to the 
    90                                 // next block.(#3887) 
    91                                 if ( this._.lastNode && 
    92                                                 this._.lastNode.type == CKEDITOR.NODE_TEXT && 
    93                                                 !CKEDITOR.tools.trim( this._.lastNode.getText() ) && 
    94                                                 this._.lastNode.getParent().isBlockBoundary() ) 
    95                                 { 
    96                                         var testRange = new CKEDITOR.dom.range( range.document ); 
    97                                         testRange.moveToPosition( this._.lastNode, CKEDITOR.POSITION_AFTER_END ); 
    98                                         if ( testRange.checkEndOfBlock() ) 
     122                                        if ( !block ) 
    99123                                        { 
    100                                                 var path = new CKEDITOR.dom.elementPath( testRange.endContainer ); 
    101                                                 var lastBlock = path.block || path.blockLimit; 
    102                                                 this._.lastNode = lastBlock.getNextSourceNode( true ); 
     124                                                checkRange = new CKEDITOR.dom.range( doc ); 
     125                                                checkRange.setStartBefore( current ); 
     126                                                if ( !this.enlargeBr ) 
     127                                                { 
     128                                                        fixedBlock = doc.createElement( fixBlockTag || 'p' ); 
     129                                                        checkRange.enlarge( CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ); 
     130                                                        brToRemove = brHandler( checkRange ); 
     131                                                        checkRange.extractContents().appendTo( fixedBlock ); 
     132                                                        checkRange.insertNode( fixedBlock ); 
     133                                                        brToRemove.remove(); 
     134                                                        block = fixedBlock; 
     135                                                } 
     136                                                else 
     137                                                { 
     138                                                        block = checkRange.fixBlock( 1, fixBlockTag || 'p' ); 
     139                                                } 
    103140                                        } 
    104141                                } 
     142                        } 
     143                        while ( !block && ( current = walker.next() ) ); 
    105144 
    106                                 // Probably the document end is reached, we need a marker node. 
    107                                 if ( !this._.lastNode ) 
    108                                 { 
    109                                         this._.lastNode = this._.docEndMarker = range.document.createText( '' ); 
    110                                         this._.lastNode.insertAfter( lastNode ); 
    111                                 } 
     145                        if ( block ) 
     146                        { 
     147                                // Get a reference for the next element. This is important because the 
     148                                // above block can be removed or changed, so we can rely on it for the 
     149                                // next interation. 
    112150 
    113                                 // Let's reuse this variable. 
    114                                 range = null; 
    115                         } 
     151                                current = block; 
     152                                while ( current.type == CKEDITOR.NODE_ELEMENT && ( lastChild = current.getLast() ) ) 
     153                                        current = lastChild; 
    116154 
    117                         var currentNode = this._.nextNode; 
    118                         lastNode = this._.lastNode; 
    119  
    120                         this._.nextNode = null; 
    121                         while ( currentNode ) 
    122                         { 
    123                                 // closeRange indicates that a paragraph boundary has been found, 
    124                                 // so the range can be closed. 
    125                                 var closeRange = 0, 
    126                                         parentPre = currentNode.hasAscendant( 'pre' ); 
    127  
    128                                 // includeNode indicates that the current node is good to be part 
    129                                 // of the range. By default, any non-element node is ok for it. 
    130                                 var includeNode = ( currentNode.type != CKEDITOR.NODE_ELEMENT ), 
    131                                         continueFromSibling = 0; 
    132  
    133                                 // If it is an element node, let's check if it can be part of the 
    134                                 // range. 
    135                                 if ( !includeNode ) 
    136                                 { 
    137                                         var nodeName = currentNode.getName(); 
    138  
    139                                         if ( currentNode.isBlockBoundary( this.forceBrBreak && 
    140                                                         !parentPre && { br : 1 } ) ) 
    141                                         { 
    142                                                 // <br> boundaries must be part of the range. It will 
    143                                                 // happen only if ForceBrBreak. 
    144                                                 if ( nodeName == 'br' ) 
    145                                                         includeNode = 1; 
    146                                                 else if ( !range && !currentNode.getChildCount() && nodeName != 'hr' ) 
    147                                                 { 
    148                                                         // If we have found an empty block, and haven't started 
    149                                                         // the range yet, it means we must return this block. 
    150                                                         block = currentNode; 
    151                                                         isLast = currentNode.equals( lastNode ); 
    152                                                         break; 
    153                                                 } 
    154  
    155                                                 // The range must finish right before the boundary, 
    156                                                 // including possibly skipped empty spaces. (#1603) 
    157                                                 if ( range ) 
    158                                                 { 
    159                                                         range.setEndAt( currentNode, CKEDITOR.POSITION_BEFORE_START ); 
    160  
    161                                                         // The found boundary must be set as the next one at this 
    162                                                         // point. (#1717) 
    163                                                         if ( nodeName != 'br' ) 
    164                                                                 this._.nextNode = currentNode; 
    165                                                 } 
    166  
    167                                                 closeRange = 1; 
    168                                         } 
    169                                         else 
    170                                         { 
    171                                                 // If we have child nodes, let's check them. 
    172                                                 if ( currentNode.getFirst() ) 
    173                                                 { 
    174                                                         // If we don't have a range yet, let's start it. 
    175                                                         if ( !range ) 
    176                                                         { 
    177                                                                 range = new CKEDITOR.dom.range( this.range.document ); 
    178                                                                 range.setStartAt( currentNode, CKEDITOR.POSITION_BEFORE_START ); 
    179                                                         } 
    180  
    181                                                         currentNode = currentNode.getFirst(); 
    182                                                         continue; 
    183                                                 } 
    184                                                 includeNode = 1; 
    185                                         } 
    186                                 } 
    187                                 else if ( currentNode.type == CKEDITOR.NODE_TEXT ) 
    188                                 { 
    189                                         // Ignore normal whitespaces (i.e. not including &nbsp; or 
    190                                         // other unicode whitespaces) before/after a block node. 
    191                                         if ( beginWhitespaceRegex.test( currentNode.getText() ) ) 
    192                                                 includeNode = 0; 
    193                                 } 
    194  
    195                                 // The current node is good to be part of the range and we are 
    196                                 // starting a new range, initialize it first. 
    197                                 if ( includeNode && !range ) 
    198                                 { 
    199                                         range = new CKEDITOR.dom.range( this.range.document ); 
    200                                         range.setStartAt( currentNode, CKEDITOR.POSITION_BEFORE_START ); 
    201                                 } 
    202  
    203                                 // The last node has been found. 
    204                                 isLast = ( ( !closeRange || includeNode ) && currentNode.equals( lastNode ) ); 
    205  
    206                                 // If we are in an element boundary, let's check if it is time 
    207                                 // to close the range, otherwise we include the parent within it. 
    208                                 if ( range && !closeRange ) 
    209                                 { 
    210                                         while ( !currentNode.getNext( bookmarkGuard ) && !isLast ) 
    211                                         { 
    212                                                 var parentNode = currentNode.getParent(); 
    213  
    214                                                 if ( parentNode.isBlockBoundary( this.forceBrBreak 
    215                                                                 && !parentPre && { br : 1 } ) ) 
    216                                                 { 
    217                                                         closeRange = 1; 
    218                                                         isLast = isLast || ( parentNode.equals( lastNode) ); 
    219                                                         break; 
    220                                                 } 
    221  
    222                                                 currentNode = parentNode; 
    223                                                 includeNode = 1; 
    224                                                 isLast = ( currentNode.equals( lastNode ) ); 
    225                                                 continueFromSibling = 1; 
    226                                         } 
    227                                 } 
    228  
    229                                 // Now finally include the node. 
    230                                 if ( includeNode ) 
    231                                         range.setEndAt( currentNode, CKEDITOR.POSITION_AFTER_END ); 
    232  
    233                                 currentNode = getNextSourceNode ( currentNode, continueFromSibling, lastNode ); 
    234                                 isLast = !currentNode; 
    235  
    236                                 // We have found a block boundary. Let's close the range and move out of the 
    237                                 // loop. 
    238                                 if ( isLast || ( closeRange && range ) ) 
    239                                                 break; 
    240                         } 
    241  
    242                         // Now, based on the processed range, look for (or create) the block to be returned. 
    243                         if ( !block ) 
    244                         { 
    245                                 // If no range has been found, this is the end. 
    246                                 if ( !range ) 
    247                                 { 
    248                                         this._.docEndMarker && this._.docEndMarker.remove(); 
    249                                         this._.nextNode = null; 
    250                                         return null; 
    251                                 } 
    252  
    253                                 var startPath = new CKEDITOR.dom.elementPath( range.startContainer ); 
    254                                 var startBlockLimit = startPath.blockLimit, 
    255                                         checkLimits = { div : 1, th : 1, td : 1 }; 
    256                                 block = startPath.block; 
    257  
    258                                 if ( !block 
    259                                                 && !this.enforceRealBlocks 
    260                                                 && checkLimits[ startBlockLimit.getName() ] 
    261                                                 && range.checkStartOfBlock() 
    262                                                 && range.checkEndOfBlock() ) 
    263                                         block = startBlockLimit; 
    264                                 else if ( !block || ( this.enforceRealBlocks && block.getName() == 'li' ) ) 
    265                                 { 
    266                                         // Create the fixed block. 
    267                                         block = this.range.document.createElement( blockTag || 'p' ); 
    268  
    269                                                 // Move the contents of the temporary range to the fixed block. 
    270                                                 range.extractContents().appendTo( block ); 
    271                                                 block.trim(); 
    272  
    273                                                 // Insert the fixed block into the DOM. 
    274                                                 range.insertNode( block ); 
    275  
    276                                                 removePreviousBr = removeLastBr = true; 
    277                                         } 
    278                                 else if ( block.getName() != 'li' ) 
    279                                 { 
    280                                         // If the range doesn't includes the entire contents of the 
    281                                         // block, we must split it, isolating the range in a dedicated 
    282                                         // block. 
    283                                         if ( !range.checkStartOfBlock() || !range.checkEndOfBlock() ) 
    284                                         { 
    285                                                 // The resulting block will be a clone of the current one. 
    286                                                 block = block.clone( false ); 
    287  
    288                                                 // Extract the range contents, moving it to the new block. 
    289                                                 range.extractContents().appendTo( block ); 
    290                                                 block.trim(); 
    291  
    292                                                 // Split the block. At this point, the range will be in the 
    293                                                 // right position for our intents. 
    294                                                 var splitInfo = range.splitBlock(); 
    295  
    296                                                 removePreviousBr = !splitInfo.wasStartOfBlock; 
    297                                                 removeLastBr = !splitInfo.wasEndOfBlock; 
    298  
    299                                                 // Insert the new block into the DOM. 
    300                                                 range.insertNode( block ); 
    301                                         } 
    302                                 } 
    303                                 else if ( !isLast ) 
    304                                 { 
    305                                         // LIs are returned as is, with all their children (due to the 
    306                                         // nested lists). But, the next node is the node right after 
    307                                         // the current range, which could be an <li> child (nested 
    308                                         // lists) or the next sibling <li>. 
    309  
    310                                         this._.nextNode = ( block.equals( lastNode ) ? null : getNextSourceNode( range.getBoundaryNodes().endNode, 1, lastNode ) ); 
    311                                 } 
    312                         } 
    313  
    314                         if ( removePreviousBr ) 
    315                         { 
    316                                 var previousSibling = block.getPrevious(); 
    317                                 if ( previousSibling && previousSibling.type == CKEDITOR.NODE_ELEMENT ) 
    318                                 { 
    319                                         if ( previousSibling.getName() == 'br' ) 
    320                                                 previousSibling.remove(); 
    321                                         else if ( previousSibling.getLast() && previousSibling.getLast().$.nodeName.toLowerCase() == 'br' ) 
    322                                                 previousSibling.getLast().remove(); 
    323                                 } 
    324                         } 
    325  
    326                         if ( removeLastBr ) 
    327                         { 
    328                                 var lastChild = block.getLast(); 
    329                                 if ( lastChild && lastChild.type == CKEDITOR.NODE_ELEMENT && lastChild.getName() == 'br' ) 
    330                                 { 
    331                                         // Take care not to remove the block expanding <br> in non-IE browsers. 
    332                                         if ( CKEDITOR.env.ie 
    333                                                  || lastChild.getPrevious( bookmarkGuard ) 
    334                                                  || lastChild.getNext( bookmarkGuard ) ) 
    335                                                 lastChild.remove(); 
    336                                 } 
    337                         } 
    338  
    339                         // Get a reference for the next element. This is important because the 
    340                         // above block can be removed or changed, so we can rely on it for the 
    341                         // next interation. 
    342                         if ( !this._.nextNode ) 
    343                         { 
    344                                 this._.nextNode = ( isLast || block.equals( lastNode ) ) ? null : 
    345                                         getNextSourceNode( block, 1, lastNode ); 
     155                                walker.current = current; 
     156                                current = walker.next(); 
    346157                        } 
    347158 
    348159                        return block; 
    349160                } 
     161        } 
     162 
     163        CKEDITOR.dom.range.prototype.createIterator = function( blockList ) 
     164        { 
     165                return new iterator( this, blockList ); 
    350166        }; 
    351167 
    352         CKEDITOR.dom.range.prototype.createIterator = function() 
     168        function brHandler( range ) 
    353169        { 
    354                 return new iterator( this ); 
    355         }; 
     170                var startBoundary = range.getTouchedStartNode(), 
     171                        endBoundary = range.getTouchedEndNode(), 
     172                        toRemove = [ startBoundary.getPrevious(), startBoundary, endBoundary ]; 
     173 
     174                for ( var i = 0; i < toRemove.length; i++ ) 
     175                { 
     176                        var node = toRemove[ i ]; 
     177                        if ( !( node && node.type == CKEDITOR.NODE_ELEMENT && node.is( 'br' ) ) ) 
     178                                toRemove.splice( i, 1 ); 
     179                } 
     180 
     181                return { 
     182                        remove : function() 
     183                        { 
     184                                for ( var i = 0; i < toRemove.length; i++ ) 
     185                                        toRemove[ i ].remove(); 
     186                        } 
     187                } 
     188        } 
     189 
     190        var nonWhitespaces = CKEDITOR.dom.walker.whitespaces( 1 ), 
     191                nonBookmark = CKEDITOR.dom.walker.bookmark( 0, 1 ); 
     192 
     193        var pathBlockExclusion = { address:1,blockquote:1,dl:1,dt:1,dd:1,li:1 }; 
     194 
    356195})(); 
Note: See TracChangeset for help on using the changeset viewer.
© 2003 – 2012 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy