Ticket #2905: 2905.patch

File 2905.patch, 25.8 KB (added by Garry Yao, 14 years ago)
  • _source/plugins/toolbar/plugin.js

     
    211211                'Bold', 'Italic', 'Underline', 'Strike', '-',
    212212                'NumberedList', 'BulletedList', '-',
    213213                'Subscript', 'Superscript', '-',
     214                'Find', 'Replace', '-',
    214215                'SelectAll', 'RemoveFormat', '-',
    215216                'Link', 'Unlink', 'Anchor', '-',
    216217                'Table', 'Smiley', 'HorizontalRule', 'SpecialChar', 'PageBreak'
  • _source/plugins/find/dialogs/find.js

     
    55
    66(function()
    77{
     8        // Element tag names which prevent characters counting.
     9        var characterBoundaryElementsEnum = {
     10                address :1, blockquote :1, dl :1, h1 :1, h2 :1, h3 :1,
     11                h4 :1, h5 :1, h6 :1, p :1, pre :1, li :1, dt :1, de :1, div :1, td:1, th:1
     12                };
     13       
    814        var guardDomWalkerNonEmptyTextNode = function( evt )
    915        {
    1016                if ( evt.data.to && evt.data.to.type == CKEDITOR.NODE_TEXT && evt.data.to.$.length > 0 )
     
    1117                        this.stop();
    1218                CKEDITOR.dom.domWalker.blockBoundary( { br : 1 } ).call( this, evt );
    1319        };
    14 
    15         var domWalkerEventBridge = function()
    16         {
    17                 var me = this,
    18                         handler = function( evt ){ me.fire( evt.data.type, evt.data ); me._.actionEvents.push( evt.data ); };
    19                 this._.walker.on( 'up', handler );
    20                 this._.walker.on( 'down', handler );
    21                 this._.walker.on( 'sibling', handler );
    22         };
    23 
    24         var fireCharacterEvent = function()
     20       
     21       
     22        /**
     23         * Get the  cursor object which represent both current character and it's dom position thing.
     24         */
     25        var getCurrentCursor = function()
    2526        {
    2627                var obj = {
    27                         type : 'character',
     28                        textNode : this.textNode,
     29                        offset : this.offset,
    2830                        character : this.textNode ? this.textNode.getText().charAt( this.offset ) : null,
    2931                        hitMatchBoundary : this._.matchBoundary
    3032                };
    31                 this.fire( 'character', obj );
    32                 this._.actionEvents.push( obj );
    33                 return { character : obj.character, events : this._.actionEvents };
     33                return obj;
    3434        };
     35       
     36        var pages = [ 'find', 'replace' ],
     37                fieldsMapping = [
     38                [ 'txtFindFind', 'txtFindReplace' ],
     39                [ 'txtFindCaseChk', 'txtReplaceCaseChk' ],
     40                [ 'txtFindWordChk', 'txtReplaceWordChk' ],
     41                [ 'txtFindCyclic', 'txtReplaceCyclic' ] ],
     42               
     43                //Indicate whether is user switching between tabs 
     44                isSwitch = false;
     45
     46        /**
     47         * Synchronize corresponding filed values between 'replace' and 'find' pages.
     48         * @param {String} currentPageId        The page id which receive values.
     49         */
     50        function syncFindReplacePageFields( currentPageId)
     51        {
     52                if ( isSwitch )
     53                {
     54                        var sourceIndex, targetIndex,
     55                                sourceField, targetField;
     56               
     57                        sourceIndex = currentPageId === 'find' ? 1 : 0;
     58                        targetIndex = 1 - sourceIndex;
     59                        var i, l = fieldsMapping.length;
     60                        for ( i = 0 ; i < l ; i++ )
     61                        {
     62                                var sourceField = this
     63                                        .getContentElement( pages[ sourceIndex ],
     64                                                fieldsMapping[ i ][ sourceIndex ] ),
     65                                        targetField = this
     66                                        .getContentElement( pages[ targetIndex ],
     67                                                fieldsMapping[ i ][ targetIndex ] );
     68                               
     69                                targetField.setValue( sourceField.getValue() );
     70                        }
     71                }
     72                else
     73                        isSwitch = true;
     74        }
    3575
    3676        var findDialog = function( editor, startupPage )
    3777        {
    38                 var characterWalker = function( cursorOrTextNode, offset )
     78                //back refer the dialog instance.
     79                var dialog;
     80               
     81                /**
     82                 * Iterator which walk through document char by char.
     83                 * @param {Object} start
     84                 * @param {Number} offset
     85                 */
     86                var characterWalker = function( start, offset )
    3987                {
    40                         var isCursor = ( cursorOrTextNode instanceof characterWalker );
     88                        var isCursor = typeof start.textNode !== 'undefined';
     89                        this.textNode = isCursor ? start.textNode : start;
     90                        this.offset = isCursor ? start.offset : offset;
    4191                        this._ = {
    42                                 matchBoundary : false,
    43                                 actionEvents : null
     92                                walker : new CKEDITOR.dom.domWalker( this.textNode ),
     93                                matchBoundary : false
    4494                        };
    45                         this.textNode = isCursor ? cursorOrTextNode.textNode : cursorOrTextNode,
    46                         this.offset = isCursor ? cursorOrTextNode.offset : offset,
    47                         this._.walker = new CKEDITOR.dom.domWalker( this.textNode );
    48                         CKEDITOR.event.implementOn( this );
    49                         domWalkerEventBridge.call( this );
    5095                };
    5196
    5297                characterWalker.prototype = {
     
    5297                characterWalker.prototype = {
    5398                        next : function()
    5499                        {
    55                                 // Clear any previous action events and related flags.
    56                                 this._.actionEvents = [];
     100                                // Already at the end of document, no more character available.
     101                                if( this.textNode === null && this._.matchBoundary )
     102                                        return getCurrentCursor.call( this );
     103                                       
    57104                                this._.matchBoundary = false;
    58 
    59                                 // If there are more characters in the text node, get it and raise an event.
    60                                 if ( this.textNode.type == CKEDITOR.NODE_TEXT && this.offset < this.textNode.getLength() - 1 )
     105                               
     106                                // If there are more characters in the text node, get it and
     107                                // raise an event.
     108                                if( this.textNode.type == CKEDITOR.NODE_TEXT
     109                                        && this.offset < this.textNode.getLength() - 1 )
    61110                                {
    62111                                        this.offset++;
    63                                         return fireCharacterEvent.call( this );
     112                                        return getCurrentCursor.call( this );
    64113                                }
    65114
    66                                 // If we are at the end of the text node, use dom walker to get the next text node.
     115                                // If we are at the end of the text node, use dom walker to get
     116                                // the next text node.
    67117                                var data = null;
    68                                 while ( !data || ( data.node && data.node.type != CKEDITOR.NODE_TEXT ) )
     118                                while( !data
     119                                        || ( data.node && data.node.type != CKEDITOR.NODE_TEXT ) )
    69120                                {
    70                                         data = this._.walker.forward( guardDomWalkerNonEmptyTextNode );
     121                                        data = this._.walker
     122                                                .forward( guardDomWalkerNonEmptyTextNode );
    71123
    72124                                        // Block boundary? BR? Document boundary?
    73                                         if ( !data.node || data.node.type != CKEDITOR.NODE_TEXT )
     125                                        if( !data.node || ( data.node.type !== CKEDITOR.NODE_TEXT &&
     126                                                        data.node.getName() in characterBoundaryElementsEnum ) )
    74127                                                this._.matchBoundary = true;
    75128                                }
    76129                                this.textNode = data.node;
     
    75128                                }
    76129                                this.textNode = data.node;
    77130                                this.offset = 0;
    78                                 return fireCharacterEvent.call( this );
     131                                return getCurrentCursor.call( this );
    79132                        },
    80 
     133                       
    81134                        back : function()
    82135                        {
    83                                 // Clear any previous action events and related flags.
    84                                 this._.actionEvents = [];
    85136                                this._.matchBoundary = false;
    86137
    87138                                // More characters -> decrement offset and return.
     
    88139                                if ( this.textNode.type == CKEDITOR.NODE_TEXT && this.offset > 0 )
    89140                                {
    90141                                        this.offset--;
    91                                         return fireCharacterEvent.call( this );
     142                                        return getCurrentCursor.call( this );
    92143                                }
    93144
    94145                                // Start of text node -> use dom walker to get the previous text node.
     
    98149                                        data = this._.walker.reverse( guardDomWalkerNonEmptyTextNode );
    99150
    100151                                        // Block boundary? BR? Document boundary?
    101                                         if ( !data.node || data.node.type != CKEDITOR.NODE_TEXT )
     152                                        if ( !data.node || ( data.node.type !== CKEDITOR.NODE_TEXT &&
     153                                        data.node.getName() in characterBoundaryElementsEnum ) )
    102154                                                this._.matchBoundary = true;
    103155                                }
    104156                                this.textNode = data.node;
     
    103155                                }
    104156                                this.textNode = data.node;
    105157                                this.offset = data.node.length - 1;
    106                                 return fireCharacterEvent.call( this );
    107                         },
    108 
    109                         getChar : function()
    110                         {
    111                                 return this.textNode ? this.textNode.getText().charAt( this.offset ) : null;
     158                                return getCurrentCursor.call( this );
    112159                        }
    113160                };
    114 
    115                 var characterRange = function( initCursor, maxLength )
     161               
     162                /**
     163                 * A range of cursors which represent a trunk of characters which try to
     164                 * match, it has the same length as the pattern  string.
     165                 */
     166                var characterRange = function( characterWalker, rangeLength )
    116167                {
    117168                        this._ = {
    118                                 cursors : initCursor.push ? initCursor : [ initCursor ],
    119                                 maxLength : maxLength,
    120                                 highlightRange : null
     169                                walker : characterWalker,
     170                                cursors : [],
     171                                rangeLength : rangeLength,
     172                                highlightRange : null,
     173                                isMatched : false
    121174                        };
    122175                };
    123176
     
    122175                };
    123176
    124177                characterRange.prototype = {
     178                        /**
     179                         * Translate this range to {@link CKEDITOR.dom.range}
     180                         */
    125181                        toDomRange : function()
    126182                        {
    127183                                var cursors = this._.cursors;
     
    136192                                range.setEnd( last.textNode, last.offset + 1 );
    137193                                return range;
    138194                        },
     195                       
     196                        setMatched : function()
     197                        {
     198                                this._.isMatched = true;
     199                                this.highlight();
     200                        },
     201                       
     202                        clearMatched : function()
     203                        {
     204                                this._.isMatched = false;
     205                                this.removeHighlight();
     206                        },
     207                       
     208                        isMatched : function()
     209                        {
     210                                return this._.isMatched;
     211                        },
    139212
    140213                        highlight : function()
    141214                        {
     215                                if(CKEDITOR.env.ie)
     216                                        dialog.restoreSelection();
     217                               
    142218                                // TODO: wait till Fred has implemented style removal for this.
    143219                                editor.getSelection().selectRanges( [ this.toDomRange() ] );
     220                               
     221                                if(CKEDITOR.env.ie)
     222                                {
     223                                        dialog.saveSelection();
     224                                       
     225                                        //since IE broke text nodes, update these changes back to character range.
     226                                        var dirtyRange = editor.getSelection().getRanges()[0];
     227                                        var cursors = this._.cursors;
     228                                        var first = cursors[0],
     229                                        last = cursors[ cursors.length - 1 ];
     230                                        first.textNode = dirtyRange.startContainer;
     231                                        first.offset = dirtyRange.startOffset;
     232                                        last.textNode = dirtyRange.endContainer;
     233                                        last.offset = dirtyRange.endOffset;
     234                                }
    144235                        },
    145236
    146237                        removeHighlight : function()
     
    146237                        removeHighlight : function()
    147238                        {
    148239                                // TODO: wait till Fred has implemented style removal for this.
     240                                this._.highlightRange = null;
    149241                        },
    150242
    151243                        getHighlightDomRange : function()
     
    153245                                // TODO: wait till Fred has implemented style removal for this.
    154246                                return this.toDomRange();
    155247                        },
    156 
    157                         moveNext : function()
     248                       
     249                        moveBack : function()
    158250                        {
    159                                 var next = new characterWalker( this._.cursors[ this._.cursors.length - 1 ] ),
    160                                         retval = next.next(),
     251                                var retval = this._.walker.back(),
    161252                                        cursors = this._.cursors;
    162253
    163                                 // Clear the cursors queue if we've crossed a match boundary.
    164254                                if ( retval.hitMatchBoundary )
    165255                                        this._.cursors = cursors = [];
    166256
    167                                 cursors.push( next );
    168                                 if ( cursors.length > this._.maxLength )
    169                                         cursors.shift();
     257                                cursors.unshift( retval );
     258                                if ( cursors.length > this._.rangeLength )
     259                                        cursors.pop();
    170260
    171261                                return retval;
    172262                        },
    173 
    174                         moveBack : function()
     263       
     264                        moveNext : function()
    175265                        {
    176                                 var prev = new characterWalker( this._.cursors[0] ),
    177                                         retval = prev.back(),
     266                                var retval = this._.walker.next(),
    178267                                        cursors = this._.cursors;
    179268
     269                                // Clear the cursors queue if we've crossed a match boundary.
    180270                                if ( retval.hitMatchBoundary )
    181271                                        this._.cursors = cursors = [];
    182272
    183                                 cursors.unshift( prev );
    184                                 if ( cursors.length > this._.maxLength )
    185                                         cursors.pop();
     273                                cursors.push( retval );
     274                                if ( cursors.length > this._.rangeLength )
     275                                        cursors.shift();
    186276
    187277                                return retval;
    188278                        },
     
    193283                                if ( cursors.length < 1 )
    194284                                        return null;
    195285
    196                                 return cursors[ cursors.length - 1 ].getChar();
     286                                return cursors[ cursors.length - 1 ].character;
    197287                        },
    198288
    199                         getNextRange : function( maxLength )
     289                        updateRange : function( newrangeLength )
    200290                        {
    201                                 var cursors = this._.cursors;
    202                                 if ( cursors.length < 1 )
    203                                         return null;
    204 
    205                                 var next = new characterWalker( cursors[ cursors.length - 1 ] );
    206                                 next.next();
    207                                 return new characterRange( next, maxLength );
     291                                this._.cursors = [];
     292                                this._.rangeLength = newrangeLength;
     293                                this.removeHighlight();
    208294                        },
    209295
    210296                        getCursors : function()
     
    216302                var KMP_NOMATCH = 0,
    217303                        KMP_ADVANCED = 1,
    218304                        KMP_MATCHED = 2;
     305                /**
     306                 * Examination the occurrence of a word which implement KMP algorithm.
     307                 */
    219308                var kmpMatcher = function( pattern, ignoreCase )
    220309                {
    221310                        var overlap = [ -1 ];
     
    278367                        };
    279368
    280369                var finder = {
     370                        startCursor : null,
    281371                        range : null,
    282                         find : function( pattern, matchCase, matchWord )
     372                        find : function( pattern, matchCase, matchWord, matchCyclic )
    283373                        {
    284                                 if ( !this.range )
    285                                         this.range = new characterRange( new characterWalker( editor.document.getBody(), 0 ), pattern.length );
     374                                if( !this.range )
     375                                        this.range = new characterRange( new characterWalker(
     376                                                this.startCursor ) , pattern.length );
    286377                                else
    287378                                {
    288                                         this.range.removeHighlight();
    289                                         this.range = this.range.getNextRange( pattern.length );
     379                                        this.range.updateRange( pattern.length );
    290380                                }
    291381
    292382                                var matcher = new kmpMatcher( pattern, !matchCase ),
     
    295385
    296386                                while ( character != null )
    297387                                {
     388                                        this.range.moveNext();
    298389                                        while ( ( character = this.range.getEndCharacter() ) )
    299390                                        {
    300391                                                matchState = matcher.feedCharacter( character );
     
    309400                                                if ( matchWord )
    310401                                                {
    311402                                                        var cursors = this.range.getCursors(),
    312                                                                 head = new characterCursor( cursors[ cursors.length - 1 ] ),
    313                                                                 tail = new characterCursor( cursors[0] );
    314                                                         if ( !( head.next().character || isWordSeparator( head.getChar() ) ) )
    315                                                                 continue;
    316                                                         if ( !( tail.back().character || isWordSeparator( tail.getChar() ) ) )
     403                                                                tail = cursors[ cursors.length - 1 ],
     404                                                                head = cursors[ 0 ],
     405                                                                headWalker = new characterWalker(head),
     406                                                                tailWalker = new characterWalker(tail);
     407                                                               
     408                                                        if ( ! ( isWordSeparator(
     409                                                                                headWalker.back().character )
     410                                                                                && isWordSeparator(
     411                                                                                tailWalker.next().character ) ) )
    317412                                                                continue;
    318413                                                }
    319414
    320                                                 this.range.highlight();
     415                                                this.range.setMatched();
    321416                                                return true;
    322417                                        }
    323418                                }
     419                               
     420                                this.range.clearMatched();
     421                               
     422                                // clear current range and start from beginning
     423                                if ( matchCyclic )
     424                                {
     425                                        this.startCursor = getDefaultStartCursor();
     426                                        this.range = null;
     427                                }
     428                                return false;
     429                        },
     430                       
     431                        /**
     432                         * Record how much replacement occurred toward one replacing.
     433                         */
     434                        replaceCounter : 0,
     435                       
     436                        replace : function( pattern, newString, matchCase, matchWord,
     437                                matchCyclic, matchReplaceAll )
     438                        {
     439                                var replaceResult = false;
     440                                if ( this.range && this.range.isMatched() )
     441                                {
     442                                        if ( CKEDITOR.env.ie )
     443                                                dialog.restoreSelection();
    324444
    325                                 this.range = null;
    326                                 return false;
     445                                        var domrange = this.range.toDomRange();
     446                                        var documentFragment = domrange.extractContents();
     447                                        // Use the first text container as holder, no matter what
     448                                        // kind of element it is.
     449                                        var contentHolder = documentFragment.getFirst();
     450
     451                                        if ( contentHolder.type === CKEDITOR.NODE_ELEMENT )
     452                                                contentHolder.setText( newString );
     453                                        else
     454                                                contentHolder = editor.document.createText( newString );
     455
     456                                        domrange.insertNode( contentHolder );
     457
     458                                        if ( CKEDITOR.env.ie )
     459                                                dialog.saveSelection();
     460
     461                                        this.replaceCounter++;
     462                                        replaceResult = true;
     463                                }
     464                               
     465                                var findResult = this.find(
     466                                        pattern, matchCase, matchWord,  matchCyclic );
     467                                if ( findResult && matchReplaceAll )
     468                                {
     469                                        this.replace.apply( this,
     470                                                Array.prototype.slice.call( arguments ) );
     471                                }
     472                                return matchReplaceAll ? this.replaceCounter : replaceResult
     473                                        || findResult;
    327474                        }
     475                       
    328476                };
     477               
     478                /**
     479                 * Get the default cursor which is the start of this document.
     480                 */
     481                function getDefaultStartCursor()
     482                {
     483                        return {textNode : editor.document.getBody(), offset: 0};
     484                }
     485               
     486                /**
     487                 * Get cursor that indicate search begin with, receive from user selection prior.
     488                 */
     489                function getStartCursor()
     490                {
     491                        if ( CKEDITOR.env.ie )
     492                                dialog.restoreSelection();
    329493
     494                        var sel = editor.getSelection();
     495                        if ( sel )
     496                        {
     497                                var lastRange = sel.getRanges()[ sel.getRanges().length - 1 ];
     498                                return {
     499                                        textNode : lastRange.getBoundaryNodes().endNode,
     500                                        offset : lastRange.endContainer.type === CKEDITOR.NODE_ELEMENT ?
     501                                                0       : lastRange.endOffset
     502                                };
     503                        }
     504                        else
     505                                return getDefaultStartCursor();
     506                }
     507               
    330508                return {
    331509                        title : editor.lang.findAndReplace.title,
    332510                        resizable : CKEDITOR.DIALOG_RESIZE_NONE,
     
    331509                        title : editor.lang.findAndReplace.title,
    332510                        resizable : CKEDITOR.DIALOG_RESIZE_NONE,
    333511                        minWidth : 400,
    334                         minHeight : 245,
     512                        minHeight : 255,
    335513                        buttons : [ CKEDITOR.dialog.cancelButton ],             //Cancel button only.
    336514                        contents : [
    337515                                {
     
    352530                                                                        isChanged : false,
    353531                                                                        labelLayout : 'horizontal',
    354532                                                                        accessKey : 'F',
     533                                                                        setup : function(){alert('setup');}
    355534                                                                },
    356535                                                                {
    357536                                                                        type : 'button',
     
    363542                                                                                var dialog = this.getDialog();
    364543                                                                                if ( !finder.find( dialog.getValueOf( 'find', 'txtFindFind' ),
    365544                                                                                                        dialog.getValueOf( 'find', 'txtFindCaseChk' ),
    366                                                                                                         dialog.getValueOf( 'find', 'txtFindWordChk' ) ) )
     545                                                                                                        dialog.getValueOf( 'find', 'txtFindWordChk' ),
     546                                                                                                        dialog.getValueOf( 'find', 'txtFindCyclic' ) ) )
    367547                                                                                        alert( editor.lang.findAndReplace.notFoundMsg );
    368548                                                                        }
    369                                                                 },
     549                                                                }
    370550                                                        ]
    371551                                                },
    372552                                                {
     
    374554                                                        id : 'txtFindCaseChk',
    375555                                                        isChanged : false,
    376556                                                        style : 'margin-top:28px',
    377                                                         label : editor.lang.findAndReplace.matchCase,
     557                                                        label : editor.lang.findAndReplace.matchCase
    378558                                                },
    379559                                                {
    380560                                                        type : 'checkbox',
     
    380560                                                        type : 'checkbox',
    381561                                                        id : 'txtFindWordChk',
    382562                                                        isChanged : false,
    383                                                         label : editor.lang.findAndReplace.matchWord,
     563                                                        label : editor.lang.findAndReplace.matchWord
    384564                                                },
    385565                                                {
    386566                                                        type : 'checkbox',
     
    387567                                                        id : 'txtFindCyclic',
    388568                                                        isChanged : false,
    389569                                                        checked : true,
    390                                                         label : editor.lang.findAndReplace.matchCyclic,
    391                                                 },
     570                                                        label : editor.lang.findAndReplace.matchCyclic
     571                                                }
    392572                                        ]
    393573                                },
    394574                                {
     
    407587                                                                        label : editor.lang.findAndReplace.findWhat,
    408588                                                                        isChanged : false,
    409589                                                                        labelLayout : 'horizontal',
    410                                                                         accessKey : 'F',
     590                                                                        accessKey : 'F'
    411591                                                                },
    412592                                                                {
    413593                                                                        type : 'button',
     
    416596                                                                        label : editor.lang.findAndReplace.replace,
    417597                                                                        onClick : function()
    418598                                                                        {
    419                                                                                 alert( editor.lang.findAndReplace.notFoundMsg );
     599                                                                                var dialog = this.getDialog();
     600                                                                                if ( !finder.replace( dialog
     601                                                                                        .getValueOf( 'replace',
     602                                                                                                'txtFindReplace' ), dialog
     603                                                                                        .getValueOf( 'replace',
     604                                                                                                'txtReplace' ), dialog
     605                                                                                        .getValueOf( 'replace',
     606                                                                                                'txtReplaceCaseChk' ), dialog
     607                                                                                        .getValueOf( 'replace',
     608                                                                                                'txtReplaceWordChk' ), dialog
     609                                                                                        .getValueOf( 'replace',
     610                                                                                                'txtReplaceCyclic' ) ) )
     611                                                                                        alert( editor.lang.findAndReplace.notFoundMsg );
    420612                                                                        }
    421                                                                 },
     613                                                                }
    422614                                                        ]
    423615                                                },
    424616                                                {
     
    432624                                                                        label : editor.lang.findAndReplace.replaceWith,
    433625                                                                        isChanged : false,
    434626                                                                        labelLayout : 'horizontal',
    435                                                                         accessKey : 'R',
     627                                                                        accessKey : 'R'
    436628                                                                },
    437629                                                                {
    438630                                                                        type : 'button',
     
    442634                                                                        isChanged : false,
    443635                                                                        onClick : function()
    444636                                                                        {
    445                                                                                 alert( editor.lang.findAndReplace.notFoundMsg );
     637                                                                                var dialog = this.getDialog();
     638                                                                                var replaceNums;
     639
     640                                                                                finder.replaceCounter = 0;
     641                                                                                if ( ( replaceNums = finder.replace(
     642                                                                                        dialog.getValueOf( 'replace',
     643                                                                                                'txtFindReplace' ), dialog
     644                                                                                                .getValueOf( 'replace',
     645                                                                                                        'txtReplace' ), dialog
     646                                                                                                .getValueOf( 'replace',
     647                                                                                                        'txtReplaceCaseChk' ),
     648                                                                                        dialog.getValueOf( 'replace',
     649                                                                                                'txtReplaceWordChk' ), dialog
     650                                                                                                .getValueOf( 'replace',
     651                                                                                                        'txtReplaceCyclic' ), true ) ) )
     652                                                                                        alert(editor.lang.findAndReplace.replaceSuccMsg
     653                                                                                                .replace(/%1/, replaceNums));
     654                                                                                else
     655                                                                                        alert( editor.lang.findAndReplace.notFoundMsg );
    446656                                                                        }
    447                                                                 },
     657                                                                }
    448658                                                        ]
    449659                                                },
    450660                                                {
     
    451661                                                        type : 'checkbox',
    452662                                                        id : 'txtReplaceCaseChk',
    453663                                                        isChanged : false,
    454                                                         label : editor.lang.findAndReplace.matchCase,
     664                                                        label : editor.lang.findAndReplace.matchCase
    455665                                                },
    456666                                                {
    457667                                                        type : 'checkbox',
     
    457667                                                        type : 'checkbox',
    458668                                                        id : 'txtReplaceWordChk',
    459669                                                        isChanged : false,
    460                                                         label : editor.lang.findAndReplace.matchWord,
     670                                                        label : editor.lang.findAndReplace.matchWord
    461671                                                },
    462672                                                {
    463673                                                        type : 'checkbox',
     
    464674                                                        id : 'txtReplaceCyclic',
    465675                                                        isChanged : false,
    466676                                                        checked : true,
    467                                                         label : editor.lang.findAndReplace.matchCyclic,
    468                                                 },
     677                                                        label : editor.lang.findAndReplace.matchCyclic
     678                                                }
    469679                                        ]
    470680                                }
    471681                        ],
     682                        onLoad : function()
     683                        {
     684                                dialog = this;
     685                               
     686                                //keep trac of the current pattern field in use.
     687                                var patternField, wholeWordChkField;
     688                               
     689                                /**
     690                                 * Check the whether the 'wholeworld' match mode could be toggled on.
     691                                 */
     692                                function checkWholeWordState()
     693                                {
     694                                        var isWord = /^\w+$/.test( patternField.getValue() );
     695                                        var wholeWordChkFieldEl = wholeWordChkField.getElement();
     696                                        if ( isWord )
     697                                                wholeWordChkFieldEl.show();
     698                                        else
     699                                                wholeWordChkFieldEl.hide();
     700                                }
     701
     702                                this.selectPage = CKEDITOR.tools.override( this.selectPage,
     703                                        function( originalFunc )
     704                                        {
     705                                                return function( pageId )
     706                                                {
     707                                                        originalFunc.call( dialog, pageId );
     708                                                       
     709                                                        var currPage = dialog._.tabs[ pageId ];
     710                                                        var patternFieldInput, patternFieldId, wholeWordChkFieldId;
     711                                                        patternFieldId = pageId === 'find' ? 'txtFindFind'
     712                                                                : 'txtFindReplace';
     713                                                        wholeWordChkFieldId = pageId === 'find' ? 'txtFindWordChk'
     714                                                                : 'txtReplaceWordChk';
     715
     716                                                        patternField = dialog.getContentElement( pageId,
     717                                                                patternFieldId );
     718                                                        wholeWordChkField = dialog.getContentElement( pageId,
     719                                                                wholeWordChkFieldId );
     720                                                       
     721                                                        // prepare for check pattern text filed 'keyup' event
     722                                                        if ( !currPage.initialized )
     723                                                        {
     724                                                                patternFieldInput = CKEDITOR.document
     725                                                                        .getById( patternField._.inputId );
     726                                                                patternFieldInput.on( 'keyup', checkWholeWordState );
     727                                                                currPage.initialized = true;
     728                                                        }
     729                                                       
     730                                                        // synchronize fields on tab switch.
     731                                                        syncFindReplacePageFields.call( this, pageId );
     732                                                       
     733                                                        //check wholeword match status on tab switch
     734                                                        checkWholeWordState();
     735                                };
     736                        } );
     737
     738                        },
    472739                        onShow : function()
    473740                        {
     741                                //Establish initial searching start position.
     742                                finder.startCursor = getStartCursor();
     743                               
    474744                                if ( startupPage == 'replace' )
    475745                                        this.getContentElement( 'replace', 'txtFindReplace' ).focus();
    476746                                else
     
    478748                        },
    479749                        onHide : function()
    480750                        {
     751                                isSwitch = false;
    481752                                if ( finder.range )
    482753                                {
    483754                                        finder.range.removeHighlight();
     
    483754                                        finder.range.removeHighlight();
    484755                                        editor.getSelection().selectRanges( [finder.range.toDomRange()] );
    485756                                }
     757                                delete finder.range;
    486758                        }
    487759                };
    488760        };
     
    496768                        return findDialog( editor, 'replace' )
    497769                }
    498770        );
    499 })();
     771})();
  • _source/skins/default/toolbar.css

     
    315315{
    316316        background-position: 0 -416px;
    317317}
     318.cke_skin_default a.cke_button_find .cke_icon
     319{
     320        background-position: 0 -240px;
     321}
     322
     323.cke_skin_default a.cke_button_replace .cke_icon
     324{
     325        background-position: 0 -256px;
     326}
  • _source/lang/en.js

     
    99 */
    1010
    1111/**#@+
    12    @type String
    13    @example
     12@type String
     13@example
    1414*/
    1515
    1616/**
     
    170170                matchCase                       : 'Match case',
    171171                matchWord                       : 'Match whole word',
    172172                matchCyclic                     : 'Match cyclic',
    173                 replaceAll                      : 'Replace All'
     173                replaceAll                      : 'Replace All',
     174                replaceSuccMsg          : 'Succeed with: %1 replacement(s) in total.'
    174175        },
    175176
    176177        // Table Dialog
  • _source/core/dom/document.js

     
    7070
    7171                createText : function( text )
    7272                {
    73                         return new CKEDITOR.dom.text( '', this );
     73                        return new CKEDITOR.dom.text( text , this );
    7474                },
    7575
    7676                /**
  • _source/core/config.js

     
    146146         * @example
    147147         * config.plugins = 'basicstyles,button,htmldataprocessor,toolbar,wysiwygarea';
    148148         */
    149         plugins : 'basicstyles,button,elementspath,horizontalrule,htmldataprocessor,keystrokes,newpage,pagebreak,removeformat,smiley,link,list,sourcearea,table,specialchar,tab,toolbar,wysiwygarea',
     149        plugins : 'basicstyles,button,elementspath,horizontalrule,htmldataprocessor,keystrokes,newpage,pagebreak,removeformat,smiley,link,list,sourcearea,table,specialchar,tab,toolbar,wysiwygarea,find',
    150150
    151151        /**
    152152         * The theme to be used to build the UI.
© 2003 – 2022, CKSource sp. z o.o. sp.k. All rights reserved. | Terms of use | Privacy policy