Ticket #3176: 3176.patch

File 3176.patch, 8.8 KB (added by Garry Yao, 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.
     
    92101                        {
    93102                                // Already at the end of document, no more character available.
    94103                                if( this.textNode == null )
    95                                         return cursorStep.call( this );
     104                                        return null;
    96105                                       
    97106                                this._.matchBoundary = false;
    98107                               
     
    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 !=
     142                                        CKEDITOR.NODE_TEXT )
     143                                       
    124144                                this.textNode = data.node;
    125145                                this.offset = 0;
    126146                                return cursorStep.call( this );
     
    128148                       
    129149                        back : function()
    130150                        {
     151                                // Already at the start of document, no more character available.
     152                                if( this.textNode == null )
     153                                        return null;
     154                               
    131155                                this._.matchBoundary = false;
    132156
    133157                                // More characters -> decrement offset and return.
     
    139163
    140164                                // Start of text node -> use dom walker to get the previous text node.
    141165                                var data = null;
    142                                 while ( !data
    143                                 || ( data.node && data.node.type != CKEDITOR.NODE_TEXT ) )
     166                                do
    144167                                {
    145168                                        data = this._.walker.reverse( guardDomWalkerNonEmptyTextNode );
    146169
     
    147170                                        // Block boundary? BR? Document boundary?
    148171                                        if ( !data.node || ( data.node.type !== CKEDITOR.NODE_TEXT &&
    149172                                        data.node.getName() in characterBoundaryElementsEnum ) )
     173                                        {
    150174                                                this._.matchBoundary = true;
     175                                               
     176                                                // Scope to characters within body
     177                                                if ( data.node && data.node.getName() == 'body' )
     178                                                {
     179                                                        data.node = null;
     180                                                        break;
     181                                                }
     182                                        }
    151183                                }
     184                                while ( data.node && data.node.type !=
     185                                        CKEDITOR.NODE_TEXT )
    152186                                this.textNode = data.node;
    153                                 this.offset = data.node.length - 1;
     187                                this.offset = this.textNode? data.node.length - 1 : 0;
    154188                                return cursorStep.call( this );
    155189                        }
    156190                };
     
    194228                                var startNode = domRange.startContainer,
    195229                                        startIndex = domRange.startOffset,
    196230                                        endNode = domRange.endContainer,
    197                                         endIndex = domRange.endOffset,
    198                                         boundaryNodes = domRange.getBoundaryNodes();
     231                                        endIndex = domRange.endOffset;
    199232
    200233                                if ( startNode.type != CKEDITOR.NODE_TEXT )
    201234                                {
    202                                         startNode = boundaryNodes.startNode;
     235                                        startNode = domRange.getTouchedStartNode();
    203236                                        while ( startNode.type != CKEDITOR.NODE_TEXT )
    204                                                 startNode = startNode.getFirst();
     237                                                startNode = startNode.getNextSourceNode();
    205238                                        startIndex = 0;
    206239                                }
    207240
     
    207240
    208241                                if ( endNode.type != CKEDITOR.NODE_TEXT )
    209242                                {
    210                                         endNode = boundaryNodes.endNode;
     243                                        endNode = domRange.getTouchedEndNode();
    211244                                        while ( endNode.type != CKEDITOR.NODE_TEXT )
    212                                                 endNode = endNode.getLast();
    213                                         endIndex = endNode.getLength();
     245                                                endNode = endNode.getPreviousSourceNode();
     246                                        endIndex = endNode.getLength() - 1;
    214247                                }
    215248
    216249                                // If the endNode is an empty text node, our walker would just walk through
     
    216249                                // If the endNode is an empty text node, our walker would just walk through
    217250                                // it without stopping. So need to backtrack to the nearest non-emtpy text
    218251                                // node.
    219                                 if ( endNode.getLength() < 1 )
     252                                if ( endNode && endNode.getLength() < 1 )
    220253                                {
    221                                         while ( ( endNode = endNode.getPreviousSourceNode() ) && !( endNode.type == CKEDITOR.NODE_TEXT && endNode.getLength() > 0 ) );
    222                                         endIndex = endNode.getLength();
     254                                        while ( ( endNode = endNode.getPreviousSourceNode() ) && !( endNode.type == CKEDITOR.NODE_TEXT && endNode.getLength() > 0 ) )
     255                                                endIndex = endNode.getLength() - 1;
    223256                                }
    224257
    225                                 var cursor = new characterWalker( startNode, startIndex );
    226                                 this._.cursors = [ cursor ];
    227                                 if ( !( cursor.textNode.equals( endNode ) && cursor.offset == endIndex - 1 ) )
     258                                var walker = new characterWalker( startNode, startIndex ), cursor;
     259                               
     260                                // DomRange contains at least one character.
     261                                ( this._.cursors = [] ).push( cursor = walker.current() );
     262                                do
    228263                                {
    229                                         do
    230                                         {
    231                                                 cursor = new characterWalker( cursor );
    232                                                 cursor.next();
    233                                                 this._.cursors.push( cursor );
    234                                         }
    235                                         while ( !( cursor.textNode.equals( endNode ) && cursor.offset == endIndex - 1 ) );
     264                                        cursor = walker.next();
     265                                        this._.cursors.push( cursor );
    236266                                }
     267                                while ( !( cursor.textNode.equals( endNode ) && cursor.offset == endIndex ) )
    237268
    238269                                this._.rangeLength = this._.cursors.length;
    239270                        },
     
    301332                                var retval = this._.walker.back(),
    302333                                        cursors = this._.cursors;
    303334
    304                                 if ( retval.hitMatchBoundary )
     335                                if ( !retval || retval.hitMatchBoundary )
    305336                                        this._.cursors = cursors = [];
    306 
     337                                if( retval )
     338                                {
    307339                                cursors.unshift( retval );
    308340                                if ( cursors.length > this._.rangeLength )
    309341                                        cursors.pop();
     342                                }
    310343
    311344                                return retval;
    312345                        },
     
    317350                                        cursors = this._.cursors;
    318351
    319352                                // Clear the cursors queue if we've crossed a match boundary.
    320                                 if ( retval.hitMatchBoundary )
     353                                if ( !retval || retval.hitMatchBoundary )
    321354                                        this._.cursors = cursors = [];
    322 
    323                                 cursors.push( retval );
    324                                 if ( cursors.length > this._.rangeLength )
    325                                         cursors.shift();
     355                               
     356                                if ( retval )
     357                                {
     358                                        cursors.push( retval );
     359                                        if ( cursors.length > this._.rangeLength )
     360                                                cursors.shift();
     361                                }
    326362
    327363                                return retval;
    328364                        },
     
    452488                                                matchState = matcher.feedCharacter( character );
    453489                                                if ( matchState == KMP_MATCHED )
    454490                                                        break;
    455                                                 if ( this.range.moveNext().hitMatchBoundary )
     491                                                var next = this.range.moveNext();
     492                                                if ( next && next.hitMatchBoundary )
    456493                                                        matcher.reset();
    457494                                        }
    458495
     
    464501                                                                tail = cursors[ cursors.length - 1 ],
    465502                                                                head = cursors[ 0 ],
    466503                                                                headWalker = new characterWalker( head ),
    467                                                                 tailWalker = new characterWalker( tail );
     504                                                                tailWalker = new characterWalker( tail ),
     505                                                                headBoundaryCursor = headWalker.back(),
     506                                                                tailBoundaryCursor = tailWalker.next();
    468507                                                               
    469                                                         if ( ! ( isWordSeparator(
    470                                                                                 headWalker.back().character )
    471                                                                                 && isWordSeparator(
    472                                                                                 tailWalker.next().character ) ) )
    473                                                                 continue;
     508                                                        if ( !( ( !headBoundaryCursor
     509                                                                || headBoundaryCursor.hitMatchBoundary
     510                                                                || isWordSeparator( headBoundaryCursor.character ) )
     511                                                                &&
     512                                                                ( !tailBoundaryCursor
     513                                                                || tailBoundaryCursor.hitMatchBoundary
     514                                                                || isWordSeparator( tailBoundaryCursor.character ) ) ) )
     515                                                                {
     516                                                                        matchState = KMP_NOMATCH;
     517                                                                        matcher.reset();
     518                                                                        continue;
     519                                                                }
    474520                                                }
    475521
    476522                                                this.range.setMatched();
  • _source/core/dom/range.js

     
    15031503                        if ( this.collapsed || container.type != CKEDITOR.NODE_ELEMENT )
    15041504                                return container ;
    15051505
    1506                         return container.getChild[ this.endOffset - 1 ] || container ;
     1506                        return container.getChild( this.endOffset - 1 )|| container ;
    15071507                }
    15081508        };
    15091509})();
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy