Ticket #3515: 3515.patch

File 3515.patch, 5.1 KB (added by Garry Yao, 12 years ago)
  • _source/plugins/find/dialogs/find.js

     
    2626         */
    2727        var cursorStep = function()
    2828        {
    29                 var obj = {
     29                return {
    3030                        textNode : this.textNode,
    3131                        offset : this.offset,
    3232                        character : this.textNode ?
    3333                                this.textNode.getText().charAt( this.offset ) : null,
    3434                        hitMatchBoundary : this._.matchBoundary
    3535                };
    36                 return obj;
    3736        };
    3837
    3938        var pages = [ 'find', 'replace' ],
     
    7271                var highlightStyle = new CKEDITOR.style( editor.config.find_highlight );
    7372
    7473                /**
    75                  * Iterator which walk through document char by char.
    76                  * @param {Object} start
    77                  * @param {Number} offset
    78                  * @param {Boolean} isStrict
     74                 * Iterator which walk through the specified range char by char. By
     75                 * default the walking will not stop at the character boundaries, until
     76                 * the end of the range is encountered.
     77                 * @param { CKEDITOR.dom.range } range
     78                 * @param {Boolean} matchWord Whether the walking will stop at character boundary.
    7979                 */
    8080                var characterWalker = function( range , matchWord )
    8181                {
     
    193193                                range.setEnd( last.textNode, last.offset + 1 );
    194194                                return range;
    195195                        },
    196 
     196                        /**
     197                         * Reflect the latest changes from dom range.
     198                         */
    197199                        updateFromDomRange : function( domRange )
    198200                        {
    199                                 var startNode = domRange.startContainer,
    200                                         startIndex = domRange.startOffset,
    201                                         endNode = domRange.endContainer,
    202                                         endIndex = domRange.endOffset,
    203                                         boundaryNodes = domRange.getBoundaryNodes();
    204 
    205                                 if ( startNode.type != CKEDITOR.NODE_TEXT )
    206                                 {
    207                                         startNode = boundaryNodes.startNode;
    208                                         while ( startNode.type != CKEDITOR.NODE_TEXT )
    209                                                 startNode = startNode.getFirst();
    210                                         startIndex = 0;
    211                                 }
    212 
    213                                 if ( endNode.type != CKEDITOR.NODE_TEXT )
    214                                 {
    215                                         endNode = boundaryNodes.endNode;
    216                                         while ( endNode.type != CKEDITOR.NODE_TEXT )
    217                                                 endNode = endNode.getLast();
    218                                         endIndex = endNode.getLength();
    219                                 }
    220 
    221                                 // If the endNode is an empty text node, our walker would just walk through
    222                                 // it without stopping. So need to backtrack to the nearest non-emtpy text
    223                                 // node.
    224                                 if ( endNode.getLength() < 1 )
    225                                 {
    226                                         while ( ( endNode = endNode.getPreviousSourceNode() )
    227                                                    && !( endNode.type == CKEDITOR.NODE_TEXT
    228                                                                         && endNode.getLength() > 0 ) )
    229                                         { /*jsl:pass*/ }
    230 
    231                                         endIndex = endNode.getLength();
    232                                 }
    233 
    234                                 // Rebuild the character range.
    235201                                var cursor,
    236                                                 walker = new characterWalker(
    237                                                                 getRangeAfterCursor(
    238                                                                                                         ( { textNode: startNode, offset : startIndex } ),
    239                                                                                                         true ) );
     202                                                walker = new characterWalker( domRange );
    240203                                this._.cursors = [];
    241204                                do
    242205                                {
    243206                                        cursor = walker.next();
    244                                         this._.cursors.push( cursor );
     207                                        if ( cursor.character )
     208                                                this._.cursors.push( cursor );
    245209                                }
    246                                 while ( !( cursor.textNode.equals( endNode )
    247                                                          && cursor.offset == endIndex - 1 ) );
     210                                while ( cursor.character );
    248211                                this._.rangeLength = this._.cursors.length;
    249212                        },
    250213
     
    439402                                                this._.state = this._.overlap[ this._.state ];
    440403                                }
    441404
    442                                 return null;
    443405                        },
    444406
    445407                        reset : function()
     
    535497                        replace : function( dialog, pattern, newString, matchCase, matchWord,
    536498                                matchCyclic, matchReplaceAll )
    537499                        {
    538                                 var replaceResult = false;
    539                                 if ( this.range && this.range.isMatched() )
     500                                // Successiveness of current replace/find.
     501                                var result = false;
     502
     503                                // 1. Perform the replace when there's already a match here.
     504                                // 2. Otherwise perform the find but don't replace it immediately.
     505                                if ( this.matchRange && this.matchRange.isMatched() )
    540506                                {
    541                                         var domRange = this.range.toDomRange();
     507                                        var domRange = this.matchRange.toDomRange();
    542508                                        var text = editor.document.createText( newString );
    543509                                        domRange.deleteContents();
    544510                                        domRange.insertNode( text );
    545                                         this.range.updateFromDomRange( domRange );
    546 
     511                                        this.matchRange.updateFromDomRange( domRange );
     512                                        this.matchRange._.isMatched = false;
    547513                                        this.replaceCounter++;
    548                                         replaceResult = true;
     514                                        result = true;
    549515                                }
    550 
    551                                 var findResult = this.find( pattern, matchCase, matchWord, matchCyclic );
    552                                 if ( findResult && matchReplaceAll )
     516                                else
     517                                        result = this.find( pattern, matchCase, matchWord, matchCyclic );
     518                               
     519                                // Recusively replace all matches.
     520                                if ( matchReplaceAll && result )
    553521                                        this.replace.apply( this, Array.prototype.slice.call( arguments ) );
     522
    554523                                return matchReplaceAll ?
    555                                         this.replaceCounter : replaceResult || findResult;
     524                                        this.replaceCounter : result;
    556525                        }
    557526                };
    558527
    559528                /**
    560                  * Get the default cursor which is the start of this document.
    561                  */
    562                 function getDefaultStartCursor()
    563                 {
    564                         return { textNode : editor.document.getBody(), offset: 0 };
    565                 }
    566 
    567                 /**
    568529                 * The range in which find/replace happened, receive from user
    569530                 * selection prior.
    570531                 */
© 2003 – 2021 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy