Ticket #2871: 2871_4.patch

File 2871_4.patch, 21.8 KB (added by Martin Kou, 12 years ago)
  • _source/plugins/domiterator/plugin.js

     
     1/*
     2Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
     3For licensing, see LICENSE.html or http://ckeditor.com/license
     4*/
     5
     6/**
     7 * @file DOM iterator, which iterates over list items, lines and paragraphs.
     8 */
     9
     10CKEDITOR.plugins.add( 'domiterator' );
     11
     12(function()
     13{
     14        // Functions ported over from v2.
     15        function getTouchedStartNode( range )
     16        {
     17                var container = range.startContainer;
     18
     19                if ( range.collapsed || container.type != CKEDITOR.NODE_ELEMENT )
     20                        return container;
     21
     22                return container.getChildCount() > range.startOffset ? container.getChild( range.startOffset ) : container;
     23        }
     24
     25        function getTouchedEndNode( range )
     26        {
     27                var container = range.endContainer;
     28
     29                if ( range.collapsed || container.type != CKEDITOR.NODE_ELEMENT )
     30                        return container;
     31
     32                return container.getChildCount() > range.endOffset ? container.getChild( range.endOffset ) : container;
     33        }
     34       
     35        function getNextSourceNode( currentNode, startFromSibling, nodeType, stopSearchNode )
     36        {
     37                if ( !currentNode )
     38                        return null;
     39
     40                var node;
     41
     42                if ( !startFromSibling && currentNode.getFirst && currentNode.getFirst() )
     43                        node = currentNode.getFirst();
     44                else
     45                {
     46                        if ( stopSearchNode && currentNode.equals( stopSearchNode ) )
     47                                return null;
     48
     49                        node = currentNode.getNext();
     50
     51                        if ( !node && ( !stopSearchNode || !stopSearchNode.equals( currentNode.parentNode ) ) )
     52                                return getNextSourceNode( currentNode.getParent(), true, nodeType, stopSearchNode );
     53                }
     54
     55                if ( nodeType && node && node.type != nodeType )
     56                        return getNextSourceNode( node, false, nodeType, stopSearchNode );
     57
     58                return node;
     59        }
     60
     61        var iterator = function( range )
     62        {
     63                if ( arguments.length < 1 )
     64                        return;
     65
     66                this.range = range;
     67                this.forceBrBreak = false;
     68                this.enforceRealBlocks = false;
     69
     70                this._ || ( this._ = {} );
     71        },
     72                beginWhitespaceRegex = /^[\r\n\t ]+$/;
     73
     74
     75        iterator.prototype = {
     76                getNextParagraph : function( blockTag )
     77                {
     78                        // The block element to be returned.
     79                        var block;
     80
     81                        // The range object used to identify the paragraph contents.
     82                        var range;
     83
     84                        // Indicats that the current element in the loop is the last one.
     85                        var isLast;
     86
     87                        // Instructs to cleanup remaining BRs.
     88                        var removePreviousBr, removeLastBr;
     89
     90                        // This is the first iteration. Let's initialize it.
     91                        if ( !this._.lastNode )
     92                        {
     93                                range = this.range.clone();
     94                                range.enlarge( this.forceBrBreak ? CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS );
     95
     96                                this._.nextNode = getTouchedStartNode( range );
     97                                this._.lastNode = getTouchedEndNode( range );
     98
     99                                // Let's reuse this variable.
     100                                range = null;
     101                        }
     102
     103                        var currentNode = this._.nextNode,
     104                                lastNode = this._.lastNode;
     105
     106                        this._.nextNode = null;
     107
     108                        while ( currentNode )
     109                        {
     110                                // closeRange indicates that a paragraph boundary has been found,
     111                                // so the range can be closed.
     112                                var closeRange = false;
     113
     114                                // includeNode indicates that the current node is good to be part
     115                                // of the range. By default, any non-element node is ok for it.
     116                                var includeNode = ( currentNode.type != CKEDITOR.NODE_ELEMENT ),
     117                                        continueFromSibling = false;
     118
     119                                // If it is an element node, let's check if it can be part of the
     120                                // range.
     121                                if ( !includeNode )
     122                                {
     123                                        var nodeName = currentNode.getName();
     124
     125                                        if ( currentNode.isBlockBoundary( this.forceBrBreak && { br : 1 } ) )
     126                                        {
     127                                                // <br> boundaries must be part of the range. It will
     128                                                // happen only if ForceBrBreak.
     129                                                if ( nodeName == 'br' )
     130                                                        includeNode = true;
     131                                                else if ( !range && currentNode.getChildCount() == 0 && nodeName != 'hr' )
     132                                                {
     133                                                        // If we have found an empty block, and haven't started
     134                                                        // the range yet, it means we must return this block.
     135                                                        block = currentNode;
     136                                                        isLast = currentNode.equals( lastNode );
     137                                                        break;
     138                                                }
     139
     140                                                // The range must finish right before the boundary,
     141                                                // including possibly skipped empty spaces. (#1603)
     142                                                if ( range )
     143                                                {
     144                                                        range.setEndAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
     145
     146                                                        // The found boundary must be set as the next one at this
     147                                                        // point. (#1717)
     148                                                        if ( nodeName != 'br' )
     149                                                                this._.nextNode = getNextSourceNode( currentNode, true, null, lastNode ) || currentNode;
     150                                                }
     151
     152                                                closeRange = true;
     153                                        }
     154                                        else
     155                                        {
     156                                                // If we have child nodes, let's check them.
     157                                                if ( currentNode.getFirst() )
     158                                                {
     159                                                        // If we don't have a range yet, let's start it.
     160                                                        if ( !range )
     161                                                        {
     162                                                                range = new CKEDITOR.dom.range( this.range.document );
     163                                                                range.setStartAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
     164                                                        }
     165
     166                                                        currentNode = currentNode.getFirst();
     167                                                        continue;
     168                                                }
     169                                                includeNode = true;
     170                                        }
     171                                }
     172                                else if ( currentNode.type == CKEDITOR.NODE_TEXT )
     173                                {
     174                                        // Ignore normal whitespaces (i.e. not including &nbsp; or
     175                                        // other unicode whitespaces) before/after a block node.
     176                                        if ( beginWhitespaceRegex.test( currentNode.getText() ) )
     177                                                includeNode = false;
     178                                }
     179
     180                                // The current node is good to be part of the range and we are
     181                                // starting a new range, initialize it first.
     182                                if ( includeNode && !range )
     183                                {
     184                                        range = new CKEDITOR.dom.range( this.range.document );
     185                                        range.setStartAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
     186                                }
     187
     188                                // The last node has been found.
     189                                isLast = ( ( !closeRange || includeNode ) && currentNode.equals( lastNode ) );
     190
     191                                // If we are in an element boundary, let's check if it is time
     192                                // to close the range, otherwise we include the parent within it.
     193                                if ( range && !closeRange )
     194                                {
     195                                        while ( !currentNode.getNext() && !isLast )
     196                                        {
     197                                                var parentNode = currentNode.getParent();
     198
     199                                                if ( parentNode.isBlockBoundary( this.forceBrBreak && { br : 1 } ) )
     200                                                {
     201                                                        closeRange = true;
     202                                                        isLast = isLast || ( parentNode.equals( lastNode) );
     203                                                        break;
     204                                                }
     205
     206                                                currentNode = parentNode;
     207                                                includeNode = true;
     208                                                isLast = ( currentNode.equals( lastNode ) );
     209                                                continueFromSibling = true;
     210                                        }
     211                                }
     212
     213                                // Now finally include the node.
     214                                if ( includeNode )
     215                                        range.setEndAt( currentNode, CKEDITOR.POSITION_AFTER_END );
     216
     217                                // We have found a block boundary. Let's close the range and move out of the
     218                                // loop.
     219                                if ( ( closeRange || isLast ) && range )
     220                                {
     221                                        var boundaryNodes = range.getBoundaryNodes(),
     222                                                startPath = new CKEDITOR.dom.elementPath( range.startContainer ),
     223                                                endPath = new CKEDITOR.dom.elementPath( range.endContainer );
     224                                        if ( boundaryNodes.startNode.equals( boundaryNodes.endNode )
     225                                                        && boundaryNodes.startNode.getParent().equals( startPath.blockLimit )
     226                                                        && boundaryNodes.startNode.type == CKEDITOR.NODE_ELEMENT && boundaryNodes.startNode.getAttribute( '_fck_bookmark' ) )
     227                                                range = null;
     228                                        else
     229                                                break;
     230                                }
     231
     232                                if ( isLast )
     233                                        break;
     234
     235                                currentNode = getNextSourceNode( currentNode, continueFromSibling, null, lastNode );
     236                        }
     237
     238                        // Now, based on the processed range, look for (or create) the block to be returned.
     239                        if ( !block )
     240                        {
     241                                // If no range has been found, this is the end.
     242                                if ( !range )
     243                                {
     244                                        this._.nextNode = null;
     245                                        return null;
     246                                }
     247
     248                                var startPath = new CKEDITOR.dom.elementPath( range.startContainer ),
     249                                        startBlockLimit = startPath.blockLimit,
     250                                        checkLimits = { div : 1, th : 1, td : 1 };
     251                                block = startPath.block;
     252
     253                                if ( !block
     254                                                && !this.enforceRealBlocks
     255                                                && checkLimits[ startBlockLimit.getName() ]
     256                                                && range.checkStartOfBlock()
     257                                                && range.checkEndOfBlock() )
     258                                        block = startBlockLimit;
     259                                else if ( !block || ( this.enforceRealBlocks && block.getName() == 'li' ) )
     260                                {
     261                                        // Create the fixed block.
     262                                        block = this.range.document.createElement( blockTag || 'p' );
     263
     264                                        // Move the contents of the temporary range to the fixed block.
     265                                        range.extractContents().appendTo( block );
     266                                        block.trim();
     267
     268                                        // Insert the fixed block into the DOM.
     269                                        range.insertNode( block );
     270
     271                                        removePreviousBr = removeLastBr = true;
     272                                }
     273                                else if ( block.getName() != 'li' )
     274                                {
     275                                        // If the range doesn't includes the entire contents of the
     276                                        // block, we must split it, isolating the range in a dedicated
     277                                        // block.
     278                                        if ( !range.checkStartOfBlock() || !range.checkEndOfBlock() )
     279                                        {
     280                                                // The resulting block will be a clone of the current one.
     281                                                block = block.clone( false );
     282
     283                                                // Extract the range contents, moving it to the new block.
     284                                                range.extractContents().appendTo( block );
     285                                                block.trim();
     286
     287                                                // Split the block. At this point, the range will be in the
     288                                                // right position for our intents.
     289                                                var splitInfo = range.splitBlock();
     290
     291                                                removePreviousBr = !splitInfo.wasStartOfBlock;
     292                                                removeLastBr = !splitInfo.wasEndOfBlock;
     293
     294                                                // Insert the new block into the DOM.
     295                                                range.insertNode( block );
     296                                        }
     297                                }
     298                                else if ( !isLast )
     299                                {
     300                                        // LIs are returned as is, with all their children (due to the
     301                                        // nested lists). But, the next node is the node right after
     302                                        // the current range, which could be an <li> child (nested
     303                                        // lists) or the next sibling <li>.
     304
     305                                        this._.nextNode = ( block.equals( lastNode ) ? null :
     306                                                        getNextSourceNode( range.getBoundaryNodes().endNode, true, null, lastNode ) );
     307                                }
     308                        }
     309
     310                        if ( removePreviousBr )
     311                        {
     312                                var previousSibling = block.getPrevious();
     313                                if ( previousSibling && previousSibling.type == CKEDITOR.NODE_ELEMENT )
     314                                {
     315                                        if ( previousSibling.getName() == 'br' )
     316                                                previousSibling.remove();
     317                                        else if ( previousSibling.getLast() && previousSibling.getLast().$.nodeName.toLowerCase() == 'br' )
     318                                                previousSibling.getLast().remove();
     319                                }
     320                        }
     321
     322                        if ( removeLastBr )
     323                        {
     324                                var lastChild = block.getLast();
     325                                if ( lastChild && lastChild.type == CKEDITOR.NODE_ELEMENT && lastChild.getName() == 'br' )
     326                                        lastChild.remove();
     327                        }
     328
     329                        // Get a reference for the next element. This is important because the
     330                        // above block can be removed or changed, so we can rely on it for the
     331                        // next interation.
     332                        if ( !this._.nextNode )
     333                                this._.nextNode = ( isLast || block.equals( lastNode ) ) ? null : getNextSourceNode( block, true, null, lastNode );
     334
     335                        return block;
     336                }
     337        };
     338
     339        CKEDITOR.dom.range.prototype.createIterator = function()
     340        {
     341                return new iterator( this );
     342        };
     343})();
  • _source/core/dom/domwalker.js

    Property changes on: _source/plugins/domiterator/plugin.js
    ___________________________________________________________________
    Added: svn:executable
       + *
    
     
    179179                }
    180180        };
    181181
     182        /*
     183         * Anything whose display computed style is block, list-item, table,
     184         * table-row-group, table-header-group, table-footer-group, table-row,
     185         * table-column-group, table-column, table-cell, table-caption, or whose node
     186         * name is hr, br (when enterMode is br only) is a block boundary.
     187         */
     188        var blockBoundaryDisplayMatch =
     189        {
     190                block : 1,
     191                'list-item' : 1,
     192                table : 1,
     193                'table-row-group' : 1,
     194                'table-header-group' : 1,
     195                'table-footer-group' : 1,
     196                'table-row' : 1,
     197                'table-column-group' : 1,
     198                'table-column' : 1,
     199                'table-cell' : 1,
     200                'table-caption' : 1
     201        },
     202                blockBoundaryNodeNameMatch = { hr : 1 };
     203
     204        CKEDITOR.dom.element.prototype.isBlockBoundary = function( customNodeNames )
     205        {
     206                var nodeNameMatches = CKEDITOR.tools.extend( {}, blockBoundaryNodeNameMatch, customNodeNames || {} );
     207
     208                return blockBoundaryDisplayMatch[ this.getComputedStyle( 'display' ) ] ||
     209                        nodeNameMatches[ this.getName() ];
     210        };
     211
    182212        CKEDITOR.dom.domWalker.blockBoundary = function( customNodeNames )
    183213        {
    184214                return function( evt )
    185215                {
    186                         /*
    187                          * Anything whose display computed style is block, list-item, table,
    188                          * table-row-group, table-header-group, table-footer-group, table-row,
    189                          * table-column-group, table-column, table-cell, table-caption, or whose node
    190                          * name is hr, br (when enterMode is br only) is a block boundary.
    191                          */
    192                         var displayMatches = { block : 1, 'list-item' : 1, table : 1, 'table-row-group' : 1, 'table-header-group' : 1,
    193                                 'table-footer-group' : 1, 'table-row' : 1, 'table-column-group' : 1, 'table-column' : 1, 'table-cell' : 1,
    194                                 'table-caption' : 1 },
    195                                 nodeNameMatches = CKEDITOR.tools.extend( { hr : 1 }, customNodeNames || {} ),
    196                                 to = evt.data.to,
     216                        var to = evt.data.to,
    197217                                from = evt.data.from;
    198218                        if ( to && to.type == CKEDITOR.NODE_ELEMENT )
    199219                        {
    200                                 if ( displayMatches[ to.getComputedStyle( 'display' ) ] || nodeNameMatches[ to.getName() ] )
     220                                if ( to.isBlockBoundary( customNodeNames ) )
    201221                                {
    202222                                        evt.stop();
    203223                                        this.stop();
     
    206226                        }
    207227                        if ( ( evt.data.type == 'up' || evt.data.type == 'sibling' ) && from && from.type == CKEDITOR.NODE_ELEMENT )
    208228                        {
    209                                 if ( displayMatches[ from.getComputedStyle( 'display' ) ] || nodeNameMatches[ from.getName() ] )
     229                                if ( from.isBlockBoundary( customNodeNames ) )
    210230                                {
    211231                                        evt.stop();
    212232                                        this.stop();
  • _source/core/dom/node.js

     
    422422                {
    423423                        this.insertBefore( nodeToReplace );
    424424                        nodeToReplace.remove();
     425                },
     426
     427                trim : function()
     428                {
     429                        this.ltrim();
     430                        this.rtrim();
     431                },
     432
     433                ltrim : function()
     434                {
     435                        var child;
     436                        while ( this.getFirst && ( child = this.getFirst() ) )
     437                        {
     438                                if ( child.type == CKEDITOR.NODE_TEXT )
     439                                {
     440                                        var trimmed = CKEDITOR.tools.ltrim( child.getText() ),
     441                                                originalLength = child.getLength();
     442
     443                                        if ( trimmed.length == 0 )
     444                                        {
     445                                                child.remove();
     446                                                continue;
     447                                        }
     448                                        else if ( trimmed.length < originalLength )
     449                                        {
     450                                                child.split( originalLength - trimmed.length );
     451
     452                                                // IE BUG: child.remove() may raise JavaScript errors here. (#81)
     453                                                this.$.removeChild( this.$.firstChild );
     454                                        }
     455                                }
     456                                break;
     457                        }
     458                },
     459
     460                rtrim : function()
     461                {
     462                        var child;
     463                        while ( this.getLast && ( child = this.getLast() ) )
     464                        {
     465                                if ( child.type == CKEDITOR.NODE_TEXT )
     466                                {
     467                                        var trimmed = CKEDITOR.tools.rtrim( child.getText() ),
     468                                                originalLength = child.getLength();
     469
     470                                        if ( trimmed.length == 0 )
     471                                        {
     472                                                child.remove();
     473                                                continue;
     474                                        }
     475                                        else if ( trimmed.length < originalLength )
     476                                        {
     477                                                child.split( trimmed.length );
     478
     479                                                // IE BUG: child.getNext().remove() may raise JavaScript errors here.
     480                                                // (#81)
     481                                                this.$.lastChild.parentNode.removeChild( this.$.lastChild );
     482                                        }
     483                                }
     484                                break;
     485                        }
     486
     487                        if ( !CKEDITOR.env.ie && !CKEDITOR.env.opera )
     488                        {
     489                                child = this.$.lastChild;
     490
     491                                if ( child && child.type == 1 && child.nodeName.toLowerCase() == 'br' )
     492                                {
     493                                        // Use "eChildNode.parentNode" instead of "node" to avoid IE bug (#324).
     494                                        child.parentNode.removeChild( child ) ;
     495                                }
     496                        }
    425497                }
    426498        }
    427499);
  • _source/core/dom/range.js

     
    259259
    260260        var inlineChildReqElements = { abbr:1,acronym:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,'var':1 };
    261261
    262         var getBoundaryNodes = function()
    263         {
    264                 var startNode = this.startContainer,
    265                         endNode = this.endContainer,
    266                         startOffset = this.startOffset,
    267                         endOffset = this.endOffset,
    268                         childCount;
    269 
    270                 if ( startNode.type == CKEDITOR.NODE_ELEMENT )
    271                 {
    272                         childCount = startNode.getChildCount();
    273                         if ( childCount > startOffset )
    274                                 startNode = startNode.getChild( startOffset );
    275                         else if ( childCount < 1 )
    276                                 startNode = startNode.getPreviousSourceNode();
    277                         else            // startOffset > childCount but childCount is not 0
    278                         {
    279                                 // Try to take the node just after the current position.
    280                                 startNode = startNode.$;
    281                                 while ( startNode.lastChild )
    282                                         startNode = startNode.lastChild;
    283                                 startNode = new CKEDITOR.dom.node( startNode );
    284 
    285                                 // Normally we should take the next node in DFS order. But it
    286                                 // is also possible that we've already reached the end of
    287                                 // document.
    288                                 startNode = startNode.getNextSourceNode() || startNode;
    289                         }
    290                 }
    291                 if ( endNode.type == CKEDITOR.NODE_ELEMENT )
    292                 {
    293                         childCount = endNode.getChildCount();
    294                         if ( childCount > endOffset )
    295                                 endNode = endNode.getChild( endOffset ).getPreviousSourceNode();
    296                         else if ( childCount < 1 )
    297                                 endNode = endNode.getPreviousSourceNode();
    298                         else            // endOffset > childCount but childCount is not 0
    299                         {
    300                                 // Try to take the node just before the current position.
    301                                 endNode = endNode.$;
    302                                 while ( endNode.lastChild )
    303                                         endNode = endNode.lastChild;
    304                                 endNode = new CKEDITOR.dom.node( endNode );
    305                         }
    306                 }
    307 
    308                 return { startNode : startNode, endNode : endNode };
    309         };
    310 
    311262        // Check every node between the block boundary and the startNode or endNode.
    312263        var getCheckStartEndBlockFunction = function( isStart )
    313264        {
     
    478429                                this.collapse( true );
    479430                },
    480431
     432                getBoundaryNodes : function()
     433                {
     434                        var startNode = this.startContainer,
     435                                endNode = this.endContainer,
     436                                startOffset = this.startOffset,
     437                                endOffset = this.endOffset,
     438                                childCount;
     439
     440                        if ( startNode.type == CKEDITOR.NODE_ELEMENT )
     441                        {
     442                                childCount = startNode.getChildCount();
     443                                if ( childCount > startOffset )
     444                                        startNode = startNode.getChild( startOffset );
     445                                else if ( childCount < 1 )
     446                                        startNode = startNode.getPreviousSourceNode();
     447                                else            // startOffset > childCount but childCount is not 0
     448                                {
     449                                        // Try to take the node just after the current position.
     450                                        startNode = startNode.$;
     451                                        while ( startNode.lastChild )
     452                                                startNode = startNode.lastChild;
     453                                        startNode = new CKEDITOR.dom.node( startNode );
     454
     455                                        // Normally we should take the next node in DFS order. But it
     456                                        // is also possible that we've already reached the end of
     457                                        // document.
     458                                        startNode = startNode.getNextSourceNode() || startNode;
     459                                }
     460                        }
     461                        if ( endNode.type == CKEDITOR.NODE_ELEMENT )
     462                        {
     463                                childCount = endNode.getChildCount();
     464                                if ( childCount > endOffset )
     465                                        endNode = endNode.getChild( endOffset ).getPreviousSourceNode();
     466                                else if ( childCount < 1 )
     467                                        endNode = endNode.getPreviousSourceNode();
     468                                else            // endOffset > childCount but childCount is not 0
     469                                {
     470                                        // Try to take the node just before the current position.
     471                                        endNode = endNode.$;
     472                                        while ( endNode.lastChild )
     473                                                endNode = endNode.lastChild;
     474                                        endNode = new CKEDITOR.dom.node( endNode );
     475                                }
     476                        }
     477
     478                        return { startNode : startNode, endNode : endNode };
     479                },
     480
    481481                getCommonAncestor : function( includeSelf )
    482482                {
    483483                        var start = this.startContainer;
     
    969969                                case CKEDITOR.ENLARGE_BLOCK_CONTENTS:
    970970                                case CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS:
    971971                                        // DFS backward to get the block/list item boundary at or before the start.
    972                                         var boundaryNodes = getBoundaryNodes.apply( this ),
     972                                        var boundaryNodes = this.getBoundaryNodes(),
    973973                                                startNode = boundaryNodes.startNode,
    974974                                                endNode = boundaryNodes.endNode,
    975975                                                guardFunction = ( unit == CKEDITOR.ENLARGE_BLOCK_CONTENTS ?
     
    11551155                        updateCollapsed( this );
    11561156                },
    11571157
    1158                 // TODO: The fixed block isn't trimmed, does not work for <pre>.
    11591158                // TODO: Does not add bogus <br> to empty fixed blocks.
    11601159                fixBlock : function( isStart, blockTag )
    11611160                {
     
    11641163                        this.collapse( isStart );
    11651164                        this.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS );
    11661165                        this.extractContents().appendTo( fixedBlock );
     1166                        fixedBlock.trim();
    11671167                        this.insertNode( fixedBlock );
    11681168                        this.moveToBookmark( bookmark );
    11691169                        return fixedBlock;
     
    12601260                                        return false;
    12611261                        }
    12621262
    1263                         var startNode = getBoundaryNodes.apply( this ).startNode,
     1263                        var startNode = this.getBoundaryNodes().startNode,
    12641264                                walker = new CKEDITOR.dom.domWalker( startNode );
    12651265
    12661266                        // DFS backwards until the block boundary, with the checker function.
     
    12841284                                        return false;
    12851285                        }
    12861286
    1287                         var endNode = getBoundaryNodes.apply( this ).endNode,
     1287                        var endNode = this.getBoundaryNodes().endNode,
    12881288                                walker = new CKEDITOR.dom.domWalker( endNode );
    12891289
    12901290                        // DFS forward until the block boundary, with the checker function.
  • _source/core/dom/documentFragment.js

     
    1818
    1919                append : elementPrototype.append,
    2020
     21                getFirst : elementPrototype.getFirst,
     22
     23                getLast : elementPrototype.getLast,
     24
    2125                appendTo : function( targetElement )
    2226                {
    2327                        if ( CKEDITOR.env.ie )
© 2003 – 2020 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy