Ticket #2905: 2905_4.patch

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

     
    213213                'Outdent', 'Indent', 'Blockquote', '-',
    214214                'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-',
    215215                'Subscript', 'Superscript', '-',
     216                'Find', 'Replace', '-',
    216217                'SelectAll', 'RemoveFormat', '-',
    217218                'Link', 'Unlink', 'Anchor', '-',
    218219                'Image', '-',
  • _source/plugins/find/dialogs/find.js

     
     1/*
     2Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
     3For licensing, see LICENSE.html or http://ckeditor.com/license
     4*/
     5
     6(function()
     7{
     8        // Element tag names which prevent characters counting.
     9        var characterBoundaryElementsEnum =
     10        {
     11                address :1, blockquote :1, dl :1, h1 :1, h2 :1, h3 :1,
     12                h4 :1, h5 :1, h6 :1, p :1, pre :1, li :1, dt :1, de :1, div :1, td:1, th:1
     13        };
     14       
     15        var guardDomWalkerNonEmptyTextNode = function( evt )
     16        {
     17                if ( evt.data.to && evt.data.to.type == CKEDITOR.NODE_TEXT
     18                        && evt.data.to.$.length > 0 )
     19                        this.stop();
     20                CKEDITOR.dom.domWalker.blockBoundary( { br : 1 } ).call( this, evt );
     21        };
     22       
     23       
     24        /**
     25         * Get the cursor object which represent both current character and it's dom
     26         * position thing.
     27         */
     28        var getCurrentCursor = function()
     29        {
     30                var obj = {
     31                        textNode : this.textNode,
     32                        offset : this.offset,
     33                        character : this.textNode ? this.textNode.getText().charAt( this.offset ) : null,
     34                        hitMatchBoundary : this._.matchBoundary
     35                };
     36                return obj;
     37        };
     38       
     39        var pages = [ 'find', 'replace' ],
     40                fieldsMapping = [
     41                [ 'txtFindFind', 'txtFindReplace' ],
     42                [ 'txtFindCaseChk', 'txtReplaceCaseChk' ],
     43                [ 'txtFindWordChk', 'txtReplaceWordChk' ],
     44                [ 'txtFindCyclic', 'txtReplaceCyclic' ] ];
     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 syncFieldsBetweenTabs( currentPageId)
     51        {
     52                        var sourceIndex, targetIndex,
     53                                sourceField, targetField;
     54               
     55                        sourceIndex = currentPageId === 'find' ? 1 : 0;
     56                        targetIndex = 1 - sourceIndex;
     57                        var i, l = fieldsMapping.length;
     58                        for ( i = 0 ; i < l ; i++ )
     59                        {
     60                                var sourceField = this
     61                                        .getContentElement( pages[ sourceIndex ],
     62                                                fieldsMapping[ i ][ sourceIndex ] ),
     63                                        targetField = this
     64                                        .getContentElement( pages[ targetIndex ],
     65                                                fieldsMapping[ i ][ targetIndex ] );
     66                               
     67                                targetField.setValue( sourceField.getValue() );
     68                        }
     69        }
     70
     71        var findDialog = function( editor, startupPage )
     72        {
     73                //back refer the dialog instance.
     74                var dialog;
     75               
     76                /**
     77                 * Iterator which walk through document char by char.
     78                 * @param {Object} start
     79                 * @param {Number} offset
     80                 */
     81                var characterWalker = function( start, offset )
     82                {
     83                        var isCursor = typeof start.textNode !== 'undefined';
     84                        this.textNode = isCursor ? start.textNode : start;
     85                        this.offset = isCursor ? start.offset : offset;
     86                        this._ = {
     87                                walker : new CKEDITOR.dom.domWalker( this.textNode ),
     88                                matchBoundary : false
     89                        };
     90                };
     91
     92                characterWalker.prototype = {
     93                        next : function()
     94                        {
     95                                // Already at the end of document, no more character available.
     96                                if( this.textNode === null && this._.matchBoundary )
     97                                        return getCurrentCursor.call( this );
     98                                       
     99                                this._.matchBoundary = false;
     100                               
     101                                // If there are more characters in the text node, get it and
     102                                // raise an event.
     103                                if( this.textNode.type == CKEDITOR.NODE_TEXT
     104                                        && this.offset < this.textNode.getLength() - 1 )
     105                                {
     106                                        this.offset++;
     107                                        return getCurrentCursor.call( this );
     108                                }
     109
     110                                // If we are at the end of the text node, use dom walker to get
     111                                // the next text node.
     112                                var data = null;
     113                                while ( !data || ( data.node && data.node.type !=
     114                                        CKEDITOR.NODE_TEXT ) )
     115                                {
     116                                        data = this._.walker.forward(
     117                                                guardDomWalkerNonEmptyTextNode );
     118       
     119                                        // Block boundary? BR? Document boundary?
     120                                        if ( !data.node
     121                                                || ( data.node.type !== CKEDITOR.NODE_TEXT
     122                                                        && data.node.getName() in
     123                                                        characterBoundaryElementsEnum ) )
     124                                                this._.matchBoundary = true;
     125                                }
     126                                this.textNode = data.node;
     127                                this.offset = 0;
     128                                return getCurrentCursor.call( this );
     129                        },
     130                       
     131                        back : function()
     132                        {
     133                                this._.matchBoundary = false;
     134
     135                                // More characters -> decrement offset and return.
     136                                if ( this.textNode.type == CKEDITOR.NODE_TEXT && this.offset > 0 )
     137                                {
     138                                        this.offset--;
     139                                        return getCurrentCursor.call( this );
     140                                }
     141
     142                                // Start of text node -> use dom walker to get the previous text node.
     143                                var data = null;
     144                                while ( !data
     145                                || ( data.node && data.node.type != CKEDITOR.NODE_TEXT ) )
     146                                {
     147                                        data = this._.walker.reverse( guardDomWalkerNonEmptyTextNode );
     148
     149                                        // Block boundary? BR? Document boundary?
     150                                        if ( !data.node || ( data.node.type !== CKEDITOR.NODE_TEXT &&
     151                                        data.node.getName() in characterBoundaryElementsEnum ) )
     152                                                this._.matchBoundary = true;
     153                                }
     154                                this.textNode = data.node;
     155                                this.offset = data.node.length - 1;
     156                                return getCurrentCursor.call( this );
     157                        }
     158                };
     159               
     160                /**
     161                 * A range of cursors which represent a trunk of characters which try to
     162                 * match, it has the same length as the pattern  string.
     163                 */
     164                var characterRange = function( characterWalker, rangeLength )
     165                {
     166                        this._ = {
     167                                walker : characterWalker,
     168                                cursors : [],
     169                                rangeLength : rangeLength,
     170                                highlightRange : null,
     171                                isMatched : false
     172                        };
     173                };
     174
     175                characterRange.prototype = {
     176                        /**
     177                         * Translate this range to {@link CKEDITOR.dom.range}
     178                         */
     179                        toDomRange : function()
     180                        {
     181                                var cursors = this._.cursors;
     182                                if ( cursors.length < 1 )
     183                                        return null;
     184
     185                                var first = cursors[0],
     186                                        last = cursors[ cursors.length - 1 ],
     187                                        range = new CKEDITOR.dom.range( editor.document );
     188
     189                                range.setStart( first.textNode, first.offset );
     190                                range.setEnd( last.textNode, last.offset + 1 );
     191                                return range;
     192                        },
     193                       
     194                        setMatched : function()
     195                        {
     196                                this._.isMatched = true;
     197                                this.highlight();
     198                        },
     199                       
     200                        clearMatched : function()
     201                        {
     202                                this._.isMatched = false;
     203                                this.removeHighlight();
     204                        },
     205                       
     206                        isMatched : function()
     207                        {
     208                                return this._.isMatched;
     209                        },
     210                       
     211                        /**
     212                         * Hightlight the current matched chunk of text, using selection
     213                         * system to represent highlight until marking-style is implemented.
     214                         */
     215                        highlight : function()
     216                        {
     217                                if(CKEDITOR.env.ie)
     218                                        dialog.restoreSelection();
     219                               
     220                                editor.getSelection().selectRanges( [ this.toDomRange() ] );
     221                               
     222                                if(CKEDITOR.env.ie)
     223                                {
     224                                        dialog.saveSelection();
     225                                       
     226                                        // since IE broke text nodes, update these changes back to
     227                                        // character range.
     228                                        var dirtyRange = editor.getSelection().getRanges()[0];
     229                                        var cursors = this._.cursors;
     230                                        var first = cursors[0],
     231                                        last = cursors[ cursors.length - 1 ];
     232                                        first.textNode = dirtyRange.startContainer;
     233                                        first.offset = dirtyRange.startOffset;
     234                                        last.textNode = dirtyRange.endContainer;
     235                                        last.offset = dirtyRange.endOffset;
     236                                }
     237                        },
     238                       
     239                        /**
     240                         * Wait for highlight marking-style in order to perform removal.
     241                         */
     242                        removeHighlight : function()
     243                        {
     244                                this._.highlightRange = null;
     245                        },
     246
     247                        moveBack : function()
     248                        {
     249                                var retval = this._.walker.back(),
     250                                        cursors = this._.cursors;
     251
     252                                if ( retval.hitMatchBoundary )
     253                                        this._.cursors = cursors = [];
     254
     255                                cursors.unshift( retval );
     256                                if ( cursors.length > this._.rangeLength )
     257                                        cursors.pop();
     258
     259                                return retval;
     260                        },
     261       
     262                        moveNext : function()
     263                        {
     264                                var retval = this._.walker.next(),
     265                                        cursors = this._.cursors;
     266
     267                                // Clear the cursors queue if we've crossed a match boundary.
     268                                if ( retval.hitMatchBoundary )
     269                                        this._.cursors = cursors = [];
     270
     271                                cursors.push( retval );
     272                                if ( cursors.length > this._.rangeLength )
     273                                        cursors.shift();
     274
     275                                return retval;
     276                        },
     277
     278                        getEndCharacter : function()
     279                        {
     280                                var cursors = this._.cursors;
     281                                if ( cursors.length < 1 )
     282                                        return null;
     283
     284                                return cursors[ cursors.length - 1 ].character;
     285                        },
     286
     287                        updateRange : function( newrangeLength )
     288                        {
     289                                this._.cursors = [];
     290                                this._.rangeLength = newrangeLength;
     291                                this.removeHighlight();
     292                        },
     293
     294                        getCursors : function()
     295                        {
     296                                return this._.cursors;
     297                        }
     298                };
     299
     300                var KMP_NOMATCH = 0,
     301                        KMP_ADVANCED = 1,
     302                        KMP_MATCHED = 2;
     303                /**
     304                 * Examination the occurrence of a word which implement KMP algorithm.
     305                 */
     306                var kmpMatcher = function( pattern, ignoreCase )
     307                {
     308                        var overlap = [ -1 ];
     309                        if ( ignoreCase )
     310                                pattern = pattern.toLowerCase();
     311                        for ( var i = 0 ; i < pattern.length ; i++ )
     312                        {
     313                                overlap.push( overlap[i] + 1 );
     314                                while ( overlap[ i + 1 ] > 0
     315                                        && pattern.charAt( i ) != pattern
     316                                                .charAt( overlap[ i + 1 ] - 1 ) )
     317                                        overlap[ i + 1 ] = overlap[ overlap[ i + 1 ] - 1 ] + 1;
     318                        }
     319
     320                        this._ = {
     321                                overlap : overlap,
     322                                state : 0,
     323                                ignoreCase : !!ignoreCase,
     324                                pattern : pattern
     325                        };
     326                };
     327                kmpMatcher.prototype = {
     328                        feedCharacter : function( c )
     329                        {
     330                                if ( this._.ignoreCase )
     331                                        c = c.toLowerCase();
     332
     333                                while ( true )
     334                                {
     335                                        if ( c == this._.pattern.charAt( this._.state ) )
     336                                        {
     337                                                this._.state++;
     338                                                if ( this._.state == this._.pattern.length )
     339                                                {
     340                                                        this._.state = 0;
     341                                                        return KMP_MATCHED;
     342                                                }
     343                                                return KMP_ADVANCED;
     344                                        }
     345                                        else if ( this._.state == 0 )
     346                                                return KMP_NOMATCH;
     347                                        else
     348                                                this._.state = this._.overlap[ this._.state ];
     349                                }
     350
     351                                return null;
     352                        },
     353
     354                        reset : function()
     355                        {
     356                                this._.state = 0;
     357                        }
     358                };
     359
     360                var wordSeparatorRegex =
     361                /[.,"'?!;: \u0085\u00a0\u1680\u280e\u2028\u2029\u202f\u205f\u3000]/,
     362                        isWordSeparator = function( c )
     363                        {
     364                                if ( !c )
     365                                        return true;
     366                                var code = c.charCodeAt( 0 );
     367                                return ( code >= 9 && code <= 0xd )
     368                                || ( code >= 0x2000 && code <= 0x200a )
     369                                || wordSeparatorRegex.test( c );
     370                        };
     371
     372                var finder = {
     373                        startCursor : null,
     374                        range : null,
     375                        find : function( pattern, matchCase, matchWord, matchCyclic )
     376                        {
     377                                if( !this.range )
     378                                        this.range = new characterRange( new characterWalker(
     379                                                this.startCursor ) , pattern.length );
     380                                else
     381                                {
     382                                        this.range.updateRange( pattern.length );
     383                                }
     384
     385                                var matcher = new kmpMatcher( pattern, !matchCase ),
     386                                        matchState = KMP_NOMATCH,
     387                                        character = '%';
     388
     389                                while ( character != null )
     390                                {
     391                                        this.range.moveNext();
     392                                        while ( ( character = this.range.getEndCharacter() ) )
     393                                        {
     394                                                matchState = matcher.feedCharacter( character );
     395                                                if ( matchState == KMP_MATCHED )
     396                                                        break;
     397                                                if ( this.range.moveNext().hitMatchBoundary )
     398                                                        matcher.reset();
     399                                        }
     400
     401                                        if ( matchState == KMP_MATCHED )
     402                                        {
     403                                                if ( matchWord )
     404                                                {
     405                                                        var cursors = this.range.getCursors(),
     406                                                                tail = cursors[ cursors.length - 1 ],
     407                                                                head = cursors[ 0 ],
     408                                                                headWalker = new characterWalker(head),
     409                                                                tailWalker = new characterWalker(tail);
     410                                                               
     411                                                        if ( ! ( isWordSeparator(
     412                                                                                headWalker.back().character )
     413                                                                                && isWordSeparator(
     414                                                                                tailWalker.next().character ) ) )
     415                                                                continue;
     416                                                }
     417
     418                                                this.range.setMatched();
     419                                                return true;
     420                                        }
     421                                }
     422                               
     423                                this.range.clearMatched();
     424                               
     425                                // clear current session and restart from beginning
     426                                if ( matchCyclic )
     427                                        this.range = null;
     428                               
     429                                return false;
     430                        },
     431                       
     432                        /**
     433                         * Record how much replacement occurred toward one replacing.
     434                         */
     435                        replaceCounter : 0,
     436                       
     437                        replace : function( pattern, newString, matchCase, matchWord,
     438                                matchCyclic, matchReplaceAll )
     439                        {
     440                                var replaceResult = false;
     441                                if ( this.range && this.range.isMatched() )
     442                                {
     443                                        if ( CKEDITOR.env.ie )
     444                                                dialog.restoreSelection();
     445
     446                                        var domrange = this.range.toDomRange();
     447                                        var documentFragment = domrange.extractContents();
     448                                        // Use the first text container as holder, no matter what
     449                                        // kind of element it is.
     450                                        var contentHolder = documentFragment.getFirst();
     451
     452                                        if ( contentHolder.type === CKEDITOR.NODE_ELEMENT )
     453                                                contentHolder.setText( newString );
     454                                        else
     455                                                contentHolder = editor.document.createText( newString );
     456
     457                                        domrange.insertNode( contentHolder );
     458
     459                                        if ( CKEDITOR.env.ie )
     460                                                dialog.saveSelection();
     461
     462                                        this.replaceCounter++;
     463                                        replaceResult = true;
     464                                }
     465                               
     466                                var findResult = this.find(
     467                                        pattern, matchCase, matchWord,  matchCyclic );
     468                                if ( findResult && matchReplaceAll )
     469                                {
     470                                        this.replace.apply( this,
     471                                                Array.prototype.slice.call( arguments ) );
     472                                }
     473                                return matchReplaceAll ?
     474                                        this.replaceCounter : replaceResult || findResult;
     475                        }
     476                       
     477                };
     478               
     479                /**
     480                 * Get the default cursor which is the start of this document.
     481                 */
     482                function getDefaultStartCursor()
     483                {
     484                        return {textNode : editor.document.getBody(), offset: 0};
     485                }
     486               
     487                /**
     488                 * Get cursor that indicate search begin with, receive from user
     489                 * selection prior.
     490                 */
     491                function getStartCursor()
     492                {
     493                        if ( CKEDITOR.env.ie )
     494                                dialog.restoreSelection();
     495
     496                        var sel = editor.getSelection();
     497                        if ( sel )
     498                        {
     499                                var lastRange = sel.getRanges()[ sel.getRanges().length - 1 ];
     500                                return {
     501                                        textNode : lastRange.getBoundaryNodes().endNode,
     502                                        offset : lastRange.endContainer.type ===
     503                                                CKEDITOR.NODE_ELEMENT ?
     504                                                0       : lastRange.endOffset
     505                                };
     506                        }
     507                        else
     508                                return getDefaultStartCursor();
     509                }
     510               
     511                return {
     512                        title : editor.lang.findAndReplace.title,
     513                        resizable : CKEDITOR.DIALOG_RESIZE_NONE,
     514                        minWidth : 400,
     515                        minHeight : 255,
     516                        buttons : [ CKEDITOR.dialog.cancelButton ],             //Cancel button only.
     517                        contents : [
     518                                {
     519                                        id : 'find',
     520                                        label : editor.lang.findAndReplace.find,
     521                                        title : editor.lang.findAndReplace.find,
     522                                        accessKey : '',
     523                                        elements : [
     524                                                {
     525                                                        type : 'hbox',
     526                                                        widths : [ '230px', '90px' ],
     527                                                        children :
     528                                                        [
     529                                                                {
     530                                                                        type : 'text',
     531                                                                        id : 'txtFindFind',
     532                                                                        label : editor.lang.findAndReplace.findWhat,
     533                                                                        isChanged : false,
     534                                                                        labelLayout : 'horizontal',
     535                                                                        accessKey : 'F'
     536                                                                },
     537                                                                {
     538                                                                        type : 'button',
     539                                                                        align : 'left',
     540                                                                        style : 'width:100%',
     541                                                                        label : editor.lang.findAndReplace.find,
     542                                                                        onClick : function()
     543                                                                        {
     544                                                                                var dialog = this.getDialog();
     545                                                                                if ( !finder.find( dialog.getValueOf(
     546                                                                                        'find', 'txtFindFind' ), dialog
     547                                                                                        .getValueOf( 'find',
     548                                                                                                'txtFindCaseChk' ), dialog
     549                                                                                        .getValueOf( 'find',
     550                                                                                                'txtFindWordChk' ), dialog
     551                                                                                        .getValueOf( 'find',
     552                                                                                                'txtFindCyclic' ) ) )
     553                                                                                        alert( editor.lang.findAndReplace
     554                                                                                                .notFoundMsg );
     555                                                                        }
     556                                                                }
     557                                                        ]
     558                                                },
     559                                                {
     560                                                        type : 'checkbox',
     561                                                        id : 'txtFindCaseChk',
     562                                                        isChanged : false,
     563                                                        style : 'margin-top:28px',
     564                                                        label : editor.lang.findAndReplace.matchCase
     565                                                },
     566                                                {
     567                                                        type : 'checkbox',
     568                                                        id : 'txtFindWordChk',
     569                                                        isChanged : false,
     570                                                        label : editor.lang.findAndReplace.matchWord
     571                                                },
     572                                                {
     573                                                        type : 'checkbox',
     574                                                        id : 'txtFindCyclic',
     575                                                        isChanged : false,
     576                                                        checked : true,
     577                                                        label : editor.lang.findAndReplace.matchCyclic
     578                                                }
     579                                        ]
     580                                },
     581                                {
     582                                        id : 'replace',
     583                                        label : editor.lang.findAndReplace.replace,
     584                                        accessKey : 'M',
     585                                        elements : [
     586                                                {
     587                                                        type : 'hbox',
     588                                                        widths : [ '230px', '90px' ],
     589                                                        children :
     590                                                        [
     591                                                                {
     592                                                                        type : 'text',
     593                                                                        id : 'txtFindReplace',
     594                                                                        label : editor.lang.findAndReplace.findWhat,
     595                                                                        isChanged : false,
     596                                                                        labelLayout : 'horizontal',
     597                                                                        accessKey : 'F'
     598                                                                },
     599                                                                {
     600                                                                        type : 'button',
     601                                                                        align : 'left',
     602                                                                        style : 'width:100%',
     603                                                                        label : editor.lang.findAndReplace.replace,
     604                                                                        onClick : function()
     605                                                                        {
     606                                                                                var dialog = this.getDialog();
     607                                                                                if ( !finder.replace( dialog
     608                                                                                        .getValueOf( 'replace',
     609                                                                                                'txtFindReplace' ), dialog
     610                                                                                        .getValueOf( 'replace',
     611                                                                                                'txtReplace' ), dialog
     612                                                                                        .getValueOf( 'replace',
     613                                                                                                'txtReplaceCaseChk' ), dialog
     614                                                                                        .getValueOf( 'replace',
     615                                                                                                'txtReplaceWordChk' ), dialog
     616                                                                                        .getValueOf( 'replace',
     617                                                                                                'txtReplaceCyclic' ) ) )
     618                                                                                        alert( editor.lang.findAndReplace
     619                                                                                                .notFoundMsg );
     620                                                                        }
     621                                                                }
     622                                                        ]
     623                                                },
     624                                                {
     625                                                        type : 'hbox',
     626                                                        widths : [ '230px', '90px' ],
     627                                                        children :
     628                                                        [
     629                                                                {
     630                                                                        type : 'text',
     631                                                                        id : 'txtReplace',
     632                                                                        label : editor.lang.findAndReplace
     633                                                                        .replaceWith,
     634                                                                        isChanged : false,
     635                                                                        labelLayout : 'horizontal',
     636                                                                        accessKey : 'R'
     637                                                                },
     638                                                                {
     639                                                                        type : 'button',
     640                                                                        align : 'left',
     641                                                                        style : 'width:100%',
     642                                                                        label : editor.lang.findAndReplace
     643                                                                                .replaceAll,
     644                                                                        isChanged : false,
     645                                                                        onClick : function()
     646                                                                        {
     647                                                                                var dialog = this.getDialog();
     648                                                                                var replaceNums;
     649
     650                                                                                finder.replaceCounter = 0;
     651                                                                                if ( ( replaceNums = finder.replace(
     652                                                                                        dialog.getValueOf( 'replace',
     653                                                                                                'txtFindReplace' ), dialog
     654                                                                                                .getValueOf( 'replace',
     655                                                                                                        'txtReplace' ), dialog
     656                                                                                                .getValueOf( 'replace',
     657                                                                                                        'txtReplaceCaseChk' ),
     658                                                                                        dialog.getValueOf( 'replace',
     659                                                                                                'txtReplaceWordChk' ), dialog
     660                                                                                                .getValueOf( 'replace',
     661                                                                                                        'txtReplaceCyclic' ), true ) ) )
     662                                                                                        alert( editor.lang.findAndReplace
     663                                                                                                .replaceSuccMsg
     664                                                                                                .replace( /%1/, replaceNums ) );
     665                                                                                else
     666                                                                                        alert( editor.lang.findAndReplace
     667                                                                                                .notFoundMsg );
     668                                                                        }
     669                                                                }
     670                                                        ]
     671                                                },
     672                                                {
     673                                                        type : 'checkbox',
     674                                                        id : 'txtReplaceCaseChk',
     675                                                        isChanged : false,
     676                                                        label : editor.lang.findAndReplace
     677                                                                .matchCase
     678                                                },
     679                                                {
     680                                                        type : 'checkbox',
     681                                                        id : 'txtReplaceWordChk',
     682                                                        isChanged : false,
     683                                                        label : editor.lang.findAndReplace
     684                                                                .matchWord
     685                                                },
     686                                                {
     687                                                        type : 'checkbox',
     688                                                        id : 'txtReplaceCyclic',
     689                                                        isChanged : false,
     690                                                        checked : true,
     691                                                        label : editor.lang.findAndReplace
     692                                                                .matchCyclic
     693                                                }
     694                                        ]
     695                                }
     696                        ],
     697                        onLoad : function()
     698                        {
     699                                dialog = this;
     700                               
     701                                //keep trac of the current pattern field in use.
     702                                var patternField, wholeWordChkField;
     703                               
     704                                /**
     705                                 * Check the whether the 'wholeworld' match mode could be
     706                                 * toggled on.
     707                                 */
     708                                function checkWholeWordState()
     709                                {
     710                                        var isWord = /^\w+$/.test( patternField.getValue() );
     711                                        var wholeWordChkFieldEl = wholeWordChkField.getElement();
     712                                        if ( isWord )
     713                                                wholeWordChkFieldEl.show();
     714                                        else
     715                                                wholeWordChkFieldEl.hide();
     716                                }
     717                               
     718                                //Ignore initial page select on dialog show
     719                                var isUserSelect = false;
     720                                this.on('hide', function(){
     721                                        isUserSelect = false;
     722                                });
     723                                this.on('show', function(){
     724                                        isUserSelect = true;
     725                                });
     726                               
     727                                this.selectPage = CKEDITOR.tools.override( this.selectPage,
     728                                        function( originalFunc )
     729                                        {
     730                                                return function( pageId )
     731                                                {
     732                                                        originalFunc.call( dialog, pageId );
     733                                                       
     734                                                        var currPage = dialog._.tabs[ pageId ];
     735                                                        var patternFieldInput, patternFieldId, wholeWordChkFieldId;
     736                                                        patternFieldId = pageId === 'find' ? 'txtFindFind'
     737                                                                : 'txtFindReplace';
     738                                                        wholeWordChkFieldId = pageId === 'find' ? 'txtFindWordChk'
     739                                                                : 'txtReplaceWordChk';
     740
     741                                                        patternField = dialog.getContentElement( pageId,
     742                                                                patternFieldId );
     743                                                        wholeWordChkField = dialog.getContentElement( pageId,
     744                                                                wholeWordChkFieldId );
     745                                                       
     746                                                        // prepare for check pattern text filed 'keyup' event
     747                                                        if ( !currPage.initialized )
     748                                                        {
     749                                                                patternFieldInput = CKEDITOR.document
     750                                                                        .getById( patternField._.inputId );
     751                                                                patternFieldInput.on( 'keyup', checkWholeWordState );
     752                                                                currPage.initialized = true;
     753                                                        }
     754                                                       
     755                                                        if(isUserSelect)
     756                                                                // synchronize fields on tab switch.
     757                                                                syncFieldsBetweenTabs.call( this, pageId );
     758                                                       
     759                                                        //check wholeword match status on tab switch
     760                                                        checkWholeWordState();
     761                                };
     762                        } );
     763
     764                        },
     765                        onShow : function()
     766                        {
     767                                //Establish initial searching start position.
     768                                finder.startCursor = getStartCursor();
     769                               
     770                                if ( startupPage == 'replace' )
     771                                        this.getContentElement( 'replace', 'txtFindReplace' ).focus();
     772                                else
     773                                        this.getContentElement( 'find', 'txtFindFind' ).focus();
     774                        },
     775                        onHide : function()
     776                        {
     777                                if ( finder.range && finder.range.isMatched() )
     778                                {
     779                                        editor.getSelection().selectRanges(
     780                                                [ finder.range.toDomRange() ] );
     781                                }
     782                                //clear current session before dialog close
     783                                delete finder.range;
     784                        }
     785                };
     786        };
     787
     788        CKEDITOR.dialog.add( 'find', function( editor ){
     789                        return findDialog( editor, 'find' )
     790                }
     791        );
     792
     793        CKEDITOR.dialog.add( 'replace', function( editor ){
     794                        return findDialog( editor, 'replace' )
     795                }
     796        );
     797})();
     798 No newline at end of file
  • _source/plugins/find/plugin.js

     
     1/*
     2Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
     3For licensing, see LICENSE.html or http://ckeditor.com/license
     4*/
     5
     6CKEDITOR.plugins.add( 'find',
     7{
     8        init : function( editor )
     9        {
     10                var forms = CKEDITOR.plugins.find;
     11                editor.ui.addButton( 'Find',
     12                        {
     13                                label : editor.lang.findAndReplace.find,
     14                                command : 'find'
     15                        });
     16                editor.addCommand( 'find', new CKEDITOR.dialogCommand( 'find' ) );
     17
     18                editor.ui.addButton( 'Replace',
     19                        {
     20                                label : editor.lang.findAndReplace.replace,
     21                                command : 'replace'
     22                        });
     23                editor.addCommand( 'replace', new CKEDITOR.dialogCommand( 'replace' ) );
     24
     25                CKEDITOR.dialog.add( 'find',    this.path + 'dialogs/find.js' );
     26                CKEDITOR.dialog.add( 'replace', this.path + 'dialogs/find.js' );
     27        }
     28} );
     29 No newline at end of file
  • _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

     
    147147         * config.plugins = 'basicstyles,button,htmldataprocessor,toolbar,wysiwygarea';
    148148         */
    149149
    150         plugins : 'basicstyles,blockquote,button,elementspath,horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,newpage,pagebreak,preview,print,removeformat,smiley,sourcearea,table,specialchar,tab,toolbar,wysiwygarea',
     150        plugins : 'basicstyles,blockquote,button,elementspath,horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,newpage,pagebreak,preview,print,removeformat,smiley,sourcearea,table,specialchar,tab,toolbar,wysiwygarea,find',
    151151
    152152        /**
    153153         * 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