Ticket #3304: 3304_8.patch

File 3304_8.patch, 32.1 KB (added by Garry Yao, 11 years ago)
  • _source/tests/core/dom/range.html

     
    2121
    2222        var doc = new CKEDITOR.dom.document( document );
    2323
     24        var getRange = function( startId, endId )
     25        {
     26                var range = new CKEDITOR.dom.range( CKEDITOR.document );
     27                range.moveToBookmark( { startNode : startId, endNode : endId, serializable : true } );
     28                return range;
     29        };
     30
    2431        return tests = {
    2532                test__constructor : function()
    2633                {
     
    930937                        assert.isFalse( range.collapsed, 'range.collapsed' );
    931938                },
    932939
     940                test_enlarge_list1 : function()
     941                {
     942                        var range = getRange( 'S1', null );
     943                        range.enlarge( CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS );
     944
     945                        assert.areSame( document.getElementById( '_EnlargeP7' ), range.startContainer.$, 'range.startContainer' );
     946                        assert.areSame( 0, range.startOffset, 'range.startOffset' );
     947                        assert.areSame( document.getElementById( '_EnlargeP7' ), range.endContainer.$, 'range.endContainer' );
     948                        assert.areSame( 3, range.endOffset, 'range.endOffset' );
     949                        assert.isFalse( range.collapsed, 'range.collapsed' );
     950                },
     951
     952                test_enlarge_list2 : function()
     953                {
     954                        var range = getRange( 'S2', 'E2' );
     955                        range.enlarge( CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS );
     956
     957                        assert.areSame( document.getElementById( '_EnlargeP8' ), range.startContainer.$, 'range.startContainer' );
     958                        assert.areSame( 0, range.startOffset, 'range.startOffset' );
     959                        assert.areSame( document.getElementById( '_EnlargeP8' ), range.endContainer.$, 'range.endContainer' );
     960                        assert.areSame( 4, range.endOffset, 'range.endOffset' );
     961                        assert.isFalse( range.collapsed, 'range.collapsed' );
     962                },
     963
     964                test_enlarge_list3 : function()
     965                {
     966                        var range = getRange( 'S3', null );
     967                        range.enlarge( CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS );
     968
     969                        assert.areSame( document.getElementById( '_EnlargeP9' ), range.startContainer.$, 'range.startContainer' );
     970                        assert.areSame( 2, range.startOffset, 'range.startOffset' );
     971                        assert.areSame( document.getElementById( '_EnlargeP9' ), range.endContainer.$, 'range.endContainer' );
     972                        assert.areSame( 3, range.endOffset, 'range.endOffset' );
     973                        assert.isFalse( range.collapsed, 'range.collapsed' );
     974                },
     975
     976                test_enlarge_list4 : function()
     977                {
     978                        var range = getRange( 'S4', null );
     979                        range.enlarge( CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS );
     980
     981                        assert.areSame( document.getElementById( '_EnlargeP10' ), range.startContainer.$, 'range.startContainer' );
     982                        assert.areSame( 3, range.startOffset, 'range.startOffset' );
     983                        assert.areSame( document.getElementById( '_EnlargeP10' ), range.endContainer.$, 'range.endContainer' );
     984                        assert.areSame( 5, range.endOffset, 'range.endOffset' );
     985                        assert.isFalse( range.collapsed, 'range.collapsed' );
     986                },
     987
     988                test_enlarge_list5 : function()
     989                {
     990                        var range = getRange( 'S9', null );
     991                        var bookmark = range.createBookmark();
     992                        range.enlarge( CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS );
     993
     994                        assert.areSame( document.getElementById( '_EnlargeP15' ), range.startContainer.$, 'range.startContainer' );
     995                        assert.areSame( 0, range.startOffset, 'range.startOffset' );
     996                        assert.areSame( document.getElementById( '_EnlargeP15' ), range.endContainer.$, 'range.endContainer' );
     997                        assert.areSame( 4, range.endOffset, 'range.endOffset' );
     998                        assert.isFalse( range.collapsed, 'range.collapsed' );
     999                        range.moveToBookmark( bookmark );
     1000                },
     1001
     1002                test_enlarge_block1 : function()
     1003                {
     1004                        var range = getRange( 'S5', null );
     1005                        range.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS );
     1006
     1007                        assert.areSame( document.getElementById( '_EnlargeP11' ), range.startContainer.$, 'range.startContainer' );
     1008                        assert.areSame( 0, range.startOffset, 'range.startOffset' );
     1009                        assert.areSame( document.getElementById( '_EnlargeP11'), range.endContainer.$, 'range.endContainer' );
     1010                        assert.areSame( 5, range.endOffset, 'range.endOffset' );
     1011                        assert.isFalse( range.collapsed, 'range.collapsed' );
     1012                },
     1013
     1014                test_enlarge_block2 : function()
     1015                {
     1016                        var range = getRange( 'S10', null );
     1017                        var bookmark = range.createBookmark();
     1018                        range.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS );
     1019
     1020                        assert.areSame( document.getElementById( '_EnlargeP16' ), range.startContainer.$, 'range.startContainer' );
     1021                        assert.areSame( 0, range.startOffset, 'range.startOffset' );
     1022                        assert.areSame( document.getElementById( '_EnlargeP16'), range.endContainer.$, 'range.endContainer' );
     1023                        assert.areSame( 5, range.endOffset, 'range.endOffset' );
     1024                        assert.isFalse( range.collapsed, 'range.collapsed' );
     1025                        range.moveToBookmark( bookmark );
     1026                },
     1027
     1028                test_enlarge_block3 : function()
     1029                {
     1030                        var range = getRange( 'S6', null );
     1031                        range.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS );
     1032
     1033                        assert.areSame( document.getElementById( '_EnlargeP12' ), range.startContainer.$, 'range.startContainer' );
     1034                        assert.areSame( 0, range.startOffset, 'range.startOffset' );
     1035                        assert.areSame( document.getElementById( '_EnlargeP12'), range.endContainer.$, 'range.endContainer' );
     1036                        assert.areSame( 2, range.endOffset, 'range.endOffset' );
     1037                        assert.isFalse( range.collapsed, 'range.collapsed' );
     1038                },
     1039               
     1040                test_enlarge_block4 : function()
     1041                {
     1042                        var range = getRange( 'S7', null );
     1043                        range.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS );
     1044
     1045                        assert.areSame( document.getElementById( '_EnlargeP13' ), range.startContainer.$, 'range.startContainer' );
     1046                        assert.areSame( 0, range.startOffset, 'range.startOffset' );
     1047                        assert.areSame( document.getElementById( '_EnlargeP13'), range.endContainer.$, 'range.endContainer' );
     1048                        assert.areSame( 2, range.endOffset, 'range.endOffset' );
     1049                        assert.isFalse( range.collapsed, 'range.collapsed' );
     1050                },
     1051
     1052                test_enlarge_block5 : function()
     1053                {
     1054                        var range = getRange( 'S8', null );
     1055                        range.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS );
     1056
     1057                        assert.areSame( document.getElementById( '_EnlargeP14' ), range.startContainer.$, 'range.startContainer' );
     1058                        assert.areSame( 0, range.startOffset, 'range.startOffset' );
     1059                        assert.isTrue( range.collapsed, 'range.collapsed' );
     1060                },
     1061
    9331062                test_deleteContents_W3C_1 : function()
    9341063                {
    9351064                        // W3C DOM Range Specs - Section 2.6 - Example 1
     
    19702099                <p id="_EnlargeP4">Test <i id="_EnlargeI4"> Enlarge</i></p>
    19712100                <p id="_EnlargeP5">Test <i id="_EnlargeI5">Enlarge</i></p>
    19722101                <p id="_EnlargeP6">Test <i id="_EnlargeI6"><b></b>Enlarge</i></p>
     2102                <p id="_EnlargeP7">Test <span id="S1"></span>List<br/ >Item Enlarge</p>
     2103                <p id="_EnlargeP8">Test <span id="S2"></span>List<span id="E2"></span> <br /><br />Item Enlarge</p>
     2104                <p id="_EnlargeP9">Test List <br /><span id="S3"></span><br />Item Enlarge</p>
     2105                <p id="_EnlargeP10">Test List <br /><br />Item<span id="S4"></span> Enlarge</p>
     2106                <p id="_EnlargeP11">Test <strong>Block<span id="S5"></span></strong><br /><br />Enlarge</p>
     2107                <div id="_EnlargeP12">Test<span id="S6"></span> Block <div>Enlarge</div></div>
     2108                <div>Test <div id="_EnlargeP13">Blo<span id="S7"></span>ck</div> Enlarge</div>
     2109                <p id="_EnlargeP14"><span id="S8"></span></p>
     2110                <p id="_EnlargeP15">Test <span id="S9"></span>List<br/ >Item Enlarge</p>
     2111                <p id="_EnlargeP16">Test <strong>Block<span id="S10"></span></strong><br /><br />Enlarge</p>
    19732112        </div>
    19742113        <script type="text/javascript">
    19752114        //<![CDATA[
  • _source/plugins/domiterator/plugin.js

     
    314314                        // above block can be removed or changed, so we can rely on it for the
    315315                        // next interation.
    316316                        if ( !this._.nextNode )
     317                        {
    317318                                this._.nextNode = ( isLast || block.equals( lastNode ) ) ? null :
    318319                                        getNextSourceNode( block, lastNode, true );
     320                        }
    319321
    320322                        return block;
    321323                }
  • _source/plugins/find/dialogs/find.js

     
    55
    66(function()
    77{
    8         // Element tag names which prevent characters counting.
    9         var characterBoundaryElementsEnum =
     8        function guardDomWalkerNonEmptyTextNode( node )
    109        {
    11                 address :1, blockquote :1, dl :1, h1 :1, h2 :1, h3 :1,
    12                 h4 :1, h5 :1, h6 :1, p :1, pre :1, li :1, dt :1, de :1, div :1, td:1, th:1
    13         };
     10                return ( node.type == CKEDITOR.NODE_TEXT && node.getLength() > 0 )
     11        }
    1412
    15         var guardDomWalkerNonEmptyTextNode = function( evt )
     13        /**
     14         * Elements which break characters been considered as sequence.
     15        */
     16        function checkCharactersBoundary ( node )
    1617        {
    17                 if ( evt.data.to && evt.data.to.type == CKEDITOR.NODE_TEXT
    18                         && evt.data.to.$.length > 0 )
    19                         this.stop();
    20                 CKEDITOR.dom.domWalker.blockBoundary( { br : 1 } ).call( this, evt );
    21         };
    22 
     18                var dtd = CKEDITOR.dtd;
     19                return node.isBlockBoundary(
     20                        CKEDITOR.tools.extend( {}, dtd.$empty, dtd.$nonEditable ) );
     21        }
    2322
    2423        /**
    2524         * Get the cursor object which represent both current character and it's dom
     
    3029                var obj = {
    3130                        textNode : this.textNode,
    3231                        offset : this.offset,
    33                         character : this.textNode ? this.textNode.getText().charAt( this.offset ) : null,
     32                        character : this.textNode ?
     33                                this.textNode.getText().charAt( this.offset ) : null,
    3434                        hitMatchBoundary : this._.matchBoundary
    3535                };
    3636                return obj;
     
    7575                 * Iterator which walk through document char by char.
    7676                 * @param {Object} start
    7777                 * @param {Number} offset
     78                 * @param {Boolean} isStrict
    7879                 */
    79                 var characterWalker = function( start, offset )
     80                var characterWalker = function( range , matchWord )
    8081                {
    81                         var isCursor = typeof( start.textNode ) !== 'undefined';
    82                         this.textNode = isCursor ? start.textNode : start;
    83                         this.offset = isCursor ? start.offset : offset;
     82                        var walker =
     83                                new CKEDITOR.dom.walker( range );
     84                        walker[ matchWord ? 'guard' : 'evaluator' ] =
     85                                guardDomWalkerNonEmptyTextNode;
     86                        walker.breakOnFalse = true;
     87
    8488                        this._ = {
    85                                 walker : new CKEDITOR.dom.domWalker( this.textNode ),
     89                                matchWord : matchWord,
     90                                walker : walker,
    8691                                matchBoundary : false
    8792                        };
    8893                };
     
    9095                characterWalker.prototype = {
    9196                        next : function()
    9297                        {
     98                                return this.move();     
     99                        },
     100                       
     101                        back : function()
     102                        {
     103                                return this.move( true );
     104                        },
     105                       
     106                        move : function( rtl )
     107                        {
     108                                var currentTextNode = this.textNode;
    93109                                // Already at the end of document, no more character available.
    94                                 if( !this.textNode )
     110                                if(  currentTextNode === null )
    95111                                        return cursorStep.call( this );
    96112
    97113                                this._.matchBoundary = false;
     
    96112
    97113                                this._.matchBoundary = false;
    98114
    99                                 // If there are more characters in the text node, get it and
    100                                 // raise an event.
    101                                 if( this.textNode.type == CKEDITOR.NODE_TEXT
    102                                         && this.offset < this.textNode.getLength() - 1 )
     115                                // There are more characters in the text node, step forward.
     116                                if( currentTextNode
     117                                    && rtl
     118                                        && this.offset > 0 )
     119                                {
     120                                        this.offset--;
     121                                        return cursorStep.call( this );
     122                                }
     123                                else if( currentTextNode
     124                                        && this.offset < currentTextNode.getLength() - 1 )
    103125                                {
    104126                                        this.offset++;
    105127                                        return cursorStep.call( this );
     
    104126                                        this.offset++;
    105127                                        return cursorStep.call( this );
    106128                                }
    107 
    108                                 // If we are at the end of the text node, use dom walker to get
    109                                 // the next text node.
    110                                 var data = null;
    111                                 while ( !data || ( data.node && data.node.type !=
    112                                         CKEDITOR.NODE_TEXT ) )
     129                                else
    113130                                {
    114                                         data = this._.walker.forward(
    115                                                 guardDomWalkerNonEmptyTextNode );
     131                                        currentTextNode = null;
     132                                        // At the end of the text node, walking foward for the next.
     133                                        while ( !currentTextNode )
     134                                        {
     135                                                currentTextNode =
     136                                                        this._.walker[ rtl ? 'previous' : 'next' ].call( this._.walker );
    116137
    117                                         // Block boundary? BR? Document boundary?
    118                                         if ( !data.node
    119                                                 || ( data.node.type !== CKEDITOR.NODE_TEXT
    120                                                         && data.node.getName() in
    121                                                         characterBoundaryElementsEnum ) )
    122                                                 this._.matchBoundary = true;
    123                                 }
    124                                 this.textNode = data.node;
    125                                 this.offset = 0;
    126                                 return cursorStep.call( this );
    127                         },
     138                                                // Stop searching if we're need full word match OR
     139                                                // already reach document end.
     140                                                if ( this._.matchWord && !currentTextNode
     141                                                         ||this._.walker._.end )
     142                                                        break;
    128143
    129                         back : function()
    130                         {
    131                                 this._.matchBoundary = false;
    132 
    133                                 // More characters -> decrement offset and return.
    134                                 if ( this.textNode.type == CKEDITOR.NODE_TEXT && this.offset > 0 )
    135                                 {
    136                                         this.offset--;
    137                                         return cursorStep.call( this );
     144                                                // Marking as match character boundaries.
     145                                                if( !currentTextNode
     146                                                   && checkCharactersBoundary( this._.walker.current ) )
     147                                                        this._.matchBoundary = true;
     148       
     149                                        }
     150                                        // Found a fresh text node.
     151                                        this.textNode = currentTextNode;
     152                                        if ( currentTextNode )
     153                                                this.offset = rtl ? currentTextNode.getLength() - 1 : 0;
     154                                        else
     155                                                this.offset = 0;
    138156                                }
    139157
    140                                 // Start of text node -> use dom walker to get the previous text node.
    141                                 var data = null;
    142                                 while ( !data
    143                                 || ( data.node && data.node.type != CKEDITOR.NODE_TEXT ) )
    144                                 {
    145                                         data = this._.walker.reverse( guardDomWalkerNonEmptyTextNode );
    146 
    147                                         // Block boundary? BR? Document boundary?
    148                                         if ( !data.node || ( data.node.type !== CKEDITOR.NODE_TEXT &&
    149                                         data.node.getName() in characterBoundaryElementsEnum ) )
    150                                                 this._.matchBoundary = true;
    151                                 }
    152                                 this.textNode = data.node;
    153                                 this.offset = data.node.length - 1;
    154158                                return cursorStep.call( this );
    155159                        }
     160
    156161                };
    157162
    158163                /**
     
    218223                                // node.
    219224                                if ( endNode.getLength() < 1 )
    220225                                {
    221                                         while ( ( endNode = endNode.getPreviousSourceNode() ) && !( endNode.type == CKEDITOR.NODE_TEXT && endNode.getLength() > 0 ) )
     226                                        while ( ( endNode = endNode.getPreviousSourceNode() )
     227                                                   && !( endNode.type == CKEDITOR.NODE_TEXT
     228                                                                        && endNode.getLength() > 0 ) )
    222229                                        { /*jsl:pass*/ }
    223230
    224231                                        endIndex = endNode.getLength();
     
    224231                                        endIndex = endNode.getLength();
    225232                                }
    226233
    227                                 var cursor = new characterWalker( startNode, startIndex );
    228                                 this._.cursors = [ cursor ];
    229                                 if ( !( cursor.textNode.equals( endNode ) && cursor.offset == endIndex - 1 ) )
     234                                // Rebuild the character range.
     235                                var cursor,
     236                                                walker = new characterWalker(
     237                                                                getRangeAfterCursor(
     238                                                                                                        ( { textNode: startNode, offset : startIndex } ),
     239                                                                                                        true ) );
     240                                this._.cursors = [];
     241                                do
    230242                                {
    231                                         do
    232                                         {
    233                                                 cursor = new characterWalker( cursor );
    234                                                 cursor.next();
    235                                                 this._.cursors.push( cursor );
    236                                         }
    237                                         while ( !( cursor.textNode.equals( endNode ) && cursor.offset == endIndex - 1 ) );
     243                                        cursor = walker.next();
     244                                        this._.cursors.push( cursor );
    238245                                }
    239 
     246                                while ( !( cursor.textNode.equals( endNode )
     247                                                         && cursor.offset == endIndex - 1 ) );
    240248                                this._.rangeLength = this._.cursors.length;
    241249                        },
    242250
     
    338346                                return cursors[ cursors.length - 1 ].character;
    339347                        },
    340348
    341                         getNextRange : function( maxLength )
     349                        getNextCharacterRange : function( maxLength )
    342350                        {
    343                                 var cursors = this._.cursors;
    344                                 if ( cursors.length < 1 )
     351                                var lastCursor,
     352                                                cursors = this._.cursors;
     353                                if ( !( lastCursor = cursors[ cursors.length - 1 ] ) )
    345354                                        return null;
    346 
    347                                 var next = new characterWalker( cursors[ cursors.length - 1 ] );
    348                                 return new characterRange( next, maxLength );
     355                                return new characterRange(
     356                                                                                new characterWalker(
     357                                                                                        getRangeAfterCursor( lastCursor ) ),
     358                                                                                maxLength );
    349359                        },
    350 
     360                       
    351361                        getCursors : function()
    352362                        {
    353363                                return this._.cursors;
     
    354364                        }
    355365                };
    356366
     367               
     368                // The remaining document range after the character cursor.
     369                function getRangeAfterCursor( cursor , inclusive )
     370                {
     371                        var range = new CKEDITOR.dom.range();
     372                        range.setStart( cursor.textNode,
     373                                                   ( inclusive ? cursor.offset : cursor.offset + 1 ) );
     374                        range.setEndAt( editor.document.getBody(),
     375                                                        CKEDITOR.POSITION_BEFORE_END );
     376                        return range;
     377                }
     378
     379                // The document range before the character cursor.
     380                function getRangeBeforeCursor( cursor )
     381                {
     382                        var range = new CKEDITOR.dom.range();
     383                        range.setStartAt( editor.document.getBody(),
     384                                                        CKEDITOR.POSITION_AFTER_START );
     385                        range.setEnd( cursor.textNode, cursor.offset );
     386                        return range;
     387                }
     388               
    357389                var KMP_NOMATCH = 0,
    358390                        KMP_ADVANCED = 1,
    359391                        KMP_MATCHED = 2;
     
    430462                };
    431463
    432464                var finder = {
    433                         startCursor : null,
    434                         range : null,
     465                        searchRange : null,
     466                        matchRange : null,
    435467                        find : function( pattern, matchCase, matchWord, matchCyclic )
    436468                        {
    437                                 if( !this.range )
    438                                         this.range = new characterRange( new characterWalker( this.startCursor ), pattern.length );
     469                                if( !this.matchRange )
     470                                        this.matchRange =
     471                                                new characterRange(
     472                                                        new characterWalker( this.searchRange ),
     473                                                        pattern.length );
    439474                                else
    440475                                {
    441                                         this.range.removeHighlight();
    442                                         this.range = this.range.getNextRange( pattern.length );
     476                                        this.matchRange.removeHighlight();
     477                                        this.matchRange = this.matchRange.getNextCharacterRange( pattern.length );
    443478                                }
    444479
    445480                                var matcher = new kmpMatcher( pattern, !matchCase ),
     
    448483
    449484                                while ( character !== null )
    450485                                {
    451                                         this.range.moveNext();
    452                                         while ( ( character = this.range.getEndCharacter() ) )
     486                                        this.matchRange.moveNext();
     487                                        while ( ( character = this.matchRange.getEndCharacter() ) )
    453488                                        {
    454489                                                matchState = matcher.feedCharacter( character );
    455490                                                if ( matchState == KMP_MATCHED )
     
    454489                                                matchState = matcher.feedCharacter( character );
    455490                                                if ( matchState == KMP_MATCHED )
    456491                                                        break;
    457                                                 if ( this.range.moveNext().hitMatchBoundary )
     492                                                if ( this.matchRange.moveNext().hitMatchBoundary )
    458493                                                        matcher.reset();
    459494                                        }
    460495
     
    462497                                        {
    463498                                                if ( matchWord )
    464499                                                {
    465                                                         var cursors = this.range.getCursors(),
     500                                                        var cursors = this.matchRange.getCursors(),
    466501                                                                tail = cursors[ cursors.length - 1 ],
    467                                                                 head = cursors[ 0 ],
    468                                                                 headWalker = new characterWalker( head ),
    469                                                                 tailWalker = new characterWalker( tail );
    470 
     502                                                                head = cursors[ 0 ];
     503                                                                headWalker =
     504                                                                        new characterWalker(
     505                                                                                getRangeBeforeCursor( head ),
     506                                                                        true ),
     507                                                                tailWalker =
     508                                                                        new characterWalker(
     509                                                                                getRangeAfterCursor( tail ),
     510                                                                        true );
    471511                                                        if ( ! ( isWordSeparator(
    472512                                                                                headWalker.back().character )
    473513                                                                                && isWordSeparator(
     
    475515                                                                continue;
    476516                                                }
    477517
    478                                                 this.range.setMatched();
     518                                                this.matchRange.setMatched();
    479519                                                return true;
    480520                                        }
    481521                                }
     
    480520                                        }
    481521                                }
    482522
    483                                 this.range.clearMatched();
    484 
    485                                 // clear current session and restart from beginning
     523                                this.matchRange.clearMatched();
     524                                this.matchRange.removeHighlight();
     525                                // Clear current session and restart with the default search
     526                                // range.
    486527                                if ( matchCyclic )
    487528                                {
    488                                         this.startCursor = getDefaultStartCursor();
    489                                         this.range = null;
     529                                        this.searchRange = getSearchRange( true );
     530                                        this.matchRange = null;
    490531                                }
    491532
    492533                                return false;
     
    530571                }
    531572
    532573                /**
    533                  * Get cursor that indicate search begin with, receive from user
     574                 * The range in which find/replace happened, receive from user
    534575                 * selection prior.
    535576                 */
    536                 function getStartCursor()
     577                function getSearchRange( isDefault )
    537578                {
    538                         var sel = editor.getSelection();
    539                         if ( sel )
     579                        var searchRange,
     580                                sel = editor.getSelection(),
     581                                body = editor.document.getBody();
     582                        if ( sel && !isDefault )
    540583                        {
    541                                 var lastRange = sel.getRanges()[ sel.getRanges().length - 1 ];
    542                                 return {
    543                                         textNode : lastRange.getBoundaryNodes().endNode,
    544                                         offset : lastRange.endContainer.type ===
    545                                                 CKEDITOR.NODE_ELEMENT ?
    546                                                 0       : lastRange.endOffset
    547                                 };
     584                                searchRange = sel.getRanges()[ 0 ].clone();
     585                                searchRange.collapse( true );
    548586                        }
    549587                        else
    550                                 return getDefaultStartCursor();
     588                        {
     589                                searchRange = new CKEDITOR.dom.range();
     590                                searchRange.setStartAt( body, CKEDITOR.POSITION_AFTER_START );
     591                        }
     592                        searchRange.setEndAt( body, CKEDITOR.POSITION_BEFORE_END );
     593                        return searchRange;
    551594                }
    552595
    553596                return {
     
    785828                        onShow : function()
    786829                        {
    787830                                // Establish initial searching start position.
    788                                 finder.startCursor = getStartCursor.call( this );
     831                                finder.searchRange = getSearchRange();
    789832
    790833                                if ( startupPage == 'replace' )
    791834                                        this.getContentElement( 'replace', 'txtFindReplace' ).focus();
     
    794837                        },
    795838                        onHide : function()
    796839                        {
    797                                 if ( finder.range && finder.range.isMatched() )
     840                                if ( finder.matchRange && finder.matchRange.isMatched() )
    798841                                {
    799                                         finder.range.removeHighlight();
     842                                        finder.matchRange.removeHighlight();
    800843                                        editor.focus();
    801844                                        editor.getSelection().selectRanges(
    802                                                 [ finder.range.toDomRange() ] );
     845                                                [ finder.matchRange.toDomRange() ] );
    803846                                }
    804847
    805848                                // Clear current session before dialog close
    806                                 delete finder.range;
     849                                delete finder.matchRange;
    807850                        }
    808851                };
    809852        };
  • _source/core/dom/range.js

     
    263263        // check(Start|End)OfBlock.
    264264        function getCheckStartEndBlockEvalFunction( isStart )
    265265        {
     266                var hadBr = false;
    266267                return function( node )
    267268                {
    268                         var hadBr = false;
    269 
    270269                        if ( node.type == CKEDITOR.NODE_TEXT )
    271270                        {
    272271                                // If there's any visible text, then we're not at the start.
     
    279278                                // at the start.
    280279                                if ( !inlineChildReqElements[ node.getName() ] )
    281280                                {
    282                                         // If we're working at the end-of-block, forgive the first <br />.
    283                                         if ( !isStart && node.getName() == 'br' && !hadBr )
     281                                        // If we're working at the end-of-block, forgive the first <br /> in non-IE
     282                                        // browsers.
     283                                        if ( !isStart && !CKEDITOR.env.ie && node.getName() == 'br' && !hadBr )
    284284                                                hadBr = true;
    285285                                        else
    286286                                                return false;
     
    10871087
    10881088                                case CKEDITOR.ENLARGE_BLOCK_CONTENTS:
    10891089                                case CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS:
    1090                                         // DFS backward to get the block/list item boundary at or before the start.
    10911090
    1092                                         // Get the boundaries nodes.
    1093                                         var startNode = this.getTouchedStartNode(),
    1094                                                 endNode = this.getTouchedEndNode();
    1095 
    1096                                         if ( startNode.type == CKEDITOR.NODE_ELEMENT && startNode.isBlockBoundary() )
    1097                                         {
    1098                                                 this.setStartAt( startNode,
    1099                                                         CKEDITOR.dtd.$empty[ startNode.getName() ] ?
    1100                                                                 CKEDITOR.POSITION_AFTER_END :
    1101                                                                 CKEDITOR.POSITION_AFTER_START );
    1102                                         }
    1103                                         else
    1104                                         {
    1105                                                 // Get the function used to check the enlaarging limits.
    1106                                                 var guardFunction = ( unit == CKEDITOR.ENLARGE_BLOCK_CONTENTS ?
    1107                                                                 CKEDITOR.dom.domWalker.blockBoundary() :
    1108                                                                 CKEDITOR.dom.domWalker.listItemBoundary() );
    1109 
    1110                                                 // Create the DOM walker, which will traverse the DOM.
    1111                                                 var walker = new CKEDITOR.dom.domWalker( startNode );
    1112 
    1113                                                 // Go walk in reverse sense.
    1114                                                 var data = walker.reverse( guardFunction );
    1115 
    1116                                                 var boundaryEvent = data.events.shift();
     1091                                        // Enlarging the start boundary.
     1092                                        var walkerRange = new CKEDITOR.dom.range( this.document );
     1093                                        walkerRange.setStartAt(
     1094                                                this.document.getBody(), CKEDITOR.POSITION_AFTER_START );
     1095                                        walkerRange.setEnd( this.startContainer, this.startOffset );
     1096                                        var walker = new CKEDITOR.dom.walker( walkerRange ),
     1097                                               
     1098                                                guard = CKEDITOR.dom.walker.blockBoundary(
     1099                                                                ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ? { br : 1 } : null ),
     1100                                                tailBr,
     1101                                                listGuard = function( node )
     1102                                                {
     1103                                                        var result = guard( node );
     1104                                                        if ( !result && node.is && node.is( 'br' ) )
     1105                                                                tailBr = node;
     1106                                                        return result;
     1107                                                },
     1108                                                enlargeable;
     1109                                        walker.guard = guard;
     1110                                               
     1111                                        if ( ( enlargeable = walker.lastBackward() ) )
     1112                                                this.setStartAt(
     1113                                                        enlargeable, CKEDITOR.POSITION_BEFORE_START );
    11171114
    1118                                                 this.setStartBefore( boundaryEvent.from );
    1119                                         }
    1120 
    1121                                         if ( endNode.type == CKEDITOR.NODE_ELEMENT && endNode.isBlockBoundary() )
    1122                                         {
    1123                                                 this.setEndAt( endNode,
    1124                                                         CKEDITOR.dtd.$empty[ endNode.getName() ] ?
    1125                                                                 CKEDITOR.POSITION_BEFORE_START :
    1126                                                                 CKEDITOR.POSITION_BEFORE_END );
    1127                                         }
    1128                                         else
    1129                                         {
    1130                                                 // DFS forward to get the block/list item boundary at or before the end.
    1131                                                 walker.setNode( endNode );
    1132                                                 data = walker.forward( guardFunction );
    1133                                                 boundaryEvent = data.events.shift();
    1134 
    1135                                                 this.setEndAfter( boundaryEvent.from );
    1136                                         }
     1115                                        // Enlarging the end boundary.
     1116                                        walkerRange = this.clone();
     1117                                        walkerRange.collapse();
     1118                                        walkerRange.setEndAt(
     1119                                                this.document.getBody(), CKEDITOR.POSITION_BEFORE_END );
     1120                                        walker = new CKEDITOR.dom.walker( walkerRange );
     1121                                        walker.guard = ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ?
     1122                                                 listGuard : guard;
     1123                                        if ( ( enlargeable = walker.lastForward() ) )
     1124                                                        this.setEndAfter( enlargeable );
     1125                                        // We must include the <br> at the end of range if there's
     1126                                        // one and we're expanding list item contents
     1127                                        if ( tailBr )
     1128                                                this.setEndAfter( tailBr );
    11371129                        }
    11381130                },
    11391131
     
    15181510                        if ( this.collapsed || container.type != CKEDITOR.NODE_ELEMENT )
    15191511                                return container ;
    15201512
    1521                         return container.getChild[ this.endOffset - 1 ] || container ;
     1513                        return container.getChild( this.endOffset - 1 ) || container ;
    15221514                }
    15231515        };
    15241516})();
  • _source/core/dom/walker.js

     
    101101                                                node = null;
    102102                                }
    103103                                else
    104                                         node = node.getPreviousSourceNode( true, type, guard );
     104                                        node = ( guard ( node ) === false ) ?
     105                                                null : node.getPreviousSourceNode( true, type, guard );
    105106                        }
    106107                        else
    107108                        {
     
    114115                                                node = null;
    115116                                }
    116117                                else
    117                                         node = range.startContainer.getNextSourceNode( true, type, guard );
     118                                        node = ( guard ( range.startContainer ) === false ) ?
     119                                                null : range.startContainer.getNextSourceNode( true, type, guard ) ;
    118120                        }
    119121                }
    120122
     
    123125                        this.current = node;
    124126
    125127                        if ( !this.evaluator || this.evaluator( node ) !== false )
    126                                 return node;
     128                        {
     129                                if ( !breakOnFalse )
     130                                        return node;
     131                        }
    127132                        else if ( breakOnFalse && this.evaluator )
    128133                                return false;
    129134
     
    134139                return this.current = null;
    135140        }
    136141
    137 //      function iterateToLast( rtl )
    138 //      {
    139 //              var node, last = null;
     142        function iterateToLast( rtl )
     143        {
     144                var node, last = null;
    140145
    141 //              while ( node = iterate.call( this, rtl ) )
    142 //                      last = node;
     146                while ( node = iterate.call( this, rtl ) )
     147                        last = node;
    143148
    144 //              return last;
    145 //      }
     149                return last;
     150        }
    146151
    147152        CKEDITOR.dom.walker = CKEDITOR.tools.createClass(
    148153        {
     
    177182                         * it's to be considered into the walk or not. If not provided, all
    178183                         * matched nodes are considered good.
    179184                         * If the function returns "false" the node is ignored.
    180                          * @name CKEDITOR.pluginDefinition.prototype.evaluator
     185                         * @name CKEDITOR.dom.walker.prototype.evaluator
    181186                         * @property
    182187                         * @type Function
    183188                         */
     
    189194                         * entering and exiting nodes, as well as for the matched nodes.
    190195                         * If this function returns "false", the walking ends and no more
    191196                         * nodes are evaluated.
    192                          * @name CKEDITOR.pluginDefinition.prototype.guard
     197                         * @name CKEDITOR.dom.walker.prototype.guard
    193198                         * @property
    194199                         * @type Function
    195200                         */
     
    214219//                      createOnNodes : function( startNode, endNode, startInclusive, endInclusive )
    215220//                      {
    216221//                              var range = new CKEDITOR.dom.range();
    217 //                              range.setStartAt( startNode, startInclusive ? CKEDITOR.POSITION_BEFORE_START : CKEDITOR.POSITION_AFTER_END ) ;
    218 
     222//                              if ( startNode )
     223//                                      range.setStartAt( startNode, startInclusive ? CKEDITOR.POSITION_BEFORE_START : CKEDITOR.POSITION_AFTER_END ) ;
     224//                              else
     225//                                      range.setStartAt( startNode.getDocument().getBody(), CKEDITOR.POSITION_AFTER_START ) ;
     226//
    219227//                              if ( endNode )
    220228//                                      range.setEndAt( endNode, endInclusive ? CKEDITOR.POSITION_AFTER_END : CKEDITOR.POSITION_BEFORE_START ) ;
    221229//                              else
     
    220228//                                      range.setEndAt( endNode, endInclusive ? CKEDITOR.POSITION_AFTER_END : CKEDITOR.POSITION_BEFORE_START ) ;
    221229//                              else
    222230//                                      range.setEndAt( startNode.getDocument().getBody(), CKEDITOR.POSITION_BEFORE_END ) ;
    223 
     231//
    224232//                              return new CKEDITOR.dom.walker( range );
    225233//                      }
    226234//              },
    227 
     235//
    228236                proto :
    229237                {
    230238                        /**
     
    274282                        checkBackward : function()
    275283                        {
    276284                                return iterate.call( this, true, true ) !== false;
    277                         }
     285                        },
    278286
    279 // The following features have been originally included in the implementation,
    280 // but they are not used anywhere in the code, so they got commented out.
     287                        /**
     288                         * Executes a full walk forward (to the right), until no more nodes
     289                         * are available, returning the last valid node.
     290                         * @returns {CKEDITOR.dom.node} The last node at the right or null
     291                         *              if no valid nodes are available.
     292                         */
     293                        lastForward : function()
     294                        {
     295                                return iterateToLast.call( this );
     296                        },
    281297
    282 //                      /**
    283 //                       * Executes a full walk forward (to the right), until no more nodes
    284 //                       * are available, returning the last valid node.
    285 //                       * @returns {CKEDITOR.dom.node} The last node at the right or null
    286 //                       *              if no valid nodes are available.
    287 //                       */
    288 //                      lastForward : function()
    289 //                      {
    290 //                              return iterateToLast.call( this );
    291 //                      },
     298                        /**
     299                         * Executes a full walk backwards (to the left), until no more nodes
     300                         * are available, returning the last valid node.
     301                         * @returns {CKEDITOR.dom.node} The last node at the left or null
     302                         *              if no valid nodes are available.
     303                         */
     304                        lastBackward : function()
     305                        {
     306                                return iterateToLast.call( this, true );
     307                        }
    292308
    293 //                      /**
    294 //                       * Executes a full walk backwards (to the left), until no more nodes
    295 //                       * are available, returning the last valid node.
    296 //                       * @returns {CKEDITOR.dom.node} The last node at the left or null
    297 //                       *              if no valid nodes are available.
    298 //                       */
    299 //                      lastBackward : function()
    300 //                      {
    301 //                              return iterateToLast.call( this, true );
    302 //                      }
    303309                }
    304310        });
     311
     312        /*
     313         * Anything whose display computed style is block, list-item, table,
     314         * table-row-group, table-header-group, table-footer-group, table-row,
     315         * table-column-group, table-column, table-cell, table-caption, or whose node
     316         * name is hr, br (when enterMode is br only) is a block boundary.
     317         */
     318        var blockBoundaryDisplayMatch =
     319        {
     320                block : 1,
     321                'list-item' : 1,
     322                table : 1,
     323                'table-row-group' : 1,
     324                'table-header-group' : 1,
     325                'table-footer-group' : 1,
     326                'table-row' : 1,
     327                'table-column-group' : 1,
     328                'table-column' : 1,
     329                'table-cell' : 1,
     330                'table-caption' : 1
     331        },
     332        blockBoundaryNodeNameMatch = { hr : 1 };
     333
     334        CKEDITOR.dom.element.prototype.isBlockBoundary = function( customNodeNames )
     335        {
     336                var nodeNameMatches = CKEDITOR.tools.extend( {},
     337                                                                                                        blockBoundaryNodeNameMatch, customNodeNames || {} );
     338
     339                return blockBoundaryDisplayMatch[ this.getComputedStyle( 'display' ) ] ||
     340                        nodeNameMatches[ this.getName() ];
     341        };
     342
     343        CKEDITOR.dom.walker.blockBoundary = function( customNodeNames )
     344        {
     345                return function( node , type )
     346                {
     347                        return ! ( node.type == CKEDITOR.NODE_ELEMENT
     348                                                && node.isBlockBoundary( customNodeNames ) );
     349                };
     350        };
     351       
     352        CKEDITOR.dom.walker.listItemBoundary = function()
     353        {
     354                        return this.blockBoundary( { br : 1 } );
     355        };
     356
    305357})();
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy