Ticket #3176: 3176_2.patch

File 3176_2.patch, 8.3 KB (added by Martin Kou, 15 years ago)
  • _source/plugins/find/dialogs/find.js

     
    88        // Element tag names which prevent characters counting.
    99        var characterBoundaryElementsEnum =
    1010        {
    11                 address :1, blockquote :1, dl :1, h1 :1, h2 :1, h3 :1,
     11                body :1, address :1, blockquote :1, dl :1, h1 :1, h2 :1, h3 :1,
    1212                h4 :1, h5 :1, h6 :1, p :1, pre :1, li :1, dt :1, de :1, div :1, td:1, th:1
    1313        };
    1414
     
    2727         */
    2828        var cursorStep = function()
    2929        {
     30                if( !this.textNode )
     31                        return null;
     32
    3033                var obj = {
    3134                        textNode : this.textNode,
    3235                        offset : this.offset,
    33                         character : this.textNode ? this.textNode.getText().charAt( this.offset ) : null,
     36                        character : this.textNode.getText().charAt( this.offset ),
    3437                        hitMatchBoundary : this._.matchBoundary
    3538                };
    3639                return obj;
     
    8891                };
    8992
    9093                characterWalker.prototype = {
     94                       
     95                        current : function()
     96                        {
     97                                return cursorStep.call( this );
     98                        },
     99                       
    91100                        next : function()
    92101                        {
    93102                                // Already at the end of document, no more character available.
     
    107116
    108117                                // If we are at the end of the text node, use dom walker to get
    109118                                // the next text node.
    110                                 var data = null;
    111                                 while ( !data || ( data.node && data.node.type !=
    112                                         CKEDITOR.NODE_TEXT ) )
     119                                var data;
     120                                do
    113121                                {
    114122                                        data = this._.walker.forward(
    115123                                                guardDomWalkerNonEmptyTextNode );
     
    119127                                                || ( data.node.type !== CKEDITOR.NODE_TEXT
    120128                                                        && data.node.getName() in
    121129                                                        characterBoundaryElementsEnum ) )
     130                                        {
    122131                                                this._.matchBoundary = true;
     132                                               
     133                                                // Scope to content within body.
     134                                                if ( data.node && data.node.getName() == 'body' )
     135                                                {
     136                                                        data.textNode = null;
     137                                                        break;
     138                                                }
     139                                        }
    123140                                }
     141                                while ( data.node && data.node.type != CKEDITOR.NODE_TEXT );
     142                                       
    124143                                this.textNode = data.node;
    125144                                this.offset = 0;
    126145                                return cursorStep.call( this );
     
    128147
    129148                        back : function()
    130149                        {
     150                                // Already at the start of document, no more character available.
     151                                if( this.textNode == null )
     152                                        return null;
     153                               
    131154                                this._.matchBoundary = false;
    132155
    133156                                // More characters -> decrement offset and return.
     
    139162
    140163                                // Start of text node -> use dom walker to get the previous text node.
    141164                                var data = null;
    142                                 while ( !data
    143                                 || ( data.node && data.node.type != CKEDITOR.NODE_TEXT ) )
     165                                do
    144166                                {
    145167                                        data = this._.walker.reverse( guardDomWalkerNonEmptyTextNode );
    146168
    147169                                        // Block boundary? BR? Document boundary?
    148170                                        if ( !data.node || ( data.node.type !== CKEDITOR.NODE_TEXT &&
    149171                                        data.node.getName() in characterBoundaryElementsEnum ) )
     172                                        {
    150173                                                this._.matchBoundary = true;
     174                                               
     175                                                // Scope to characters within body
     176                                                if ( data.node && data.node.getName() == 'body' )
     177                                                {
     178                                                        data.node = null;
     179                                                        break;
     180                                                }
     181                                        }
    151182                                }
     183                                while ( data.node && data.node.type != CKEDITOR.NODE_TEXT );
     184
    152185                                this.textNode = data.node;
    153                                 this.offset = data.node.length - 1;
     186                                this.offset = this.textNode? data.node.length - 1 : 0;
    154187                                return cursorStep.call( this );
    155188                        }
    156189                };
     
    194227                                var startNode = domRange.startContainer,
    195228                                        startIndex = domRange.startOffset,
    196229                                        endNode = domRange.endContainer,
    197                                         endIndex = domRange.endOffset,
    198                                         boundaryNodes = domRange.getBoundaryNodes();
     230                                        endIndex = domRange.endOffset;
    199231
    200232                                if ( startNode.type != CKEDITOR.NODE_TEXT )
    201233                                {
    202                                         startNode = boundaryNodes.startNode;
     234                                        startNode = domRange.getTouchedStartNode();
    203235                                        while ( startNode.type != CKEDITOR.NODE_TEXT )
    204                                                 startNode = startNode.getFirst();
     236                                                startNode = startNode.getNextSourceNode();
    205237                                        startIndex = 0;
    206238                                }
    207239
    208240                                if ( endNode.type != CKEDITOR.NODE_TEXT )
    209241                                {
    210                                         endNode = boundaryNodes.endNode;
     242                                        endNode = domRange.getTouchedEndNode();
    211243                                        while ( endNode.type != CKEDITOR.NODE_TEXT )
    212                                                 endNode = endNode.getLast();
    213                                         endIndex = endNode.getLength();
     244                                                endNode = endNode.getPreviousSourceNode();
     245                                        endIndex = endNode.getLength() - 1;
    214246                                }
    215247
    216248                                // If the endNode is an empty text node, our walker would just walk through
    217249                                // it without stopping. So need to backtrack to the nearest non-emtpy text
    218250                                // node.
    219                                 if ( endNode.getLength() < 1 )
     251                                if ( endNode && endNode.getLength() < 1 )
    220252                                {
    221253                                        while ( ( endNode = endNode.getPreviousSourceNode() ) && !( endNode.type == CKEDITOR.NODE_TEXT && endNode.getLength() > 0 ) )
    222                                         { /*jsl:pass*/ }
    223 
    224                                         endIndex = endNode.getLength();
     254                                                endIndex = endNode.getLength() - 1;
    225255                                }
    226256
    227                                 var cursor = new characterWalker( startNode, startIndex );
    228                                 this._.cursors = [ cursor ];
    229                                 if ( !( cursor.textNode.equals( endNode ) && cursor.offset == endIndex - 1 ) )
     257                                var walker = new characterWalker( startNode, startIndex ), cursor;
     258                               
     259                                // DomRange contains at least one character.
     260                                ( this._.cursors = [] ).push( cursor = walker.current() );
     261                                do
    230262                                {
    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 ) );
     263                                        cursor = walker.next();
     264                                        this._.cursors.push( cursor );
    238265                                }
     266                                while ( !( cursor.textNode.equals( endNode ) && cursor.offset == endIndex ) );
    239267
    240268                                this._.rangeLength = this._.cursors.length;
    241269                        },
     
    303331                                var retval = this._.walker.back(),
    304332                                        cursors = this._.cursors;
    305333
    306                                 if ( retval.hitMatchBoundary )
     334                                if ( !retval || retval.hitMatchBoundary )
    307335                                        this._.cursors = cursors = [];
    308 
     336                                if( retval )
     337                                {
    309338                                cursors.unshift( retval );
    310339                                if ( cursors.length > this._.rangeLength )
    311340                                        cursors.pop();
     341                                }
    312342
    313343                                return retval;
    314344                        },
     
    319349                                        cursors = this._.cursors;
    320350
    321351                                // Clear the cursors queue if we've crossed a match boundary.
    322                                 if ( retval.hitMatchBoundary )
     352                                if ( !retval || retval.hitMatchBoundary )
    323353                                        this._.cursors = cursors = [];
     354                               
     355                                if ( retval )
     356                                {
     357                                        cursors.push( retval );
     358                                        if ( cursors.length > this._.rangeLength )
     359                                                cursors.shift();
     360                                }
    324361
    325                                 cursors.push( retval );
    326                                 if ( cursors.length > this._.rangeLength )
    327                                         cursors.shift();
    328 
    329362                                return retval;
    330363                        },
    331364
     
    454487                                                matchState = matcher.feedCharacter( character );
    455488                                                if ( matchState == KMP_MATCHED )
    456489                                                        break;
    457                                                 if ( this.range.moveNext().hitMatchBoundary )
     490                                                var next = this.range.moveNext();
     491                                                if ( next && next.hitMatchBoundary )
    458492                                                        matcher.reset();
    459493                                        }
    460494
     
    466500                                                                tail = cursors[ cursors.length - 1 ],
    467501                                                                head = cursors[ 0 ],
    468502                                                                headWalker = new characterWalker( head ),
    469                                                                 tailWalker = new characterWalker( tail );
     503                                                                tailWalker = new characterWalker( tail ),
     504                                                                headBoundaryCursor = headWalker.back(),
     505                                                                tailBoundaryCursor = tailWalker.next();
    470506
    471                                                         if ( ! ( isWordSeparator(
    472                                                                                 headWalker.back().character )
    473                                                                                 && isWordSeparator(
    474                                                                                 tailWalker.next().character ) ) )
    475                                                                 continue;
     507                                                        if ( !( ( !headBoundaryCursor
     508                                                                || headBoundaryCursor.hitMatchBoundary
     509                                                                || isWordSeparator( headBoundaryCursor.character ) )
     510                                                                &&
     511                                                                ( !tailBoundaryCursor
     512                                                                || tailBoundaryCursor.hitMatchBoundary
     513                                                                || isWordSeparator( tailBoundaryCursor.character ) ) ) )
     514                                                                {
     515                                                                        matchState = KMP_NOMATCH;
     516                                                                        matcher.reset();
     517                                                                        continue;
     518                                                                }
    476519                                                }
    477520
    478521                                                this.range.setMatched();
  • _source/core/dom/range.js

     
    15251525                        if ( this.collapsed || container.type != CKEDITOR.NODE_ELEMENT )
    15261526                                return container ;
    15271527
    1528                         return container.getChild[ this.endOffset - 1 ] || container ;
     1528                        return container.getChild( this.endOffset - 1 )|| container ;
    15291529                }
    15301530        };
    15311531})();
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy