Ticket #2905: 2905_2.patch
File 2905_2.patch, 25.6 KB (added by , 15 years ago) |
---|
-
_source/plugins/toolbar/plugin.js
211 211 'Bold', 'Italic', 'Underline', 'Strike', '-', 212 212 'NumberedList', 'BulletedList', '-', 213 213 'Subscript', 'Superscript', '-', 214 'Find', 'Replace', '-', 214 215 'SelectAll', 'RemoveFormat', '-', 215 216 'Link', 'Unlink', 'Anchor', '-', 216 217 'Table', 'Smiley', 'HorizontalRule', 'SpecialChar', 'PageBreak' -
_source/plugins/find/dialogs/find.js
5 5 6 6 (function() 7 7 { 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 8 14 var guardDomWalkerNonEmptyTextNode = function( evt ) 9 15 { 10 16 if ( evt.data.to && evt.data.to.type == CKEDITOR.NODE_TEXT && evt.data.to.$.length > 0 ) … … 11 17 this.stop(); 12 18 CKEDITOR.dom.domWalker.blockBoundary( { br : 1 } ).call( this, evt ); 13 19 }; 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() 25 26 { 26 27 var obj = { 27 type : 'character', 28 textNode : this.textNode, 29 offset : this.offset, 28 30 character : this.textNode ? this.textNode.getText().charAt( this.offset ) : null, 29 31 hitMatchBoundary : this._.matchBoundary 30 32 }; 31 this.fire( 'character', obj ); 32 this._.actionEvents.push( obj ); 33 return { character : obj.character, events : this._.actionEvents }; 33 return obj; 34 34 }; 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 } 35 75 36 76 var findDialog = function( editor, startupPage ) 37 77 { 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 ) 39 87 { 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; 41 91 this._ = { 42 matchBoundary : false,43 actionEvents : null92 walker : new CKEDITOR.dom.domWalker( this.textNode ), 93 matchBoundary : false 44 94 }; 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 );50 95 }; 51 96 52 97 characterWalker.prototype = { … … 52 97 characterWalker.prototype = { 53 98 next : function() 54 99 { 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 57 104 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 ) 61 110 { 62 111 this.offset++; 63 return fireCharacterEvent.call( this );112 return getCurrentCursor.call( this ); 64 113 } 65 114 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. 67 117 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 ) ) 69 120 { 70 data = this._.walker.forward( guardDomWalkerNonEmptyTextNode ); 121 data = this._.walker 122 .forward( guardDomWalkerNonEmptyTextNode ); 71 123 72 124 // 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 ) ) 74 127 this._.matchBoundary = true; 75 128 } 76 129 this.textNode = data.node; … … 75 128 } 76 129 this.textNode = data.node; 77 130 this.offset = 0; 78 return fireCharacterEvent.call( this );131 return getCurrentCursor.call( this ); 79 132 }, 80 133 81 134 back : function() 82 135 { 83 // Clear any previous action events and related flags.84 this._.actionEvents = [];85 136 this._.matchBoundary = false; 86 137 87 138 // More characters -> decrement offset and return. … … 88 139 if ( this.textNode.type == CKEDITOR.NODE_TEXT && this.offset > 0 ) 89 140 { 90 141 this.offset--; 91 return fireCharacterEvent.call( this );142 return getCurrentCursor.call( this ); 92 143 } 93 144 94 145 // Start of text node -> use dom walker to get the previous text node. … … 98 149 data = this._.walker.reverse( guardDomWalkerNonEmptyTextNode ); 99 150 100 151 // 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 ) ) 102 154 this._.matchBoundary = true; 103 155 } 104 156 this.textNode = data.node; … … 103 155 } 104 156 this.textNode = data.node; 105 157 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 ); 112 159 } 113 160 }; 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 ) 116 167 { 117 168 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 121 174 }; 122 175 }; 123 176 … … 122 175 }; 123 176 124 177 characterRange.prototype = { 178 /** 179 * Translate this range to {@link CKEDITOR.dom.range} 180 */ 125 181 toDomRange : function() 126 182 { 127 183 var cursors = this._.cursors; … … 136 192 range.setEnd( last.textNode, last.offset + 1 ); 137 193 return range; 138 194 }, 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 }, 139 212 140 213 highlight : function() 141 214 { 215 if(CKEDITOR.env.ie) 216 dialog.restoreSelection(); 217 142 218 // TODO: wait till Fred has implemented style removal for this. 143 219 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 } 144 235 }, 145 236 146 237 removeHighlight : function() … … 146 237 removeHighlight : function() 147 238 { 148 239 // TODO: wait till Fred has implemented style removal for this. 240 this._.highlightRange = null; 149 241 }, 150 242 151 243 getHighlightDomRange : function() … … 153 245 // TODO: wait till Fred has implemented style removal for this. 154 246 return this.toDomRange(); 155 247 }, 156 157 move Next: function()248 249 moveBack : function() 158 250 { 159 var next = new characterWalker( this._.cursors[ this._.cursors.length - 1 ] ), 160 retval = next.next(), 251 var retval = this._.walker.back(), 161 252 cursors = this._.cursors; 162 253 163 // Clear the cursors queue if we've crossed a match boundary.164 254 if ( retval.hitMatchBoundary ) 165 255 this._.cursors = cursors = []; 166 256 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(); 170 260 171 261 return retval; 172 262 }, 173 174 move Back: function()263 264 moveNext : function() 175 265 { 176 var prev = new characterWalker( this._.cursors[0] ), 177 retval = prev.back(), 266 var retval = this._.walker.next(), 178 267 cursors = this._.cursors; 179 268 269 // Clear the cursors queue if we've crossed a match boundary. 180 270 if ( retval.hitMatchBoundary ) 181 271 this._.cursors = cursors = []; 182 272 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(); 186 276 187 277 return retval; 188 278 }, … … 193 283 if ( cursors.length < 1 ) 194 284 return null; 195 285 196 return cursors[ cursors.length - 1 ]. getChar();286 return cursors[ cursors.length - 1 ].character; 197 287 }, 198 288 199 getNextRange : function( maxLength )289 updateRange : function( newrangeLength ) 200 290 { 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(); 208 294 }, 209 295 210 296 getCursors : function() … … 216 302 var KMP_NOMATCH = 0, 217 303 KMP_ADVANCED = 1, 218 304 KMP_MATCHED = 2; 305 /** 306 * Examination the occurrence of a word which implement KMP algorithm. 307 */ 219 308 var kmpMatcher = function( pattern, ignoreCase ) 220 309 { 221 310 var overlap = [ -1 ]; … … 278 367 }; 279 368 280 369 var finder = { 370 startCursor : null, 281 371 range : null, 282 find : function( pattern, matchCase, matchWord )372 find : function( pattern, matchCase, matchWord, matchCyclic ) 283 373 { 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 ); 286 377 else 287 378 { 288 this.range.removeHighlight(); 289 this.range = this.range.getNextRange( pattern.length ); 379 this.range.updateRange( pattern.length ); 290 380 } 291 381 292 382 var matcher = new kmpMatcher( pattern, !matchCase ), … … 295 385 296 386 while ( character != null ) 297 387 { 388 this.range.moveNext(); 298 389 while ( ( character = this.range.getEndCharacter() ) ) 299 390 { 300 391 matchState = matcher.feedCharacter( character ); … … 309 400 if ( matchWord ) 310 401 { 311 402 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 ) ) ) 317 412 continue; 318 413 } 319 414 320 this.range. highlight();415 this.range.setMatched(); 321 416 return true; 322 417 } 323 418 } 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(); 324 444 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; 327 474 } 475 328 476 }; 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(); 329 493 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 330 508 return { 331 509 title : editor.lang.findAndReplace.title, 332 510 resizable : CKEDITOR.DIALOG_RESIZE_NONE, … … 331 509 title : editor.lang.findAndReplace.title, 332 510 resizable : CKEDITOR.DIALOG_RESIZE_NONE, 333 511 minWidth : 400, 334 minHeight : 2 45,512 minHeight : 255, 335 513 buttons : [ CKEDITOR.dialog.cancelButton ], //Cancel button only. 336 514 contents : [ 337 515 { … … 352 530 isChanged : false, 353 531 labelLayout : 'horizontal', 354 532 accessKey : 'F', 533 setup : function(){alert('setup');} 355 534 }, 356 535 { 357 536 type : 'button', … … 363 542 var dialog = this.getDialog(); 364 543 if ( !finder.find( dialog.getValueOf( 'find', 'txtFindFind' ), 365 544 dialog.getValueOf( 'find', 'txtFindCaseChk' ), 366 dialog.getValueOf( 'find', 'txtFindWordChk' ) ) ) 545 dialog.getValueOf( 'find', 'txtFindWordChk' ), 546 dialog.getValueOf( 'find', 'txtFindCyclic' ) ) ) 367 547 alert( editor.lang.findAndReplace.notFoundMsg ); 368 548 } 369 } ,549 } 370 550 ] 371 551 }, 372 552 { … … 374 554 id : 'txtFindCaseChk', 375 555 isChanged : false, 376 556 style : 'margin-top:28px', 377 label : editor.lang.findAndReplace.matchCase ,557 label : editor.lang.findAndReplace.matchCase 378 558 }, 379 559 { 380 560 type : 'checkbox', … … 380 560 type : 'checkbox', 381 561 id : 'txtFindWordChk', 382 562 isChanged : false, 383 label : editor.lang.findAndReplace.matchWord ,563 label : editor.lang.findAndReplace.matchWord 384 564 }, 385 565 { 386 566 type : 'checkbox', … … 387 567 id : 'txtFindCyclic', 388 568 isChanged : false, 389 569 checked : true, 390 label : editor.lang.findAndReplace.matchCyclic ,391 } ,570 label : editor.lang.findAndReplace.matchCyclic 571 } 392 572 ] 393 573 }, 394 574 { … … 407 587 label : editor.lang.findAndReplace.findWhat, 408 588 isChanged : false, 409 589 labelLayout : 'horizontal', 410 accessKey : 'F' ,590 accessKey : 'F' 411 591 }, 412 592 { 413 593 type : 'button', … … 416 596 label : editor.lang.findAndReplace.replace, 417 597 onClick : function() 418 598 { 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 ); 420 612 } 421 } ,613 } 422 614 ] 423 615 }, 424 616 { … … 432 624 label : editor.lang.findAndReplace.replaceWith, 433 625 isChanged : false, 434 626 labelLayout : 'horizontal', 435 accessKey : 'R' ,627 accessKey : 'R' 436 628 }, 437 629 { 438 630 type : 'button', … … 442 634 isChanged : false, 443 635 onClick : function() 444 636 { 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 ); 446 656 } 447 } ,657 } 448 658 ] 449 659 }, 450 660 { … … 451 661 type : 'checkbox', 452 662 id : 'txtReplaceCaseChk', 453 663 isChanged : false, 454 label : editor.lang.findAndReplace.matchCase ,664 label : editor.lang.findAndReplace.matchCase 455 665 }, 456 666 { 457 667 type : 'checkbox', … … 457 667 type : 'checkbox', 458 668 id : 'txtReplaceWordChk', 459 669 isChanged : false, 460 label : editor.lang.findAndReplace.matchWord ,670 label : editor.lang.findAndReplace.matchWord 461 671 }, 462 672 { 463 673 type : 'checkbox', … … 464 674 id : 'txtReplaceCyclic', 465 675 isChanged : false, 466 676 checked : true, 467 label : editor.lang.findAndReplace.matchCyclic ,468 } ,677 label : editor.lang.findAndReplace.matchCyclic 678 } 469 679 ] 470 680 } 471 681 ], 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 }, 472 739 onShow : function() 473 740 { 741 //Establish initial searching start position. 742 finder.startCursor = getStartCursor(); 743 474 744 if ( startupPage == 'replace' ) 475 745 this.getContentElement( 'replace', 'txtFindReplace' ).focus(); 476 746 else … … 478 748 }, 479 749 onHide : function() 480 750 { 751 isSwitch = false; 481 752 if ( finder.range ) 482 753 { 483 754 finder.range.removeHighlight(); … … 483 754 finder.range.removeHighlight(); 484 755 editor.getSelection().selectRanges( [finder.range.toDomRange()] ); 485 756 } 757 delete finder.range; 486 758 } 487 759 }; 488 760 }; -
_source/skins/default/toolbar.css
315 315 { 316 316 background-position: 0 -416px; 317 317 } 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
170 170 matchCase : 'Match case', 171 171 matchWord : 'Match whole word', 172 172 matchCyclic : 'Match cyclic', 173 replaceAll : 'Replace All' 173 replaceAll : 'Replace All', 174 replaceSuccMsg : 'Succeed with: %1 replacement(s) in total.' 174 175 }, 175 176 176 177 // Table Dialog -
_source/core/dom/document.js
70 70 71 71 createText : function( text ) 72 72 { 73 return new CKEDITOR.dom.text( '', this );73 return new CKEDITOR.dom.text( text , this ); 74 74 }, 75 75 76 76 /** -
_source/core/config.js
146 146 * @example 147 147 * config.plugins = 'basicstyles,button,htmldataprocessor,toolbar,wysiwygarea'; 148 148 */ 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', 150 150 151 151 /** 152 152 * The theme to be used to build the UI.